| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index b7756d3418cab62cb43047a1743b329f49086dc6..78bb414ad1345c5730bf4c97b0b79f7e319d1fa1 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -76,6 +76,9 @@ uintptr_t ThreadState::s_mainThreadStackStart = 0;
|
| uintptr_t ThreadState::s_mainThreadUnderestimatedStackSize = 0;
|
| uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)];
|
| SafePointBarrier* ThreadState::s_safePointBarrier = nullptr;
|
| +#if ENABLE(ASSERT)
|
| +int ThreadState::s_selfKeepAliveAllocationsOnMainThread = 0;
|
| +#endif
|
|
|
| RecursiveMutex& ThreadState::threadAttachMutex()
|
| {
|
| @@ -166,6 +169,9 @@ void ThreadState::attachMainThread()
|
| MutexLocker locker(threadAttachMutex());
|
| ThreadState* state = new(s_mainThreadStateStorage) ThreadState();
|
| attachedThreads().add(state);
|
| +#if ENABLE(ASSERT)
|
| + s_selfKeepAliveAllocationsOnMainThread = 0;
|
| +#endif
|
| }
|
|
|
| void ThreadState::detachMainThread()
|
| @@ -189,6 +195,8 @@ void ThreadState::detachMainThread()
|
| attachedThreads().remove(state);
|
| state->~ThreadState();
|
| }
|
| + // Catch out any self-referential leaks created by the main thread.
|
| + ASSERT(s_selfKeepAliveAllocationsOnMainThread == 0);
|
| shutdownHeapIfNecessary();
|
| }
|
|
|
| @@ -257,7 +265,10 @@ void ThreadState::cleanup()
|
| }
|
| // We should not have any persistents left when getting to this point,
|
| // if we have it is probably a bug so adding a debug ASSERT to catch this.
|
| - ASSERT(!currentCount);
|
| + // (debug tip: use persistentRegion()->dumpLivePersistents() to get a list of
|
| + // the remaining live Persistent<>s. In gdb, performing "info symbol" on the
|
| + // trace callback addresses printed should tell you what Persistent<T>s are leaking.)
|
| + ASSERT(!currentCount && "Persistent<>s leak on thread heap shutdown");
|
| // All of pre-finalizers should be consumed.
|
| ASSERT(m_orderedPreFinalizers.isEmpty());
|
| RELEASE_ASSERT(gcState() == NoGCScheduled);
|
| @@ -1542,4 +1553,23 @@ void ThreadState::reportMarkSweepStats(const char* statsName, const ClassAgeCoun
|
| }
|
| #endif
|
|
|
| +#if ENABLE(ASSERT)
|
| +void ThreadState::incrementSelfKeepAliveAllocations()
|
| +{
|
| + if (!ThreadState::current()->isMainThread())
|
| + return;
|
| +
|
| + s_selfKeepAliveAllocationsOnMainThread++;
|
| +}
|
| +
|
| +void ThreadState::decrementSelfKeepAliveAllocations()
|
| +{
|
| + if (!ThreadState::current()->isMainThread())
|
| + return;
|
| +
|
| + ASSERT(s_selfKeepAliveAllocationsOnMainThread > 0);
|
| + s_selfKeepAliveAllocationsOnMainThread--;
|
| +}
|
| +#endif
|
| +
|
| } // namespace blink
|
|
|