Bug 1126865 - Refactor GCRutime::sweepPhase() a little r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 29 Jan 2015 09:58:06 +0000
changeset 226542 4aa870ca28d64f42d75b50ad61e655ba715df382
parent 226541 da03ea6e22dd485d2bf49dce1188894a1773715b
child 226543 8e450ff88d613ddb009fa7b211d6874c0fbf7dae
push id28200
push userkwierso@gmail.com
push dateThu, 29 Jan 2015 23:01:46 +0000
treeherdermozilla-central@4380ed39de3a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1126865
milestone38.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 1126865 - Refactor GCRutime::sweepPhase() a little r=sfink
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -5155,37 +5155,47 @@ ArenaLists::foregroundFinalize(FreeOp *f
 bool
 GCRuntime::drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase)
 {
     /* Run a marking slice and return whether the stack is now empty. */
     gcstats::AutoPhase ap(stats, phase);
     return marker.drainMarkStack(sliceBudget);
 }
 
-// Advance to the next entry in a list of arenas, returning false if the
-// mutator should resume running.
+static void
+SweepThing(Shape *shape)
+{
+    if (!shape->isMarked())
+        shape->sweep();
+}
+
+static void
+SweepThing(JSScript *script, types::AutoClearTypeInferenceStateOnOOM *oom)
+{
+    script->maybeSweepTypes(oom);
+}
+
+static void
+SweepThing(types::TypeObject *typeObject, types::AutoClearTypeInferenceStateOnOOM *oom)
+{
+    typeObject->maybeSweep(oom);
+}
+
+template <typename T, typename... Args>
 static bool
-AdvanceArenaList(ArenaHeader **list, AllocKind kind, SliceBudget &sliceBudget)
-{
-    *list = (*list)->next;
-    sliceBudget.step(Arena::thingsPerArena(Arena::thingSize(kind)));
-    return !sliceBudget.isOverBudget();
-}
-
-static bool
-SweepShapes(ArenaHeader **arenasToSweep, AllocKind kind, SliceBudget &sliceBudget)
+SweepArenaList(ArenaHeader **arenasToSweep, SliceBudget &sliceBudget, Args... args)
 {
     while (ArenaHeader *arena = *arenasToSweep) {
-        for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
-            Shape *shape = i.get<Shape>();
-            if (!shape->isMarked())
-                shape->sweep();
-        }
-
-        if (!AdvanceArenaList(arenasToSweep, kind, sliceBudget))
+        for (ArenaCellIterUnderGC i(arena); !i.done(); i.next())
+            SweepThing(i.get<T>(), args...);
+
+        *arenasToSweep = (*arenasToSweep)->next;
+        AllocKind kind = MapTypeToFinalizeKind<T>::kind;
+        sliceBudget.step(Arena::thingsPerArena(Arena::thingSize(kind)));
+        if (sliceBudget.isOverBudget())
             return false;
     }
 
     return true;
 }
 
 bool
 GCRuntime::sweepPhase(SliceBudget &sliceBudget)
@@ -5209,40 +5219,23 @@ GCRuntime::sweepPhase(SliceBudget &slice
             gcstats::AutoPhase ap1(stats, gcstats::PHASE_SWEEP_COMPARTMENTS);
             gcstats::AutoPhase ap2(stats, gcstats::PHASE_SWEEP_TYPES);
 
             for (; sweepZone; sweepZone = sweepZone->nextNodeInGroup()) {
                 ArenaLists &al = sweepZone->arenas;
 
                 types::AutoClearTypeInferenceStateOnOOM oom(sweepZone);
 
-                while (ArenaHeader *arena = al.gcScriptArenasToUpdate) {
-                    for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
-                        JSScript *script = i.get<JSScript>();
-                        script->maybeSweepTypes(&oom);
-                    }
-
-                    if (!AdvanceArenaList(&al.gcScriptArenasToUpdate,
-                                          FINALIZE_SCRIPT, sliceBudget))
-                    {
-                        return false;
-                    }
-                }
-
-                while (ArenaHeader *arena = al.gcTypeObjectArenasToUpdate) {
-                    for (ArenaCellIterUnderGC i(arena); !i.done(); i.next()) {
-                        types::TypeObject *object = i.get<types::TypeObject>();
-                        object->maybeSweep(&oom);
-                    }
-
-                    if (!AdvanceArenaList(&al.gcTypeObjectArenasToUpdate,
-                                          FINALIZE_TYPE_OBJECT, sliceBudget))
-                    {
-                        return false;
-                    }
+                if (!SweepArenaList<JSScript>(&al.gcScriptArenasToUpdate, sliceBudget, &oom))
+                    return false;
+
+                if (!SweepArenaList<types::TypeObject>(
+                        &al.gcTypeObjectArenasToUpdate, sliceBudget, &oom))
+                {
+                    return false;
                 }
 
                 // Finish sweeping type information in the zone.
                 {
                     gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_TYPES_END);
                     sweepZone->types.endSweep(rt);
                 }
 
@@ -5284,24 +5277,23 @@ GCRuntime::sweepPhase(SliceBudget &slice
             sweepZone = currentZoneGroup;
         }
 
         /* Remove dead shapes from the shape tree, but don't finalize them yet. */
         {
             gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP_SHAPE);
 
             for (; sweepZone; sweepZone = sweepZone->nextNodeInGroup()) {
-                Zone *zone = sweepZone;
-                if (!SweepShapes(&zone->arenas.gcShapeArenasToUpdate, FINALIZE_SHAPE, sliceBudget))
+                ArenaLists &al = sweepZone->arenas;
+
+                if (!SweepArenaList<Shape>(&al.gcShapeArenasToUpdate, sliceBudget))
                     return false;  /* Yield to the mutator. */
-                if (!SweepShapes(&zone->arenas.gcAccessorShapeArenasToUpdate,
-                                 FINALIZE_ACCESSOR_SHAPE, sliceBudget))
-                {
+
+                if (!SweepArenaList<AccessorShape>(&al.gcAccessorShapeArenasToUpdate, sliceBudget))
                     return false;  /* Yield to the mutator. */
-                }
             }
         }
 
         endSweepingZoneGroup();
         getNextZoneGroup();
         if (!currentZoneGroup)
             return true;  /* We're finished. */
         endMarkingZoneGroup();