Index: Source/platform/heap/Heap.cpp |
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
index aba2f9295a3be2b5a4d27f60a76b460bdfc5794a..4062e5c03157ee62d0fb62a1e211b63410917618 100644 |
--- a/Source/platform/heap/Heap.cpp |
+++ b/Source/platform/heap/Heap.cpp |
@@ -2082,7 +2082,23 @@ void Heap::collectGarbage(ThreadState::StackState stackState) |
prepareForGC(); |
- traceRootsAndPerformGlobalWeakProcessing<GlobalMarking>(); |
+ // 1. trace persistent roots. |
+ ThreadState::visitPersistentRoots(s_markingVisitor); |
+ |
+ // 2. trace objects reachable from the persistent roots including ephemerons. |
+ processMarkingStack<GlobalMarking>(); |
+ |
+ // 3. trace objects reachable from the stack. We do this independent of the |
+ // given stackState since other threads might have a different stack state. |
+ ThreadState::visitStackRoots(s_markingVisitor); |
+ |
+ // 4. trace objects reachable from the stack "roots" including ephemerons. |
+ // Only do the processing if we found a pointer to an object on one of the |
+ // thread stacks. |
+ if (lastGCWasConservative()) |
+ processMarkingStack<GlobalMarking>(); |
+ |
+ globalWeakProcessingAndCleanup(); |
// After a global marking we know that any orphaned page that was not reached |
// cannot be reached in a subsequent GC. This is due to a thread either having |
@@ -2122,7 +2138,23 @@ void Heap::collectGarbageForTerminatingThread(ThreadState* state) |
state->enterGC(); |
state->prepareForGC(); |
- traceRootsAndPerformGlobalWeakProcessing<ThreadLocalMarking>(); |
+ // 1. trace the thread local persistent roots. For thread local GCs we |
+ // don't trace the stack (ie. no conservative scanning) since this is |
+ // only called during thread shutdown where there should be no objects |
+ // on the stack. |
+ // We also assume that orphaned pages have no objects reachable from |
+ // persistent handles on other threads or CrossThreadPersistents. The |
+ // only cases where this could happen is if a subsequent conservative |
+ // global GC finds a "pointer" on the stack or due to a programming |
+ // error where an object has a dangling cross-thread pointer to an |
+ // object on this heap. |
+ state->visitPersistents(s_markingVisitor); |
+ |
+ // 2. trace objects reachable from the thread's persistent roots |
+ // including ephemerons. |
+ processMarkingStack<ThreadLocalMarking>(); |
+ |
+ globalWeakProcessingAndCleanup(); |
state->leaveGC(); |
} |
@@ -2130,18 +2162,14 @@ void Heap::collectGarbageForTerminatingThread(ThreadState* state) |
} |
template<CallbackInvocationMode Mode> |
-void Heap::traceRootsAndPerformGlobalWeakProcessing() |
+void Heap::processMarkingStack() |
{ |
- if (Mode == ThreadLocalMarking) |
- ThreadState::current()->visitLocalRoots(s_markingVisitor); |
- else |
- ThreadState::visitRoots(s_markingVisitor); |
- |
// Ephemeron fixed point loop. |
do { |
- // Recursively mark all objects that are reachable from the roots for |
- // this thread. If Mode is ThreadLocalMarking don't continue tracing if |
- // the trace hits an object on another thread's heap. |
+ // Iteratively mark all objects that are reachable from the objects |
+ // currently pushed onto the marking stack. If Mode is ThreadLocalMarking |
+ // don't continue tracing if the trace hits an object on another thread's |
+ // heap. |
while (popAndInvokeTraceCallback<Mode>(s_markingVisitor)) { } |
// Mark any strong pointers that have now become reachable in ephemeron |
@@ -2150,7 +2178,10 @@ void Heap::traceRootsAndPerformGlobalWeakProcessing() |
// Rerun loop if ephemeron processing queued more objects for tracing. |
} while (!s_markingStack->isEmpty()); |
+} |
+void Heap::globalWeakProcessingAndCleanup() |
+{ |
// Call weak callbacks on objects that may now be pointing to dead |
// objects and call ephemeronIterationDone callbacks on weak tables |
// to do cleanup (specifically clear the queued bits for weak hash |