Bug 1520076 - Schedule zones for GC after running callbacks r=jonco
authorPaul Bone <pbone@mozilla.com>
Wed, 23 Jan 2019 11:43:08 +1100
changeset 514968 cb5546692ed64bbb4d8e82dd971d21d0029810a3
parent 514967 c60e6c0c2e2318295d1bec96e95ec7eaa9b48087
child 514969 48afe4849336998668fc7761597f0c74b57a656a
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1520076
milestone66.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 1520076 - Schedule zones for GC after running callbacks r=jonco
js/src/gc/GC.cpp
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -7279,60 +7279,53 @@ GCRuntime::IncrementalResult GCRuntime::
 
   if (resetReason != AbortReason::None) {
     return resetIncrementalGC(resetReason);
   }
 
   return IncrementalResult::Ok;
 }
 
-namespace {
-
-class AutoScheduleZonesForGC {
-  JSRuntime* rt_;
-
- public:
-  explicit AutoScheduleZonesForGC(GCRuntime* gc) : rt_(gc->rt) {
-    for (ZonesIter zone(rt_, WithAtoms); !zone.done(); zone.next()) {
-      if (!zone->canCollect()) {
-        continue;
-      }
-
-      if (gc->gcMode() == JSGC_MODE_GLOBAL) {
-        zone->scheduleGC();
-      }
-
-      // To avoid resets, continue to collect any zones that were being
-      // collected in a previous slice.
-      if (gc->isIncrementalGCInProgress() && zone->wasGCStarted()) {
-        zone->scheduleGC();
-      }
-
-      // This is a heuristic to reduce the total number of collections.
-      bool inHighFrequencyMode = gc->schedulingState.inHighFrequencyGCMode();
-      if (zone->zoneSize.gcBytes() >=
-          zone->threshold.eagerAllocTrigger(inHighFrequencyMode)) {
-        zone->scheduleGC();
-      }
-
-      // This ensures we collect zones that have reached the malloc limit.
-      if (zone->shouldTriggerGCForTooMuchMalloc()) {
-        zone->scheduleGC();
-      }
-    }
-  }
-
-  ~AutoScheduleZonesForGC() {
-    for (ZonesIter zone(rt_, WithAtoms); !zone.done(); zone.next()) {
-      zone->unscheduleGC();
-    }
-  }
-};
-
-} /* anonymous namespace */
+static void ScheduleZones(GCRuntime* gc) {
+  JSRuntime* rt = gc->rt;
+
+  for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
+    if (!zone->canCollect()) {
+      continue;
+    }
+
+    if (gc->gcMode() == JSGC_MODE_GLOBAL) {
+      zone->scheduleGC();
+    }
+
+    // To avoid resets, continue to collect any zones that were being
+    // collected in a previous slice.
+    if (gc->isIncrementalGCInProgress() && zone->wasGCStarted()) {
+      zone->scheduleGC();
+    }
+
+    // This is a heuristic to reduce the total number of collections.
+    bool inHighFrequencyMode = gc->schedulingState.inHighFrequencyGCMode();
+    if (zone->zoneSize.gcBytes() >=
+        zone->threshold.eagerAllocTrigger(inHighFrequencyMode)) {
+      zone->scheduleGC();
+    }
+
+    // This ensures we collect zones that have reached the malloc limit.
+    if (zone->shouldTriggerGCForTooMuchMalloc()) {
+      zone->scheduleGC();
+    }
+  }
+}
+
+static void UnScheduleZones(GCRuntime* gc) {
+  for (ZonesIter zone(gc->rt, WithAtoms); !zone.done(); zone.next()) {
+    zone->unscheduleGC();
+  }
+}
 
 class js::gc::AutoCallGCCallbacks {
   GCRuntime& gc_;
 
  public:
   explicit AutoCallGCCallbacks(GCRuntime& gc) : gc_(gc) {
     gc_.maybeCallGCCallback(JSGC_BEGIN);
   }
@@ -7382,16 +7375,17 @@ MOZ_NEVER_INLINE GCRuntime::IncrementalR
 
   // It's ok if threads other than the main thread have suppressGC set, as
   // they are operating on zones which will not be collected from here.
   MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
 
   // Note that GC callbacks are allowed to re-enter GC.
   AutoCallGCCallbacks callCallbacks(*this);
 
+  ScheduleZones(this);
   gcstats::AutoGCSlice agc(stats(), scanZonesBeforeGC(), invocationKind, budget,
                            reason);
 
   auto result = budgetIncrementalGC(nonincrementalByAPI, reason, budget);
   if (result == IncrementalResult::ResetIncremental) {
     reason = JS::GCReason::RESET;
   }
 
@@ -7590,17 +7584,16 @@ void GCRuntime::collect(bool nonincremen
   }
 
   stats().writeLogMessage("GC starting in state %s",
                           StateName(incrementalState));
 
   AutoTraceLog logGC(TraceLoggerForCurrentThread(), TraceLogger_GC);
   AutoStopVerifyingBarriers av(rt, IsShutdownGC(reason));
   AutoEnqueuePendingParseTasksAfterGC aept(*this);
-  AutoScheduleZonesForGC asz(this);
 
   bool repeat;
   do {
     IncrementalResult cycleResult =
         gcCycle(nonincrementalByAPI, budget, reason);
 
     if (reason == JS::GCReason::ABORT_GC) {
       MOZ_ASSERT(!isIncrementalGCInProgress());
@@ -7650,16 +7643,18 @@ void GCRuntime::collect(bool nonincremen
     gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::TRACE_HEAP);
     CheckHeapAfterGC(rt);
   }
   if (hasZealMode(ZealMode::CheckGrayMarking) && !isIncrementalGCInProgress()) {
     MOZ_RELEASE_ASSERT(CheckGrayMarkingState(rt));
   }
 #endif
   stats().writeLogMessage("GC ending in state %s", StateName(incrementalState));
+
+  UnScheduleZones(this);
 }
 
 js::AutoEnqueuePendingParseTasksAfterGC::
     ~AutoEnqueuePendingParseTasksAfterGC() {
   if (!OffThreadParsingMustWaitForGC(gc_.rt)) {
     EnqueuePendingParseTasksAfterGC(gc_.rt);
   }
 }