Bug 1144834 - Move resetBufferedGrayRoots to GCRuntime; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Thu, 19 Mar 2015 08:50:52 -0700
changeset 263332 a31a1564808af4f0ac21199049a903f670edd8d9
parent 263331 83c8a3ff722b2897d5d1c37ddbc3e5ceed7015dc
child 263333 e3655beb2ecd909a8a9c3c1755c5e8e5e89b51b7
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
bugs1144834
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 1144834 - Move resetBufferedGrayRoots to GCRuntime; r=jonco
js/src/gc/GCRuntime.h
js/src/gc/RootMarking.cpp
js/src/gc/Tracer.cpp
js/src/gc/Tracer.h
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -1032,16 +1032,17 @@ class GCRuntime
     friend class js::GCMarker;
     enum class GrayBufferState {
         Unused,
         Okay,
         Failed
     };
     GrayBufferState grayBufferState;
     bool hasBufferedGrayRoots() const { return grayBufferState == GrayBufferState::Okay; }
+    void resetBufferedGrayRoots() const;
 
     /*
      * 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/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -569,19 +569,22 @@ js::gc::GCRuntime::bufferGrayRoots()
     MOZ_ASSERT(!marker.bufferingGrayRootsFailed);
     marker.callback = GCMarker::GrayCallback;
     MOZ_ASSERT(IsMarkingGray(&marker));
 
     if (JSTraceDataOp op = grayRootTracer.op)
         (*op)(&marker, grayRootTracer.data);
 
     // Propagate the failure flag from the marker to the runtime.
-    grayBufferState = marker.bufferingGrayRootsFailed
-                      ? GrayBufferState::Failed
-                      : GrayBufferState::Okay;
+    if (marker.bufferingGrayRootsFailed) {
+      grayBufferState = GrayBufferState::Failed;
+      resetBufferedGrayRoots();
+    } else {
+      grayBufferState = GrayBufferState::Okay;
+    }
 
     // Restore the GCMarker to its former correctness.
     MOZ_ASSERT(IsMarkingGray(&marker));
     marker.bufferingGrayRootsFailed = false;
     marker.callback = nullptr;
     MOZ_ASSERT(!IsMarkingGray(&marker));
     MOZ_ASSERT(IsMarkingTracer(&marker));
 }
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -550,17 +550,17 @@ GCMarker::stop()
     started = false;
 
     MOZ_ASSERT(!unmarkedArenaStackTop);
     MOZ_ASSERT(markLaterArenas == 0);
 
     /* Free non-ballast stack memory. */
     stack.reset();
 
-    resetBufferedGrayRoots();
+    runtime()->gc.resetBufferedGrayRoots();
     runtime()->gc.grayBufferState = GCRuntime::GrayBufferState::Unused;
 }
 
 void
 GCMarker::reset()
 {
     color = BLACK;
 
@@ -643,19 +643,19 @@ GCMarker::checkZone(void *p)
 {
     MOZ_ASSERT(started);
     DebugOnly<Cell *> cell = static_cast<Cell *>(p);
     MOZ_ASSERT_IF(cell->isTenured(), cell->asTenured().zone()->isCollecting());
 }
 #endif
 
 void
-GCMarker::resetBufferedGrayRoots()
+GCRuntime::resetBufferedGrayRoots() const
 {
-    for (GCZonesIter zone(runtime()); !zone.done(); zone.next())
+    for (GCZonesIter zone(rt); !zone.done(); zone.next())
         zone->gcGrayRoots.clearAndFree();
 }
 
 void
 GCRuntime::markBufferedGrayRoots(JS::Zone *zone)
 {
     MOZ_ASSERT(grayBufferState == GrayBufferState::Okay);
     MOZ_ASSERT(zone->isGCMarkingGray() || zone->isGCCompacting());
@@ -694,20 +694,18 @@ GCMarker::appendGrayRoot(void *thing, JS
             static_cast<JSObject *>(thing)->compartment()->maybeAlive = true;
             break;
           case JSTRACE_SCRIPT:
             static_cast<JSScript *>(thing)->compartment()->maybeAlive = true;
             break;
           default:
             break;
         }
-        if (!zone->gcGrayRoots.append(root)) {
+        if (!zone->gcGrayRoots.append(root))
             bufferingGrayRootsFailed = true;
-            resetBufferedGrayRoots();
-        }
     }
 }
 
 void
 GCMarker::GrayCallback(JSTracer *trc, void **thingp, JSGCTraceKind kind)
 {
     MOZ_ASSERT(thingp);
     MOZ_ASSERT(*thingp);
--- a/js/src/gc/Tracer.h
+++ b/js/src/gc/Tracer.h
@@ -199,18 +199,16 @@ class GCMarker : public JSTracer
         return isMarkStackEmpty() && !unmarkedArenaStackTop;
     }
 
     bool drainMarkStack(SliceBudget &budget);
 
     /* Set to false if we OOM while buffering gray roots. */
     bool bufferingGrayRootsFailed;
 
-    void resetBufferedGrayRoots();
-
     static void GrayCallback(JSTracer *trc, void **thing, JSGCTraceKind kind);
 
     void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
 #ifdef DEBUG
     bool shouldCheckCompartments() { return strictCompartmentChecking; }