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 d8882ad5babb73e58f7d680967f1331d4e2c1940..ef6b720da68e14a078e6af12898be3b28bcccf36 100644 |
--- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp |
+++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp |
@@ -220,7 +220,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 |
@@ -255,15 +255,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 |
@@ -290,15 +292,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(); |
@@ -1316,31 +1309,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. |
haraken
2016/04/25 08:39:23
Yeah, I prefer adding this restriction too. regist
sof
2016/04/25 08:53:05
Agreed; a thread needing to free a persistent whil
|
+ ASSERT(!m_staticPersistents.contains(persistentNode)); |
} |
+#if defined(LEAK_SANITIZER) |
void ThreadState::enterStaticReferenceRegistrationDisabledScope() |
{ |
m_disabledStaticPersistentsRegistration++; |