Bug 1736396 - Replace sweeping with tracing weak edges in the FinalizationRegistry implementation r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 19 Oct 2021 08:43:20 +0000
changeset 596299 c68ab495c45c1d405cd37fa7c6e7d1c3164fcaf9
parent 596298 bf793230eca59c3cbf80037f52c867da4adc6ac1
child 596300 dd81c3c065315f679d5e4a001064cc90a39e4db7
push id38894
push usermlaza@mozilla.com
push dateTue, 19 Oct 2021 15:45:06 +0000
treeherdermozilla-central@329de07e7a96 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1736396
milestone95.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 1736396 - Replace sweeping with tracing weak edges in the FinalizationRegistry implementation r=sfink Differential Revision: https://phabricator.services.mozilla.com/D128759
js/src/builtin/FinalizationRegistryObject.cpp
js/src/builtin/FinalizationRegistryObject.h
js/src/gc/FinalizationRegistry.cpp
--- a/js/src/builtin/FinalizationRegistryObject.cpp
+++ b/js/src/builtin/FinalizationRegistryObject.cpp
@@ -163,19 +163,19 @@ inline bool FinalizationRegistrationsObj
 }
 
 inline void FinalizationRegistrationsObject::remove(
     HandleFinalizationRecordObject record) {
   MOZ_ASSERT(records());
   records()->eraseIfEqual(record);
 }
 
-inline void FinalizationRegistrationsObject::sweep() {
+inline bool FinalizationRegistrationsObject::traceWeak(JSTracer* trc) {
   MOZ_ASSERT(records());
-  return records()->sweep();
+  return records()->traceWeak(trc);
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // FinalizationRegistryObject
 
 // Bug 1600300: FinalizationRegistryObject is foreground finalized so that
 // HeapPtr destructors never see referents with released arenas. When this is
 // fixed we may be able to make this background finalized again.
@@ -271,35 +271,36 @@ bool FinalizationRegistryObject::constru
   queue->setHasRegistry(true);
 
   args.rval().setObject(*registry);
   return true;
 }
 
 /* static */
 void FinalizationRegistryObject::trace(JSTracer* trc, JSObject* obj) {
-  auto registry = &obj->as<FinalizationRegistryObject>();
-
   // Trace the registrations weak map. At most this traces the
   // FinalizationRegistrationsObject values of the map; the contents of those
-  // objects are weakly held and are not traced.
+  // objects are weakly held and are not traced by this method.
+
+  auto* registry = &obj->as<FinalizationRegistryObject>();
   if (ObjectWeakMap* registrations = registry->registrations()) {
     registrations->trace(trc);
   }
 }
 
-void FinalizationRegistryObject::sweep() {
-  // Sweep the contents of the registrations weak map's values.
+void FinalizationRegistryObject::traceWeak(JSTracer* trc) {
+  // Trace and update the contents of the registrations weak map's values, which
+  // are weakly held.
+
   MOZ_ASSERT(registrations());
   for (ObjectValueWeakMap::Enum e(registrations()->valueMap()); !e.empty();
        e.popFront()) {
-    auto registrations =
+    auto* registrations =
         &e.front().value().toObject().as<FinalizationRegistrationsObject>();
-    registrations->sweep();
-    if (registrations->isEmpty()) {
+    if (!registrations->traceWeak(trc)) {
       e.removeFront();
     }
   }
 }
 
 /* static */
 void FinalizationRegistryObject::finalize(JSFreeOp* fop, JSObject* obj) {
   auto registry = &obj->as<FinalizationRegistryObject>();
--- a/js/src/builtin/FinalizationRegistryObject.h
+++ b/js/src/builtin/FinalizationRegistryObject.h
@@ -150,17 +150,17 @@ class FinalizationRegistrationsObject : 
   WeakFinalizationRecordVector* records();
   const WeakFinalizationRecordVector* records() const;
 
   bool isEmpty() const;
 
   bool append(HandleFinalizationRecordObject record);
   void remove(HandleFinalizationRecordObject record);
 
-  void sweep();
+  bool traceWeak(JSTracer* trc);
 
  private:
   static const JSClassOps classOps_;
 
   void* privatePtr() const;
 
   static void trace(JSTracer* trc, JSObject* obj);
   static void finalize(JSFreeOp* fop, JSObject* obj);
@@ -175,17 +175,17 @@ class FinalizationRegistryObject : publi
 
  public:
   static const JSClass class_;
   static const JSClass protoClass_;
 
   FinalizationQueueObject* queue() const;
   ObjectWeakMap* registrations() const;
 
-  void sweep();
+  void traceWeak(JSTracer* trc);
 
   static bool unregisterRecord(FinalizationRecordObject* record);
 
   static bool cleanupQueuedRecords(JSContext* cx,
                                    HandleFinalizationRegistryObject registry,
                                    HandleObject callback = nullptr);
 
  private:
--- a/js/src/gc/FinalizationRegistry.cpp
+++ b/js/src/gc/FinalizationRegistry.cpp
@@ -83,26 +83,26 @@ void GCRuntime::traceWeakFinalizationReg
   for (Zone::FinalizationRegistrySet::Enum e(set); !e.empty(); e.popFront()) {
     auto result = TraceWeakEdge(trc, &e.mutableFront(), "FinalizationRegistry");
     if (result.isDead()) {
       auto* registry =
           &result.initialTarget()->as<FinalizationRegistryObject>();
       registry->queue()->setHasRegistry(false);
       e.removeFront();
     } else {
-      result.finalTarget()->as<FinalizationRegistryObject>().sweep();
+      result.finalTarget()->as<FinalizationRegistryObject>().traceWeak(trc);
     }
   }
 
   Zone::FinalizationRecordMap& map = zone->finalizationRecordMap();
   for (Zone::FinalizationRecordMap::Enum e(map); !e.empty(); e.popFront()) {
     FinalizationRecordVector& records = e.front().value();
 
     // Update any pointers moved by the GC.
-    records.sweep();
+    records.traceWeak(trc);
 
     // Sweep finalization records and remove records for:
     records.eraseIf([](JSObject* obj) {
       FinalizationRecordObject* record = UnwrapFinalizationRecord(obj);
       return !record ||                        // Nuked CCW to record.
              !record->isActive() ||            // Unregistered record.
              !record->queue()->hasRegistry();  // Dead finalization registry.
     });