Bug 1647319 - Split off NonAtomZonesIter from ZonesIter and add AllZonesIter r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 23 Jun 2020 10:54:35 +0000
changeset 536870 4a59ad84db1b0f7129b2e28c239b1035f277f3af
parent 536869 34fb904b1175fc534e40ec02e64824acb056d55f
child 536871 8624539378e168eba093ebe43b32953b0ef14689
push id37533
push userdluca@mozilla.com
push dateTue, 23 Jun 2020 21:38:40 +0000
treeherdermozilla-central@d48aa0f0aa0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1647319
milestone79.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 1647319 - Split off NonAtomZonesIter from ZonesIter and add AllZonesIter r=sfink It's useful in later patches to have zone iterators whose constructors take a single parameter. Differential Revision: https://phabricator.services.mozilla.com/D80482
js/src/gc/PublicIterators.h
--- a/js/src/gc/PublicIterators.h
+++ b/js/src/gc/PublicIterators.h
@@ -28,64 +28,95 @@ class JS_PUBLIC_API Realm;
 namespace js {
 
 // Accessing the atoms zone can be dangerous because helper threads may be
 // accessing it concurrently to the main thread, so it's better to skip the
 // atoms zone when iterating over zones. If you need to iterate over the atoms
 // zone, consider using AutoLockAllAtoms.
 enum ZoneSelector { WithAtoms, SkipAtoms };
 
-// Iterate over all zones in the runtime, except those which may be in use by
-// parse threads.
-class ZonesIter {
+// Iterate over all zones in the runtime apart from the atoms zone and those
+// which may be in use by parse threads.
+class NonAtomZonesIter {
   gc::AutoEnterIteration iterMarker;
-  JS::Zone* atomsZone;
   JS::Zone** it;
   JS::Zone** end;
 
  public:
-  ZonesIter(gc::GCRuntime* gc, ZoneSelector selector)
-      : iterMarker(gc),
-        atomsZone(selector == WithAtoms ? gc->atomsZone.ref() : nullptr),
-        it(gc->zones().begin()),
-        end(gc->zones().end()) {
-    if (!atomsZone) {
-      skipHelperThreadZones();
-    }
+  explicit NonAtomZonesIter(gc::GCRuntime* gc)
+      : iterMarker(gc), it(gc->zones().begin()), end(gc->zones().end()) {
+    skipHelperThreadZones();
   }
-  ZonesIter(JSRuntime* rt, ZoneSelector selector)
-      : ZonesIter(&rt->gc, selector) {}
+  explicit NonAtomZonesIter(JSRuntime* rt) : NonAtomZonesIter(&rt->gc) {}
 
-  bool done() const { return !atomsZone && it == end; }
+  bool done() const { return it == end; }
 
   void next() {
     MOZ_ASSERT(!done());
-    if (atomsZone) {
-      atomsZone = nullptr;
-    } else {
-      it++;
-    }
+    it++;
     skipHelperThreadZones();
   }
 
   void skipHelperThreadZones() {
     while (!done() && get()->usedByHelperThread()) {
       it++;
     }
   }
 
   JS::Zone* get() const {
     MOZ_ASSERT(!done());
-    return atomsZone ? atomsZone : *it;
+    return *it;
   }
 
   operator JS::Zone*() const { return get(); }
   JS::Zone* operator->() const { return get(); }
 };
 
+// Iterate over all zones in the runtime, except those which may be in use by
+// parse threads.  May or may not include the atoms zone.
+class ZonesIter {
+  JS::Zone* atomsZone;
+  NonAtomZonesIter otherZones;
+
+ public:
+  ZonesIter(gc::GCRuntime* gc, ZoneSelector selector)
+      : atomsZone(selector == WithAtoms ? gc->atomsZone.ref() : nullptr),
+        otherZones(gc) {}
+  ZonesIter(JSRuntime* rt, ZoneSelector selector)
+      : ZonesIter(&rt->gc, selector) {}
+
+  bool done() const { return !atomsZone && otherZones.done(); }
+
+  JS::Zone* get() const {
+    MOZ_ASSERT(!done());
+    return atomsZone ? atomsZone : otherZones.get();
+  }
+
+  void next() {
+    MOZ_ASSERT(!done());
+    if (atomsZone) {
+      atomsZone = nullptr;
+      return;
+    }
+
+    otherZones.next();
+  }
+
+  operator JS::Zone*() const { return get(); }
+  JS::Zone* operator->() const { return get(); }
+};
+
+// Iterate over all zones in the runtime, except those which may be in use by
+// parse threads.
+class AllZonesIter : public ZonesIter {
+ public:
+  explicit AllZonesIter(gc::GCRuntime* gc) : ZonesIter(gc, WithAtoms) {}
+  explicit AllZonesIter(JSRuntime* rt) : AllZonesIter(&rt->gc) {}
+};
+
 struct CompartmentsInZoneIter {
   using ItemType = JS::Compartment;
 
   explicit CompartmentsInZoneIter(JS::Zone* zone) : zone(zone) {
     it = zone->compartments().begin();
   }
 
   bool done() const {