[js weak ref] Make JSWeakRef / WeakCell target handling more robust

1) JSWeakRef and WeakCell targets are HeapObjects (SMIs are no longer used for
signalling cleared / dead JSWeakRefs / WeakCells.) Make this explicit.

2) There's no need to assert that the target of JSWeakRef cannot be undefined
when handled by MarkCompactCollector::ClearJSWeakRefs, since the code handles
undefined just fine. (The removed comment was true though, since this is the only place
which can set the target to undefined. But maybe in the future there's some
other way to clear a JSWeakRef, e.g., explicit API for it.)

BUG=v8:8179

Change-Id: I762c2b4487770712c7538be799dc188943c92587
Reviewed-on: https://chromium-review.googlesource.com/c/1445986
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59237}
diff --git a/src/builtins/builtins-weak-refs.cc b/src/builtins/builtins-weak-refs.cc
index f7395c9..1d8a6f3 100644
--- a/src/builtins/builtins-weak-refs.cc
+++ b/src/builtins/builtins-weak-refs.cc
@@ -136,8 +136,9 @@
         NewTypeError(
             MessageTemplate::kWeakRefsWeakRefConstructorTargetMustBeObject));
   }
-  isolate->heap()->AddKeepDuringJobTarget(
-      Handle<JSReceiver>::cast(target_object));
+  Handle<JSReceiver> target_receiver =
+      handle(JSReceiver::cast(*target_object), isolate);
+  isolate->heap()->AddKeepDuringJobTarget(target_receiver);
 
   // TODO(marja): Realms.
 
@@ -147,7 +148,7 @@
       JSObject::New(target, new_target, Handle<AllocationSite>::null()));
 
   Handle<JSWeakRef> weak_ref = Handle<JSWeakRef>::cast(result);
-  weak_ref->set_target(*target_object);
+  weak_ref->set_target(*target_receiver);
   return *weak_ref;
 }
 
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index bce810f..cf687b2 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -2286,9 +2286,7 @@
   }
   JSWeakRef weak_ref;
   while (weak_objects_.js_weak_refs.Pop(kMainThread, &weak_ref)) {
-    // We do not insert cleared weak cells into the list, so the value
-    // cannot be undefined here.
-    JSReceiver target = JSReceiver::cast(weak_ref->target());
+    HeapObject target = HeapObject::cast(weak_ref->target());
     if (!non_atomic_marking_state()->IsBlackOrGrey(target)) {
       weak_ref->set_target(ReadOnlyRoots(isolate()).undefined_value());
     } else {
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 7dc1428..afad51d 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1297,6 +1297,7 @@
 void WeakCell::WeakCellVerify(Isolate* isolate) {
   CHECK(IsWeakCell());
 
+  CHECK(target()->IsJSReceiver() || target()->IsUndefined(isolate));
   CHECK(next()->IsWeakCell() || next()->IsUndefined(isolate));
   if (next()->IsWeakCell()) {
     CHECK_EQ(WeakCell::cast(next())->prev(), *this);
diff --git a/src/objects/js-weak-refs-inl.h b/src/objects/js-weak-refs-inl.h
index 6fec45f..bba9974 100644
--- a/src/objects/js-weak-refs-inl.h
+++ b/src/objects/js-weak-refs-inl.h
@@ -35,7 +35,7 @@
 CAST_ACCESSOR(JSFinalizationGroup)
 
 ACCESSORS(WeakCell, finalization_group, Object, kFinalizationGroupOffset)
-ACCESSORS(WeakCell, target, Object, kTargetOffset)
+ACCESSORS(WeakCell, target, HeapObject, kTargetOffset)
 ACCESSORS(WeakCell, holdings, Object, kHoldingsOffset)
 ACCESSORS(WeakCell, next, Object, kNextOffset)
 ACCESSORS(WeakCell, prev, Object, kPrevOffset)
@@ -45,7 +45,7 @@
 CAST_ACCESSOR(WeakCell)
 
 CAST_ACCESSOR(JSWeakRef)
-ACCESSORS(JSWeakRef, target, Object, kTargetOffset)
+ACCESSORS(JSWeakRef, target, HeapObject, kTargetOffset)
 
 ACCESSORS(JSFinalizationGroupCleanupIterator, finalization_group,
           JSFinalizationGroup, kFinalizationGroupOffset)
diff --git a/src/objects/js-weak-refs.h b/src/objects/js-weak-refs.h
index 1762bff..e13ce14 100644
--- a/src/objects/js-weak-refs.h
+++ b/src/objects/js-weak-refs.h
@@ -90,7 +90,7 @@
   DECL_CAST(WeakCell)
 
   DECL_ACCESSORS(finalization_group, Object)
-  DECL_ACCESSORS(target, Object)
+  DECL_ACCESSORS(target, HeapObject)
   DECL_ACCESSORS(holdings, Object)
 
   // For storing doubly linked lists of WeakCells in JSFinalizationGroup's
@@ -144,7 +144,7 @@
   DECL_VERIFIER(JSWeakRef)
   DECL_CAST(JSWeakRef)
 
-  DECL_ACCESSORS(target, Object)
+  DECL_ACCESSORS(target, HeapObject)
 
   static const int kTargetOffset = JSObject::kHeaderSize;
   static const int kSize = kTargetOffset + kPointerSize;