Bug 1597970 - Allow for the possiblity of FinalizationGroupObject's slots being uninitialized r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 22 Nov 2019 01:02:16 +0000
changeset 503326 866b8ca52a96e1f2d1cc5f3d4d046e0fa326dbb0
parent 503325 772d21d0b16f3c75648e56040460a7d942c116d4
child 503327 87296e3085dde8687e265620302680b995e21537
push id36833
push userbtara@mozilla.com
push dateFri, 22 Nov 2019 21:40:53 +0000
treeherdermozilla-central@2c912e46295e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1597970
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1597970 - Allow for the possiblity of FinalizationGroupObject's slots being uninitialized r=sfink The problem is that object metadata builder API can trigger GC after the object has been allocated but before its slots have been initialized. The fix is to take account that some slots may be undefined and handle this appropriately. Differential Revision: https://phabricator.services.mozilla.com/D54111
js/src/builtin/FinalizationGroupObject.cpp
js/src/jit-test/tests/gc/bug-1597970.js
--- a/js/src/builtin/FinalizationGroupObject.cpp
+++ b/js/src/builtin/FinalizationGroupObject.cpp
@@ -243,18 +243,22 @@ bool FinalizationGroupObject::construct(
 
   args.rval().setObject(*group);
   return true;
 }
 
 /* static */
 void FinalizationGroupObject::trace(JSTracer* trc, JSObject* obj) {
   auto group = &obj->as<FinalizationGroupObject>();
-  group->holdingsToBeCleanedUp()->trace(trc);
-  group->registrations()->trace(trc);
+  if (HoldingsVector* holdings = group->holdingsToBeCleanedUp()) {
+    holdings->trace(trc);
+  }
+  if (ObjectWeakMap* registrations = group->registrations()) {
+    registrations->trace(trc);
+  }
 }
 
 /* static */
 void FinalizationGroupObject::finalize(JSFreeOp* fop, JSObject* obj) {
   auto group = &obj->as<FinalizationGroupObject>();
   fop->delete_(obj, group->holdingsToBeCleanedUp(),
                MemoryUse::FinalizationGroupHoldingsVector);
   fop->delete_(obj, group->registrations(),
@@ -265,24 +269,30 @@ inline JSObject* FinalizationGroupObject
   Value value = getReservedSlot(CleanupCallbackSlot);
   if (value.isUndefined()) {
     return nullptr;
   }
   return &value.toObject();
 }
 
 ObjectWeakMap* FinalizationGroupObject::registrations() const {
-  return static_cast<ObjectWeakMap*>(
-      getReservedSlot(RegistrationsSlot).toPrivate());
+  Value value = getReservedSlot(RegistrationsSlot);
+  if (value.isUndefined()) {
+    return nullptr;
+  }
+  return static_cast<ObjectWeakMap*>(value.toPrivate());
 }
 
 FinalizationGroupObject::HoldingsVector*
 FinalizationGroupObject::holdingsToBeCleanedUp() const {
-  return static_cast<HoldingsVector*>(
-      getReservedSlot(HoldingsToBeCleanedUpSlot).toPrivate());
+  Value value = getReservedSlot(HoldingsToBeCleanedUpSlot);
+  if (value.isUndefined()) {
+    return nullptr;
+  }
+  return static_cast<HoldingsVector*>(value.toPrivate());
 }
 
 bool FinalizationGroupObject::isQueuedForCleanup() const {
   return getReservedSlot(IsQueuedForCleanupSlot).toBoolean();
 }
 
 bool FinalizationGroupObject::isCleanupJobActive() const {
   return getReservedSlot(IsCleanupJobActiveSlot).toBoolean();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1597970.js
@@ -0,0 +1,6 @@
+// |jit-test| --enable-weak-refs
+enableShellAllocationMetadataBuilder();
+evaluate(`
+  gczeal(9,3);
+  new FinalizationGroup(function() {});
+`);