Bug 1144811 - Inline the start and end buffering gray roots methods on GCMarker; r=jonco
authorTerrence Cole <terrence@mozilla.com>
Wed, 18 Mar 2015 11:11:57 -0700
changeset 234491 79ab363969377e90ead61da164b3617163f5ee18
parent 234490 512d9627cc547e541f0e8c8a85fcf161a1a98c8d
child 234492 8f19e666277d0140bb0250caa007ce10709534a2
push id28446
push userkwierso@gmail.com
push dateFri, 20 Mar 2015 02:15:45 +0000
treeherdermozilla-central@3257d9c4b257 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1144811
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 1144811 - Inline the start and end buffering gray roots methods on GCMarker; r=jonco
js/src/gc/RootMarking.cpp
js/src/gc/Tracer.cpp
js/src/gc/Tracer.h
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -551,13 +551,39 @@ js::gc::GCRuntime::markRuntime(JSTracer 
                 (*op)(trc, grayRootTracer.data);
         }
     }
 }
 
 void
 js::gc::GCRuntime::bufferGrayRoots()
 {
-    marker.startBufferingGrayRoots();
+    // Precondition: the state has been reset to "unused" after the last GC
+    //               and the zone's buffers have been cleared.
+    MOZ_ASSERT(grayBufferState == GrayBufferState::Unused);
+    for (GCZonesIter zone(rt); !zone.done(); zone.next())
+        MOZ_ASSERT(zone->gcGrayRoots.empty());
+
+    // The state starts at "Okay" and may be toggled to "Failed" if we OOM
+    // while marking.
+    grayBufferState = GrayBufferState::Okay;
+
+    // Transform the GCMarker into an unholy CallbackTracer doppleganger.
+    MOZ_ASSERT(!IsMarkingGray(&marker));
+    MOZ_ASSERT(IsMarkingTracer(&marker));
+    MOZ_ASSERT(!marker.callback);
+    marker.callback = GCMarker::GrayCallback;
+    MOZ_ASSERT(IsMarkingGray(&marker));
+
     if (JSTraceDataOp op = grayRootTracer.op)
         (*op)(&marker, grayRootTracer.data);
-    marker.endBufferingGrayRoots();
+
+    // Restore the GCMarker to its former correctness.
+    MOZ_ASSERT(IsMarkingGray(&marker));
+    marker.callback = nullptr;
+    MOZ_ASSERT(!IsMarkingGray(&marker));
+    MOZ_ASSERT(IsMarkingTracer(&marker));
+
+    // Postcondition: the state remains at "Okay", or has been toggled to
+    //                "Failed" during marking.
+    MOZ_ASSERT(grayBufferState == GrayBufferState::Okay ||
+               grayBufferState == GrayBufferState::Failed);
 }
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -648,38 +648,16 @@ GCMarker::checkZone(void *p)
 
 bool
 GCMarker::hasBufferedGrayRoots() const
 {
     return runtime()->gc.grayBufferState == GCRuntime::GrayBufferState::Okay;
 }
 
 void
-GCMarker::startBufferingGrayRoots()
-{
-    MOZ_ASSERT(runtime()->gc.grayBufferState == GCRuntime::GrayBufferState::Unused);
-    runtime()->gc.grayBufferState = GCRuntime::GrayBufferState::Okay;
-    for (GCZonesIter zone(runtime()); !zone.done(); zone.next())
-        MOZ_ASSERT(zone->gcGrayRoots.empty());
-
-    MOZ_ASSERT(!callback);
-    callback = GrayCallback;
-    MOZ_ASSERT(IsMarkingGray(this));
-}
-
-void
-GCMarker::endBufferingGrayRoots()
-{
-    MOZ_ASSERT(IsMarkingGray(this));
-    callback = nullptr;
-    MOZ_ASSERT(runtime()->gc.grayBufferState == GCRuntime::GrayBufferState::Okay ||
-               runtime()->gc.grayBufferState == GCRuntime::GrayBufferState::Failed);
-}
-
-void
 GCMarker::resetBufferedGrayRoots()
 {
     for (GCZonesIter zone(runtime()); !zone.done(); zone.next())
         zone->gcGrayRoots.clearAndFree();
 }
 
 void
 GCRuntime::markBufferedGrayRoots(JS::Zone *zone)
--- a/js/src/gc/Tracer.h
+++ b/js/src/gc/Tracer.h
@@ -206,18 +206,16 @@ class GCMarker : public JSTracer
      * we do not have write barriers on XPConnect roots. Therefore, XPConnect
      * roots must be accumulated in the first slice of incremental GC. We
      * accumulate these roots in the each compartment's gcGrayRoots vector and
      * then mark them later, after black marking is complete for each
      * compartment. This accumulation can fail, but in that case we switch to
      * non-incremental GC.
      */
     bool hasBufferedGrayRoots() const;
-    void startBufferingGrayRoots();
-    void endBufferingGrayRoots();
     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;