Bug 1144920 - Move gray buffer clearing out of GCMarker; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Thu, 19 Mar 2015 08:51:12 -0700
changeset 263333 e3655beb2ecd909a8a9c3c1755c5e8e5e89b51b7
parent 263332 a31a1564808af4f0ac21199049a903f670edd8d9
child 263334 ce3fea0cb25baff0c47881c634bea4e72eef1ef5
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1144920
milestone39.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 1144920 - Move gray buffer clearing out of GCMarker; r=jonco
js/src/gc/GCRuntime.h
js/src/gc/Tracer.cpp
js/src/jsgc.cpp
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -1032,18 +1032,26 @@ class GCRuntime
     friend class js::GCMarker;
     enum class GrayBufferState {
         Unused,
         Okay,
         Failed
     };
     GrayBufferState grayBufferState;
     bool hasBufferedGrayRoots() const { return grayBufferState == GrayBufferState::Okay; }
+
+    // Clear each zone's gray buffers, but do not change the current state.
     void resetBufferedGrayRoots() const;
 
+    // Reset the gray buffering state to Unused.
+    void clearBufferedGrayRoots() {
+        grayBufferState = GrayBufferState::Unused;
+        resetBufferedGrayRoots();
+    }
+
     /*
      * The gray bits can become invalid if UnmarkGray overflows the stack. A
      * full GC will reset this bit, since it fills in all the gray bits.
      */
     bool grayBitsValid;
 
     mozilla::Atomic<JS::gcreason::Reason, mozilla::Relaxed> majorGCTriggerReason;
 
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -549,19 +549,16 @@ GCMarker::stop()
     MOZ_ASSERT(started);
     started = false;
 
     MOZ_ASSERT(!unmarkedArenaStackTop);
     MOZ_ASSERT(markLaterArenas == 0);
 
     /* Free non-ballast stack memory. */
     stack.reset();
-
-    runtime()->gc.resetBufferedGrayRoots();
-    runtime()->gc.grayBufferState = GCRuntime::GrayBufferState::Unused;
 }
 
 void
 GCMarker::reset()
 {
     color = BLACK;
 
     stack.reset();
@@ -645,16 +642,18 @@ GCMarker::checkZone(void *p)
     DebugOnly<Cell *> cell = static_cast<Cell *>(p);
     MOZ_ASSERT_IF(cell->isTenured(), cell->asTenured().zone()->isCollecting());
 }
 #endif
 
 void
 GCRuntime::resetBufferedGrayRoots() const
 {
+    MOZ_ASSERT(grayBufferState != GrayBufferState::Okay,
+               "Do not clear the gray buffers unless we are Failed or becoming Unused");
     for (GCZonesIter zone(rt); !zone.done(); zone.next())
         zone->gcGrayRoots.clearAndFree();
 }
 
 void
 GCRuntime::markBufferedGrayRoots(JS::Zone *zone)
 {
     MOZ_ASSERT(grayBufferState == GrayBufferState::Okay);
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -5368,16 +5368,17 @@ GCRuntime::endCompactPhase(JS::gcreason:
     startedCompacting = false;
 }
 
 void
 GCRuntime::finishCollection(JS::gcreason::Reason reason)
 {
     MOZ_ASSERT(marker.isDrained());
     marker.stop();
+    clearBufferedGrayRoots();
 
     uint64_t currentTime = PRMJ_Now();
     schedulingState.updateHighFrequencyMode(lastGCTime, currentTime, tunables);
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         if (zone->isCollecting()) {
             MOZ_ASSERT(zone->isGCFinished());
             zone->setGCState(Zone::NoGC);
@@ -5491,16 +5492,17 @@ GCRuntime::resetIncrementalGC(const char
         return;
 
       case MARK: {
         /* Cancel any ongoing marking. */
         AutoCopyFreeListToArenasForGC copy(rt);
 
         marker.reset();
         marker.stop();
+        clearBufferedGrayRoots();
 
         for (GCCompartmentsIter c(rt); !c.done(); c.next())
             ResetGrayList(c);
 
         for (GCZonesIter zone(rt); !zone.done(); zone.next()) {
             MOZ_ASSERT(zone->isGCMarking());
             zone->setNeedsIncrementalBarrier(false, Zone::UpdateJit);
             zone->setGCState(Zone::NoGC);