diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 4e2d322ea236..fa30966817b4 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -556,8 +556,34 @@ js::gc::GCRuntime::markRuntime(JSTracer *trc, 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); } diff --git a/js/src/gc/Tracer.cpp b/js/src/gc/Tracer.cpp index 02a9382b9180..938e858e782c 100644 --- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -652,28 +652,6 @@ 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() { diff --git a/js/src/gc/Tracer.h b/js/src/gc/Tracer.h index b2548ea6fb28..c2a42aa912b6 100644 --- a/js/src/gc/Tracer.h +++ b/js/src/gc/Tracer.h @@ -211,8 +211,6 @@ class GCMarker : public JSTracer * non-incremental GC. */ bool hasBufferedGrayRoots() const; - void startBufferingGrayRoots(); - void endBufferingGrayRoots(); void resetBufferedGrayRoots(); static void GrayCallback(JSTracer *trc, void **thing, JSGCTraceKind kind);