| Index: Source/platform/heap/ThreadState.cpp | 
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp | 
| index 90421079cecaaf7ecf0b5030bc839390d1bd024c..9ef1f18dee738814d719af0bcbaa2ae7138ff9bc 100644 | 
| --- a/Source/platform/heap/ThreadState.cpp | 
| +++ b/Source/platform/heap/ThreadState.cpp | 
| @@ -725,7 +725,6 @@ void unexpectedGCState(ThreadState::GCState gcState) | 
| UNEXPECTED_GCSTATE(IdleGCScheduled); | 
| UNEXPECTED_GCSTATE(PreciseGCScheduled); | 
| UNEXPECTED_GCSTATE(FullGCScheduled); | 
| -        UNEXPECTED_GCSTATE(StoppingOtherThreads); | 
| UNEXPECTED_GCSTATE(GCRunning); | 
| UNEXPECTED_GCSTATE(EagerSweepScheduled); | 
| UNEXPECTED_GCSTATE(LazySweepScheduled); | 
| @@ -749,19 +748,15 @@ void ThreadState::setGCState(GCState gcState) | 
| switch (gcState) { | 
| case NoGCScheduled: | 
| checkThread(); | 
| -        VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled); | 
| +        VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled); | 
| break; | 
| case IdleGCScheduled: | 
| case PreciseGCScheduled: | 
| case FullGCScheduled: | 
| checkThread(); | 
| -        VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleGCScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled || m_gcState == StoppingOtherThreads || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); | 
| +        VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleGCScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); | 
| completeSweep(); | 
| break; | 
| -    case StoppingOtherThreads: | 
| -        checkThread(); | 
| -        VERIFY_STATE_TRANSITION(m_gcState == NoGCScheduled || m_gcState == IdleGCScheduled || m_gcState == PreciseGCScheduled || m_gcState == FullGCScheduled || m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); | 
| -        break; | 
| case GCRunning: | 
| ASSERT(!isInGC()); | 
| VERIFY_STATE_TRANSITION(m_gcState != GCRunning); | 
| @@ -773,12 +768,12 @@ void ThreadState::setGCState(GCState gcState) | 
| break; | 
| case Sweeping: | 
| checkThread(); | 
| -        VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState == EagerSweepScheduled || m_gcState == LazySweepScheduled); | 
| +        VERIFY_STATE_TRANSITION(m_gcState == EagerSweepScheduled || m_gcState == LazySweepScheduled); | 
| break; | 
| case SweepingAndIdleGCScheduled: | 
| case SweepingAndPreciseGCScheduled: | 
| checkThread(); | 
| -        VERIFY_STATE_TRANSITION(m_gcState == StoppingOtherThreads || m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); | 
| +        VERIFY_STATE_TRANSITION(m_gcState == Sweeping || m_gcState == SweepingAndIdleGCScheduled || m_gcState == SweepingAndPreciseGCScheduled); | 
| break; | 
| default: | 
| ASSERT_NOT_REACHED(); | 
| @@ -810,6 +805,14 @@ void ThreadState::runScheduledGC(StackState stackState) | 
| if (stackState != NoHeapPointersOnStack) | 
| return; | 
|  | 
| +    // If a safe point is entered while initiating a GC, we clearly do | 
| +    // not want to do another as part that -- the safe point is only | 
| +    // entered after checking if a scheduled GC ought to run first. | 
| +    // Prevent that from happening by marking GCs as forbidden while | 
| +    // one is initiated and later running. | 
| +    if (isGCForbidden()) | 
| +        return; | 
| + | 
| switch (gcState()) { | 
| case FullGCScheduled: | 
| Heap::collectAllGarbage(); | 
| @@ -1107,7 +1110,6 @@ void ThreadState::enterSafePoint(StackState stackState, void* scopeMarker) | 
| scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); | 
| #endif | 
| ASSERT(stackState == NoHeapPointersOnStack || scopeMarker); | 
| -    ASSERT(!isGCForbidden()); | 
| runScheduledGC(stackState); | 
| ASSERT(!m_atSafePoint); | 
| m_atSafePoint = true; | 
|  |