Bug 1464134 part 5 - Combine CompartmentsIterT and RealmsIterT in a single template class. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 30 May 2018 20:14:18 +0200
changeset 420611 51748a8a2967a48721906dc0ba9cf3515146a22a
parent 420610 5e336efffea84e94dafabdc0321e64add15df847
child 420612 e73059705526a72f917a5d3acb1a8aa90d1152d7
push id34075
push userapavel@mozilla.com
push dateThu, 31 May 2018 10:04:49 +0000
treeherdermozilla-central@763f30c34212 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1464134
milestone62.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 1464134 part 5 - Combine CompartmentsIterT and RealmsIterT in a single template class. r=jonco
js/src/gc/PrivateIterators-inl.h
js/src/gc/PublicIterators.h
--- a/js/src/gc/PrivateIterators-inl.h
+++ b/js/src/gc/PrivateIterators-inl.h
@@ -84,18 +84,18 @@ class GCZonesIter
         MOZ_ASSERT(!done());
         return zone;
     }
 
     operator JS::Zone*() const { return get(); }
     JS::Zone* operator->() const { return get(); }
 };
 
-using GCCompartmentsIter = CompartmentsIterT<GCZonesIter>;
-using GCRealmsIter = RealmsIterT<GCZonesIter>;
+using GCCompartmentsIter = CompartmentsOrRealmsIterT<GCZonesIter, CompartmentsInZoneIter>;
+using GCRealmsIter = CompartmentsOrRealmsIterT<GCZonesIter, RealmsInZoneIter>;
 
 /* Iterates over all zones in the current sweep group. */
 class SweepGroupZonesIter {
     JS::Zone* current;
 
   public:
     explicit SweepGroupZonesIter(JSRuntime* rt) {
         MOZ_ASSERT(CurrentThreadIsPerformingGC());
@@ -113,18 +113,18 @@ class SweepGroupZonesIter {
         MOZ_ASSERT(!done());
         return current;
     }
 
     operator JS::Zone*() const { return get(); }
     JS::Zone* operator->() const { return get(); }
 };
 
-using SweepGroupCompartmentsIter = CompartmentsIterT<SweepGroupZonesIter>;
-using SweepGroupRealmsIter = RealmsIterT<SweepGroupZonesIter>;
+using SweepGroupCompartmentsIter = CompartmentsOrRealmsIterT<SweepGroupZonesIter, CompartmentsInZoneIter>;
+using SweepGroupRealmsIter = CompartmentsOrRealmsIterT<SweepGroupZonesIter, RealmsInZoneIter>;
 
 // Iterate the free cells in an arena. See also ArenaCellIterImpl which iterates
 // the allocated cells.
 class ArenaFreeCellIter
 {
     Arena* arena;
     size_t thingSize;
     FreeSpan span;
--- a/js/src/gc/PublicIterators.h
+++ b/js/src/gc/PublicIterators.h
@@ -69,16 +69,18 @@ class ZonesIter
     }
 
     operator JS::Zone*() const { return get(); }
     JS::Zone* operator->() const { return get(); }
 };
 
 struct CompartmentsInZoneIter
 {
+    using ItemType = JSCompartment;
+
     explicit CompartmentsInZoneIter(JS::Zone* zone) : zone(zone) {
         it = zone->compartments().begin();
     }
 
     bool done() const {
         MOZ_ASSERT(it);
         return it < zone->compartments().begin() ||
                it >= zone->compartments().end();
@@ -94,23 +96,16 @@ struct CompartmentsInZoneIter
     }
 
     operator JSCompartment*() const { return get(); }
     JSCompartment* operator->() const { return get(); }
 
   private:
     JS::Zone* zone;
     JSCompartment** it;
-
-    CompartmentsInZoneIter()
-      : zone(nullptr), it(nullptr)
-    {}
-
-    // This is for the benefit of CompartmentsIterT::comp.
-    friend class mozilla::Maybe<CompartmentsInZoneIter>;
 };
 
 class RealmsInCompartmentIter
 {
     JSCompartment* comp;
     JS::Realm** it;
 
   public:
@@ -140,16 +135,18 @@ class RealmsInCompartmentIter
 };
 
 class RealmsInZoneIter
 {
     CompartmentsInZoneIter comp;
     mozilla::Maybe<RealmsInCompartmentIter> realm;
 
   public:
+    using ItemType = JS::Realm;
+
     explicit RealmsInZoneIter(JS::Zone* zone)
       : comp(zone)
     {
         settleOnCompartment();
     }
 
     void settleOnCompartment() {
         if (!comp.done()) {
@@ -177,99 +174,64 @@ class RealmsInZoneIter
     JS::Realm* get() const {
         return realm->get();
     }
 
     operator JS::Realm*() const { return get(); }
     JS::Realm* operator->() const { return get(); }
 };
 
-// This iterator iterates over all the compartments in a given set of zones. The
-// set of zones is determined by iterating ZoneIterT.
-template<class ZonesIterT>
-class CompartmentsIterT
+// This iterator iterates over all the compartments or realms in a given set of
+// zones. The set of zones is determined by iterating ZoneIterT. The set of
+// compartments or realms is determined by InnerIterT.
+template<class ZonesIterT, class InnerIterT>
+class CompartmentsOrRealmsIterT
 {
+    using T = typename InnerIterT::ItemType;
+
     gc::AutoEnterIteration iterMarker;
     ZonesIterT zone;
-    mozilla::Maybe<CompartmentsInZoneIter> comp;
+    mozilla::Maybe<InnerIterT> inner;
 
   public:
-    explicit CompartmentsIterT(JSRuntime* rt)
+    explicit CompartmentsOrRealmsIterT(JSRuntime* rt)
       : iterMarker(&rt->gc), zone(rt)
     {
-        if (zone.done())
-            comp.emplace();
-        else
-            comp.emplace(zone);
+        if (!zone.done())
+            inner.emplace(zone);
     }
 
-    CompartmentsIterT(JSRuntime* rt, ZoneSelector selector)
+    CompartmentsOrRealmsIterT(JSRuntime* rt, ZoneSelector selector)
       : iterMarker(&rt->gc), zone(rt, selector)
     {
-        if (zone.done())
-            comp.emplace();
-        else
-            comp.emplace(zone);
+        if (!zone.done())
+            inner.emplace(zone);
     }
 
     bool done() const { return zone.done(); }
 
     void next() {
         MOZ_ASSERT(!done());
-        MOZ_ASSERT(!comp.ref().done());
-        comp->next();
-        if (comp->done()) {
-            comp.reset();
+        MOZ_ASSERT(!inner.ref().done());
+        inner->next();
+        if (inner->done()) {
+            inner.reset();
             zone.next();
             if (!zone.done())
-                comp.emplace(zone);
+                inner.emplace(zone);
         }
     }
 
-    JSCompartment* get() const {
+    T* get() const {
         MOZ_ASSERT(!done());
-        return *comp;
+        return *inner;
     }
 
-    operator JSCompartment*() const { return get(); }
-    JSCompartment* operator->() const { return get(); }
+    operator T*() const { return get(); }
+    T* operator->() const { return get(); }
 };
 
-using CompartmentsIter = CompartmentsIterT<ZonesIter>;
-
-// This iterator iterates over all the realms in a given set of zones. The
-// set of zones is determined by iterating ZoneIterT.
-template<class ZonesIterT>
-class RealmsIterT
-{
-    gc::AutoEnterIteration iterMarker;
-    CompartmentsIterT<ZonesIterT> comp;
-
-  public:
-    explicit RealmsIterT(JSRuntime* rt)
-      : iterMarker(&rt->gc), comp(rt)
-    {}
-
-    RealmsIterT(JSRuntime* rt, ZoneSelector selector)
-      : iterMarker(&rt->gc), comp(rt, selector)
-    {}
-
-    bool done() const { return comp.done(); }
-
-    void next() {
-        MOZ_ASSERT(!done());
-        comp.next();
-    }
-
-    JS::Realm* get() const {
-        MOZ_ASSERT(!done());
-        return JS::GetRealmForCompartment(comp.get());
-    }
-
-    operator JS::Realm*() const { return get(); }
-    JS::Realm* operator->() const { return get(); }
-};
-
-using RealmsIter = RealmsIterT<ZonesIter>;
+using CompartmentsIter = CompartmentsOrRealmsIterT<ZonesIter, CompartmentsInZoneIter>;
+using RealmsIter = CompartmentsOrRealmsIterT<ZonesIter, RealmsInZoneIter>;
 
 } // namespace js
 
 #endif // gc_PublicIterators_h