Bug 1736397 - Part 5: Replace sweeping with tracing weak edges for unspecialized WeakCached things r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 19 Oct 2021 14:43:32 +0000
changeset 596356 aca331d41a22e9464226b83be07b8eae40c99b0f
parent 596355 e753336f6a843fc3d69fa844c3d4a428209275ea
child 596357 30cf1a1380997de94044810ab98c3fc1ad45e50a
push id38896
push userabutkovits@mozilla.com
push dateTue, 19 Oct 2021 21:51:00 +0000
treeherdermozilla-central@e9071741b84c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1736397
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 1736397 - Part 5: Replace sweeping with tracing weak edges for unspecialized WeakCached things r=sfink Making this change meant fixing WeakCached things that supplied their own sweep method at the same time because the custom sweep method would no longer be called. This dragged in a bunch of other changes but it's all along the same lines as the previous patches. Depends on D128859 Differential Revision: https://phabricator.services.mozilla.com/D128860
js/public/SweepingAPI.h
js/src/shell/jsshell.h
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/Compartment.cpp
js/src/vm/Realm.cpp
js/src/vm/Realm.h
--- a/js/public/SweepingAPI.h
+++ b/js/public/SweepingAPI.h
@@ -102,17 +102,17 @@ class WeakCache : protected detail::Weak
     // Take the store buffer lock in case sweeping triggers any generational
     // post barriers. This is not always required and WeakCache specializations
     // may delay or skip taking the lock as appropriate.
     mozilla::Maybe<js::gc::AutoLockStoreBuffer> lock;
     if (sbToLock) {
       lock.emplace(sbToLock);
     }
 
-    GCPolicy<T>::sweep(&cache);
+    GCPolicy<T>::traceWeak(trc, &cache);
     return 0;
   }
 
   bool empty() override { return cache.empty(); }
 } JS_HAZ_NON_GC_POINTER;
 
 }  // namespace JS
 
