| Index: third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| index 155e31138bbbffc8f2b7d7164fd1bde8e007987f..a6c8b6b25604ce6ad77a89fa1e408fd3eef44ce6 100644
|
| --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| @@ -226,7 +226,7 @@ void ThreadState::runTerminationGC()
|
| // pointers into the heap owned by this thread.
|
| m_isTerminating = true;
|
|
|
| - ThreadState::callThreadShutdownHooks();
|
| + releaseStaticPersistentNodes();
|
|
|
| // Set the terminate flag on all heap pages of this thread. This is used to
|
| // ensure we don't trace pages on other threads that are not part of the
|
| @@ -261,15 +261,17 @@ void ThreadState::cleanupMainThread()
|
| {
|
| ASSERT(isMainThread());
|
|
|
| + releaseStaticPersistentNodes();
|
| +
|
| #if defined(LEAK_SANITIZER)
|
| - // If LSan is about to perform leak detection, release all the registered
|
| - // static Persistent<> root references to global caches that Blink keeps,
|
| - // followed by GCs to clear out all they referred to.
|
| + // If LSan is about to perform leak detection, after having released all
|
| + // the registered static Persistent<> root references to global caches
|
| + // that Blink keeps, follow up with a round of GCs to clear out all
|
| + // what they referred to.
|
| //
|
| // This is not needed for caches over non-Oilpan objects, as they're
|
| // not scanned by LSan due to being held in non-global storage
|
| // ("static" references inside functions/methods.)
|
| - releaseStaticPersistentNodes();
|
| ThreadHeap::collectAllGarbage();
|
| #endif
|
|
|
| @@ -296,15 +298,6 @@ void ThreadState::detachMainThread()
|
| state->~ThreadState();
|
| }
|
|
|
| -void ThreadState::callThreadShutdownHooks()
|
| -{
|
| - // Invoke the cleanup hooks. This gives an opportunity to release any
|
| - // persistent handles that may exist, e.g. in thread-specific static
|
| - // locals.
|
| - for (const OwnPtr<SameThreadClosure>& hook : m_threadShutdownHooks)
|
| - (*hook)();
|
| -}
|
| -
|
| void ThreadState::detachCurrentThread()
|
| {
|
| ThreadState* state = current();
|
| @@ -1322,31 +1315,40 @@ void ThreadState::addInterruptor(PassOwnPtr<BlinkGCInterruptor> interruptor)
|
| }
|
| }
|
|
|
| -void ThreadState::registerThreadShutdownHook(PassOwnPtr<SameThreadClosure> hook)
|
| +void ThreadState::registerStaticPersistentNode(PersistentNode* node, PersistentClearCallback callback)
|
| {
|
| - ASSERT(checkThread());
|
| - ASSERT(!isTerminating());
|
| - m_threadShutdownHooks.append(hook);
|
| -}
|
| -
|
| #if defined(LEAK_SANITIZER)
|
| -void ThreadState::registerStaticPersistentNode(PersistentNode* node)
|
| -{
|
| if (m_disabledStaticPersistentsRegistration)
|
| return;
|
| +#endif
|
|
|
| ASSERT(!m_staticPersistents.contains(node));
|
| - m_staticPersistents.add(node);
|
| + m_staticPersistents.add(node, callback);
|
| }
|
|
|
| void ThreadState::releaseStaticPersistentNodes()
|
| {
|
| - for (PersistentNode* node : m_staticPersistents)
|
| - getPersistentRegion()->freePersistentNode(node);
|
| + HashMap<PersistentNode*, ThreadState::PersistentClearCallback> staticPersistents;
|
| + staticPersistents.swap(m_staticPersistents);
|
| +
|
| + PersistentRegion* persistentRegion = getPersistentRegion();
|
| + for (const auto& it : staticPersistents)
|
| + persistentRegion->releasePersistentNode(it.key, it.value);
|
| +}
|
|
|
| - m_staticPersistents.clear();
|
| +void ThreadState::freePersistentNode(PersistentNode* persistentNode)
|
| +{
|
| + PersistentRegion* persistentRegion = getPersistentRegion();
|
| + persistentRegion->freePersistentNode(persistentNode);
|
| + // Do not allow static persistents to be freed before
|
| + // they're all released in releaseStaticPersistentNodes().
|
| + //
|
| + // There's no fundamental reason why this couldn't be supported,
|
| + // but no known use for it.
|
| + ASSERT(!m_staticPersistents.contains(persistentNode));
|
| }
|
|
|
| +#if defined(LEAK_SANITIZER)
|
| void ThreadState::enterStaticReferenceRegistrationDisabledScope()
|
| {
|
| m_disabledStaticPersistentsRegistration++;
|
|
|