Index: Source/platform/heap/Heap.cpp |
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
index 6803660f46a1e7e0de3cde134f42fc5eb62910a0..c36d9ed3e01e44ebc596d7d5a7a0b6fe18596e4c 100644 |
--- a/Source/platform/heap/Heap.cpp |
+++ b/Source/platform/heap/Heap.cpp |
@@ -288,6 +288,7 @@ public: |
explicit GCScope(ThreadState::StackState stackState) |
: m_state(ThreadState::current()) |
, m_safePointScope(stackState) |
+ , m_parkedAllThreads(false) |
{ |
m_state->checkThread(); |
@@ -296,20 +297,29 @@ public: |
// a row. |
RELEASE_ASSERT(!m_state->isInGC()); |
RELEASE_ASSERT(!m_state->isSweepInProgress()); |
- ThreadState::stopThreads(); |
- m_state->enterGC(); |
+ if (LIKELY(ThreadState::stopThreads())) { |
+ m_parkedAllThreads = true; |
+ m_state->enterGC(); |
+ } |
} |
+ bool allThreadsParked() { return m_parkedAllThreads; } |
+ |
~GCScope() |
{ |
- m_state->leaveGC(); |
- ASSERT(!m_state->isInGC()); |
- ThreadState::resumeThreads(); |
+ // Only cleanup if we parked all threads in which case the GC happened |
+ // and we need to resume the other threads. |
+ if (LIKELY(m_parkedAllThreads)) { |
+ m_state->leaveGC(); |
+ ASSERT(!m_state->isInGC()); |
+ ThreadState::resumeThreads(); |
+ } |
} |
private: |
ThreadState* m_state; |
ThreadState::SafePointScope m_safePointScope; |
+ bool m_parkedAllThreads; // False if we fail to park all threads |
}; |
NO_SANITIZE_ADDRESS |
@@ -1578,7 +1588,11 @@ void Heap::collectGarbage(ThreadState::StackState stackState) |
ThreadState::current()->clearGCRequested(); |
GCScope gcScope(stackState); |
- |
+ // Check if we successfully parked the other threads. If not we bail out of the GC. |
+ if (!gcScope.allThreadsParked()) { |
+ ThreadState::current()->setGCRequested(); |
+ return; |
+ } |
#if ENABLE(GC_TRACING) |
static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear(); |
#endif |