--- a/js/src/shell/jsshell.h
+++ b/js/src/shell/jsshell.h
@@ -170,22 +170,21 @@ extern UniqueChars processWideModuleLoad
 bool CreateAlias(JSContext* cx, const char* dstName,
                  JS::HandleObject namespaceObj, const char* srcName);
 
 enum class ScriptKind { Script, ScriptStencil, DecodeScript, Module };
 
 class NonshrinkingGCObjectVector
     : public GCVector<HeapPtrObject, 0, SystemAllocPolicy> {
  public:
-  void sweep() {
+  bool traceWeak(JSTracer* trc) {
     for (HeapPtrObject& obj : *this) {
-      if (JS::GCPolicy<HeapPtrObject>::needsSweep(&obj)) {
-        obj = nullptr;
-      }
+      TraceWeakEdge(trc, &obj, "NonshrinkingGCObjectVector element");
     }
+    return true;
   }
 };
 
 using MarkBitObservers = JS::WeakCache<NonshrinkingGCObjectVector>;
 
 #ifdef SINGLESTEP_PROFILING
 using StackChars = Vector<char16_t, 0, SystemAllocPolicy>;
 #endif
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1726,37 +1726,37 @@ InnerViewTable::ViewVector* InnerViewTab
 
 void InnerViewTable::removeViews(ArrayBufferObject* buffer) {
   Map::Ptr p = map.lookup(buffer);
   MOZ_ASSERT(p);
 
   map.remove(p);
 }
 
-void InnerViewTable::sweep() { map.sweep(); }
+bool InnerViewTable::traceWeak(JSTracer* trc) { return map.traceWeak(trc); }
 
-void InnerViewTable::sweepAfterMinorGC() {
+void InnerViewTable::sweepAfterMinorGC(JSTracer* trc) {
   MOZ_ASSERT(needsSweepAfterMinorGC());
 
   if (nurseryKeysValid) {
     for (size_t i = 0; i < nurseryKeys.length(); i++) {
       JSObject* buffer = MaybeForwarded(nurseryKeys[i]);
       Map::Ptr p = map.lookup(buffer);
-      if (p && Map::SweepPolicy::needsSweep(&p->mutableKey(), &p->value())) {
+      if (p &&
+          !Map::SweepPolicy::traceWeak(trc, &p->mutableKey(), &p->value())) {
         map.remove(p);
       }
     }
-    nurseryKeys.clear();
   } else {
     // Do the required sweeping by looking at every map entry.
-    nurseryKeys.clear();
-    sweep();
+    map.traceWeak(trc);
+  }
 
-    nurseryKeysValid = true;
-  }
+  nurseryKeys.clear();
+  nurseryKeysValid = true;
 }
 
 size_t InnerViewTable::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
   size_t vectorSize = 0;
   for (Map::Enum e(map); !e.empty(); e.popFront()) {
     vectorSize += e.front().value().sizeOfExcludingThis(mallocSizeOf);
   }
 
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -559,18 +559,18 @@ class InnerViewTable {
   ViewVector* maybeViewsUnbarriered(ArrayBufferObject* obj);
   void removeViews(ArrayBufferObject* obj);
 
  public:
   explicit InnerViewTable(Zone* zone) : map(zone), nurseryKeysValid(true) {}
 
   // Remove references to dead objects in the table and update table entries
   // to reflect moved objects.
-  void sweep();
-  void sweepAfterMinorGC();
+  bool traceWeak(JSTracer* trc);
+  void sweepAfterMinorGC(JSTracer* trc);
 
   bool empty() const { return map.empty(); }
 
   bool needsSweepAfterMinorGC() const {
     return !nurseryKeys.empty() || !nurseryKeysValid;
   }
 
   size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
--- a/js/src/vm/Compartment.cpp
+++ b/js/src/vm/Compartment.cpp
@@ -499,17 +499,17 @@ void Compartment::traceIncomingCrossComp
     DebugAPI::traceCrossCompartmentEdges(trc);
   }
 }
 
 void Compartment::sweepAfterMinorGC(JSTracer* trc) {
   crossCompartmentObjectWrappers.sweepAfterMinorGC(trc);
 
   for (RealmsInCompartmentIter r(this); !r.done(); r.next()) {
-    r->sweepAfterMinorGC();
+    r->sweepAfterMinorGC(trc);
   }
 }
 
 // Remove dead wrappers from the table or update pointers to moved objects.
 void Compartment::traceCrossCompartmentObjectWrapperEdges(JSTracer* trc) {
   crossCompartmentObjectWrappers.traceWeak(trc);
 }
 
--- a/js/src/vm/Realm.cpp
+++ b/js/src/vm/Realm.cpp
@@ -321,27 +321,27 @@ void ObjectRealm::finishRoots() {
 void Realm::finishRoots() {
   if (debugEnvs_) {
     debugEnvs_->finish();
   }
 
   objects_.finishRoots();
 }
 
-void ObjectRealm::sweepAfterMinorGC() {
+void ObjectRealm::sweepAfterMinorGC(JSTracer* trc) {
   InnerViewTable& table = innerViews.get();
   if (table.needsSweepAfterMinorGC()) {
-    table.sweepAfterMinorGC();
+    table.sweepAfterMinorGC(trc);
   }
 }
 
-void Realm::sweepAfterMinorGC() {
+void Realm::sweepAfterMinorGC(JSTracer* trc) {
   globalWriteBarriered = 0;
   dtoaCache.purge();
-  objects_.sweepAfterMinorGC();
+  objects_.sweepAfterMinorGC(trc);
 }
 
 void Realm::traceWeakSavedStacks(JSTracer* trc) { savedStacks_.traceWeak(trc); }
 
 void Realm::traceWeakGlobalEdge(JSTracer* trc) {
   // If the global is dead, free its GlobalObjectData.
   auto result = TraceWeakEdge(trc, &global_, "Realm::global_");
   if (result.isDead()) {
--- a/js/src/vm/Realm.h
+++ b/js/src/vm/Realm.h
@@ -260,17 +260,17 @@ class ObjectRealm {
 
   explicit ObjectRealm(JS::Zone* zone);
   ~ObjectRealm();
 
   [[nodiscard]] bool init(JSContext* cx);
 
   void finishRoots();
   void trace(JSTracer* trc);
-  void sweepAfterMinorGC();
+  void sweepAfterMinorGC(JSTracer* trc);
   void traceWeakNativeIterators(JSTracer* trc);
 
   void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
                               size_t* innerViewsArg,
                               size_t* objectMetadataTablesArg,
                               size_t* nonSyntacticLexicalEnvironmentsArg);
 
   MOZ_ALWAYS_INLINE bool objectMaybeInIteration(JSObject* obj);
@@ -513,17 +513,17 @@ class JS::Realm : public JS::shadow::Rea
    */
   void traceRoots(JSTracer* trc,
                   js::gc::GCRuntime::TraceOrMarkRuntime traceOrMark);
   /*
    * This method clears out tables of roots in preparation for the final GC.
    */
   void finishRoots();
 
-  void sweepAfterMinorGC();
+  void sweepAfterMinorGC(JSTracer* trc);
   void traceWeakDebugEnvironmentEdges(JSTracer* trc);
   void traceWeakObjectRealm(JSTracer* trc);
   void traceWeakRegExps(JSTracer* trc);
 
   void clearScriptCounts();
   void clearScriptLCov();
 
   void purge();