Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1493)

Unified Diff: Source/platform/heap/ThreadState.cpp

Issue 1190863003: Oilpan: Allocation should be allowed in pre-finalizers (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/ThreadState.cpp
diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
index ce2fc79e21c42f39a9d22b65e0e4a545ba34586f..2c89ff49081d07f3b55bd8edae009222d8e59e3b 100644
--- a/Source/platform/heap/ThreadState.cpp
+++ b/Source/platform/heap/ThreadState.cpp
@@ -517,6 +517,31 @@ bool ThreadState::popAndInvokeThreadLocalWeakCallback(Visitor* visitor)
return false;
}
+void ThreadState::threadLocalWeakProcessing()
+{
+ ASSERT(!sweepForbidden());
+ TRACE_EVENT0("blink_gc", "ThreadState::threadLocalWeakProcessing");
+ SweepForbiddenScope forbiddenScope(this);
+ if (isMainThread())
+ ScriptForbiddenScope::enter();
+
+ // Disallow allocation during weak processing.
+ // It would be technically safe to allow allocations, but it is unsafe
+ // to mutate an object graph in a way in which a dead object gets
+ // resurrected or mutate a HashTable (because HashTable's weak processing
+ // assumes that the HashTable hasn't been mutated since the latest marking).
+ // Due to the complexity, we just forbid allocations.
+ NoAllocationScope noAllocationScope(this);
+
+ MarkingVisitor<Visitor::WeakProcessing> weakProcessingVisitor;
+
+ // Perform thread-specific weak processing.
+ while (popAndInvokeThreadLocalWeakCallback(&weakProcessingVisitor)) { }
+
+ if (isMainThread())
+ ScriptForbiddenScope::exit();
+}
+
PersistentAnchor& ThreadState::globalRoots()
{
AtomicallyInitializedStaticReference(PersistentAnchor, anchor, new PersistentAnchor);
@@ -679,7 +704,7 @@ void ThreadState::performIdleLazySweep(double deadlineSeconds)
return;
bool sweepCompleted = true;
- ThreadState::SweepForbiddenScope scope(this);
+ SweepForbiddenScope scope(this);
{
if (isMainThread())
ScriptForbiddenScope::enter();
@@ -950,39 +975,27 @@ void ThreadState::preSweep()
if (gcState() != EagerSweepScheduled && gcState() != LazySweepScheduled)
return;
- {
- if (isMainThread())
- ScriptForbiddenScope::enter();
-
- SweepForbiddenScope forbiddenScope(this);
- {
- MarkingVisitor<Visitor::WeakProcessing> weakProcessingVisitor;
+ threadLocalWeakProcessing();
- // Disallow allocation during weak processing.
- NoAllocationScope noAllocationScope(this);
- {
- // Perform thread-specific weak processing.
- TRACE_EVENT0("blink_gc", "ThreadState::threadLocalWeakProcessing");
- while (popAndInvokeThreadLocalWeakCallback(&weakProcessingVisitor)) { }
- }
- {
- TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers");
- invokePreFinalizers();
- }
- }
+#if ENABLE(LAZY_SWEEPING)
+ GCState previousGCState = gcState();
+#endif
+ // We have to set the GCState to Sweeping before calling pre-finalizers
+ // to disallow a GC during the pre-finalizers.
+ setGCState(Sweeping);
- if (isMainThread())
- ScriptForbiddenScope::exit();
- }
+ // Allocation is allowed during the pre-finalizers and destructors.
+ // However, they must not mutate an object graph in a way in which
+ // a dead object gets resurrected.
+ invokePreFinalizers();
#if defined(ADDRESS_SANITIZER)
poisonEagerHeap(SetPoison);
#endif
#if ENABLE(LAZY_SWEEPING)
- if (gcState() == EagerSweepScheduled) {
+ if (previousGCState == EagerSweepScheduled) {
// Eager sweeping should happen only in testing.
- setGCState(Sweeping);
eagerSweep();
#if defined(ADDRESS_SANITIZER)
poisonAllHeaps();
@@ -990,7 +1003,6 @@ void ThreadState::preSweep()
completeSweep();
} else {
// The default behavior is lazy sweeping.
- setGCState(Sweeping);
eagerSweep();
#if defined(ADDRESS_SANITIZER)
poisonAllHeaps();
@@ -998,7 +1010,6 @@ void ThreadState::preSweep()
scheduleIdleLazySweep();
}
#else
- setGCState(Sweeping);
completeSweep();
#endif
@@ -1040,7 +1051,7 @@ void ThreadState::eagerSweep()
if (sweepForbidden())
return;
- ThreadState::SweepForbiddenScope scope(this);
+ SweepForbiddenScope scope(this);
{
if (isMainThread())
ScriptForbiddenScope::enter();
@@ -1064,7 +1075,7 @@ void ThreadState::completeSweep()
if (sweepForbidden())
return;
- ThreadState::SweepForbiddenScope scope(this);
+ SweepForbiddenScope scope(this);
{
if (isMainThread())
ScriptForbiddenScope::enter();
@@ -1297,6 +1308,13 @@ void ThreadState::unregisterPreFinalizerInternal(void* target)
void ThreadState::invokePreFinalizers()
{
checkThread();
+ ASSERT(!sweepForbidden());
+ TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers");
+
+ if (isMainThread())
+ ScriptForbiddenScope::enter();
+
+ SweepForbiddenScope forbiddenScope(this);
Vector<void*> deadObjects;
for (auto& entry : m_preFinalizers) {
if (entry.value(entry.key))
@@ -1304,6 +1322,9 @@ void ThreadState::invokePreFinalizers()
}
// FIXME: removeAll is inefficient. It can shrink repeatedly.
m_preFinalizers.removeAll(deadObjects);
+
+ if (isMainThread())
+ ScriptForbiddenScope::exit();
}
void ThreadState::clearHeapAges()
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698