diff options
Diffstat (limited to 'third_party')
7 files changed, 105 insertions, 92 deletions
diff --git a/third_party/WebKit/Source/platform/heap/BUILD.gn b/third_party/WebKit/Source/platform/heap/BUILD.gn index 4e5a7c2..93e56e6 100644 --- a/third_party/WebKit/Source/platform/heap/BUILD.gn +++ b/third_party/WebKit/Source/platform/heap/BUILD.gn @@ -42,6 +42,7 @@ source_set("heap") { "ThreadState.h", "ThreadingTraits.h", "TraceTraits.h", + "Visitor.cpp", "Visitor.h", ] diff --git a/third_party/WebKit/Source/platform/heap/BlinkGC.h b/third_party/WebKit/Source/platform/heap/BlinkGC.h index 2ff121d..4f1447a 100644 --- a/third_party/WebKit/Source/platform/heap/BlinkGC.h +++ b/third_party/WebKit/Source/platform/heap/BlinkGC.h @@ -61,6 +61,11 @@ public: // The marking task does not mark objects outside the heap of the GCing // thread. ThreadTerminationGC, + // Just run thread-local weak processing. The weak processing may trace + // already marked objects but it must not trace any unmarked object. + // It's unfortunate that the thread-local weak processing requires + // a marking visitor. See TODO in HashTable::process. + ThreadLocalWeakProcessing, }; enum GCReason { diff --git a/third_party/WebKit/Source/platform/heap/Heap.cpp b/third_party/WebKit/Source/platform/heap/Heap.cpp index 06cfbb2..eed2697 100644 --- a/third_party/WebKit/Source/platform/heap/Heap.cpp +++ b/third_party/WebKit/Source/platform/heap/Heap.cpp @@ -56,102 +56,47 @@ namespace blink { HeapAllocHooks::AllocationHook* HeapAllocHooks::m_allocationHook = nullptr; HeapAllocHooks::FreeHook* HeapAllocHooks::m_freeHook = nullptr; -class GCForbiddenScope final { - DISALLOW_NEW(); -public: - explicit GCForbiddenScope(ThreadState* state) - : m_state(state) - { - // Prevent nested collectGarbage() invocations. - m_state->enterGCForbiddenScope(); - } - - ~GCForbiddenScope() - { - m_state->leaveGCForbiddenScope(); - } - -private: - ThreadState* m_state; -}; - -class GCScope final { +class ParkThreadsScope final { STACK_ALLOCATED(); public: - GCScope(ThreadState* state, BlinkGC::StackState stackState, BlinkGC::GCType gcType) - : m_state(state) - , m_gcForbiddenScope(state) - { - ASSERT(m_state->checkThread()); - - switch (gcType) { - case BlinkGC::GCWithSweep: - case BlinkGC::GCWithoutSweep: - m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>()); - break; - case BlinkGC::TakeSnapshot: - m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>()); - break; - case BlinkGC::ThreadTerminationGC: - m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking>()); - break; - default: - ASSERT_NOT_REACHED(); - } - } - - ~GCScope() + ParkThreadsScope() + : m_shouldResumeThreads(false) { } - bool parkAllThreads(BlinkGC::StackState stackState, BlinkGC::GCType gcType) + bool parkThreads(ThreadState* state) { - TRACE_EVENT0("blink_gc", "Heap::GCScope"); + TRACE_EVENT0("blink_gc", "Heap::ParkThreadsScope"); const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); - if (m_state->isMainThread()) + if (state->isMainThread()) TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); // TODO(haraken): In an unlikely coincidence that two threads decide // to collect garbage at the same time, avoid doing two GCs in // a row and return false. double startTime = WTF::currentTimeMS(); - bool allParked = gcType != BlinkGC::ThreadTerminationGC && ThreadState::stopThreads(); + + m_shouldResumeThreads = ThreadState::stopThreads(); + double timeForStoppingThreads = WTF::currentTimeMS() - startTime; DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, timeToStopThreadsHistogram, new CustomCountHistogram("BlinkGC.TimeForStoppingThreads", 1, 1000, 50)); timeToStopThreadsHistogram.count(timeForStoppingThreads); - if (m_state->isMainThread()) + if (state->isMainThread()) TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); - - return allParked; + return m_shouldResumeThreads; } - Visitor* visitor() const { return m_visitor.get(); } - -private: - ThreadState* m_state; - // See ThreadState::runScheduledGC() why we need to already be in a - // GCForbiddenScope before any safe point is entered. - GCForbiddenScope m_gcForbiddenScope; - OwnPtr<Visitor> m_visitor; -}; - -class ResumeThreadScope final { - STACK_ALLOCATED(); -public: - explicit ResumeThreadScope(BlinkGC::GCType gcType) - : m_resumeThreads(gcType != BlinkGC::ThreadTerminationGC) - { - } - ~ResumeThreadScope() + ~ParkThreadsScope() { // Only cleanup if we parked all threads in which case the GC happened // and we need to resume the other threads. - if (m_resumeThreads) + if (m_shouldResumeThreads) ThreadState::resumeThreads(); } + private: - bool m_resumeThreads; + bool m_shouldResumeThreads; }; void Heap::flushHeapDoesNotContainCache() @@ -396,22 +341,24 @@ const char* Heap::gcReasonString(BlinkGC::GCReason reason) void Heap::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType, BlinkGC::GCReason reason) { + ASSERT(gcType != BlinkGC::ThreadTerminationGC); + ThreadState* state = ThreadState::current(); // Nested collectGarbage() invocations aren't supported. RELEASE_ASSERT(!state->isGCForbidden()); state->completeSweep(); - GCScope gcScope(state, stackState, gcType); - // See collectGarbageForTerminatingThread() comment on why a - // safepoint scope isn't entered for it. - SafePointScope safePointScope(stackState, gcType != BlinkGC::ThreadTerminationGC ? state : nullptr); + VisitorScope visitorScope(state, gcType); + + SafePointScope safePointScope(stackState, state); + + // Resume all parked threads upon leaving this scope. + ParkThreadsScope parkThreadsScope; // Try to park the other threads. If we're unable to, bail out of the GC. - if (!gcScope.parkAllThreads(stackState, gcType)) + if (!parkThreadsScope.parkThreads(state)) return; - // Resume all parked threads upon leaving this scope. - ResumeThreadScope resumeThreads(gcType); ScriptForbiddenIfMainThreadScope scriptForbidden; TRACE_EVENT2("blink_gc,devtools.timeline", "Heap::collectGarbage", @@ -424,7 +371,7 @@ void Heap::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); // Disallow allocation during garbage collection (but not during the - // finalization that happens when the gcScope is torn down). + // finalization that happens when the visitorScope is torn down). ThreadState::NoAllocationScope noAllocationScope(state); preGC(); @@ -436,17 +383,17 @@ void Heap::collectGarbage(BlinkGC::StackState stackState, BlinkGC::GCType gcType Heap::resetHeapCounters(); // 1. Trace persistent roots. - ThreadState::visitPersistentRoots(gcScope.visitor()); + ThreadState::visitPersistentRoots(visitorScope.visitor()); // 2. Trace objects reachable from the stack. We do this independent of the // given stackState since other threads might have a different stack state. - ThreadState::visitStackRoots(gcScope.visitor()); + ThreadState::visitStackRoots(visitorScope.visitor()); // 3. Transitive closure to trace objects including ephemerons. - processMarkingStack(gcScope.visitor()); + processMarkingStack(visitorScope.visitor()); - postMarkingProcessing(gcScope.visitor()); - globalWeakProcessing(gcScope.visitor()); + postMarkingProcessing(visitorScope.visitor()); + globalWeakProcessing(visitorScope.visitor()); // Now we can delete all orphaned pages because there are no dangling // pointers to the orphaned pages. (If we have such dangling pointers, @@ -487,9 +434,9 @@ void Heap::collectGarbageForTerminatingThread(ThreadState* state) { // A thread-specific termination GC must not allow other global GCs to go // ahead while it is running, hence the termination GC does not enter a - // safepoint. GCScope will not enter also a safepoint scope for + // safepoint. VisitorScope will not enter also a safepoint scope for // ThreadTerminationGC. - GCScope gcScope(state, BlinkGC::NoHeapPointersOnStack, BlinkGC::ThreadTerminationGC); + VisitorScope visitorScope(state, BlinkGC::ThreadTerminationGC); ThreadState::NoAllocationScope noAllocationScope(state); @@ -505,14 +452,14 @@ void Heap::collectGarbageForTerminatingThread(ThreadState* state) // global GC finds a "pointer" on the stack or due to a programming // error where an object has a dangling cross-thread pointer to an // object on this heap. - state->visitPersistents(gcScope.visitor()); + state->visitPersistents(visitorScope.visitor()); // 2. Trace objects reachable from the thread's persistent roots // including ephemerons. - processMarkingStack(gcScope.visitor()); + processMarkingStack(visitorScope.visitor()); - postMarkingProcessing(gcScope.visitor()); - globalWeakProcessing(gcScope.visitor()); + postMarkingProcessing(visitorScope.visitor()); + globalWeakProcessing(visitorScope.visitor()); state->postGC(BlinkGC::GCWithSweep); } diff --git a/third_party/WebKit/Source/platform/heap/ThreadState.cpp b/third_party/WebKit/Source/platform/heap/ThreadState.cpp index 0fa6980..3d9554d 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp @@ -37,8 +37,8 @@ #include "platform/heap/CallbackStack.h" #include "platform/heap/Handle.h" #include "platform/heap/Heap.h" -#include "platform/heap/MarkingVisitor.h" #include "platform/heap/SafePoint.h" +#include "platform/heap/Visitor.h" #include "public/platform/Platform.h" #include "public/platform/WebMemoryAllocatorDump.h" #include "public/platform/WebProcessMemoryDump.h" @@ -480,10 +480,10 @@ void ThreadState::threadLocalWeakProcessing() // Due to the complexity, we just forbid allocations. NoAllocationScope noAllocationScope(this); - MarkingVisitor<Visitor::WeakProcessing> weakProcessingVisitor; + VisitorScope visitorScope(this, BlinkGC::ThreadLocalWeakProcessing); // Perform thread-specific weak processing. - while (popAndInvokeThreadLocalWeakCallback(&weakProcessingVisitor)) { } + while (popAndInvokeThreadLocalWeakCallback(visitorScope.visitor())) { } if (isMainThread()) { double timeForThreadLocalWeakProcessing = WTF::currentTimeMS() - startTime; diff --git a/third_party/WebKit/Source/platform/heap/Visitor.cpp b/third_party/WebKit/Source/platform/heap/Visitor.cpp new file mode 100644 index 0000000..575285d --- /dev/null +++ b/third_party/WebKit/Source/platform/heap/Visitor.cpp @@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/heap/Visitor.h" + +#include "platform/heap/BlinkGC.h" +#include "platform/heap/MarkingVisitor.h" +#include "platform/heap/ThreadState.h" + +namespace blink { + +VisitorScope::VisitorScope(ThreadState* state, BlinkGC::GCType gcType) + : m_state(state) +{ + // See ThreadState::runScheduledGC() why we need to already be in a + // GCForbiddenScope before any safe point is entered. + m_state->enterGCForbiddenScope(); + + ASSERT(m_state->checkThread()); + + switch (gcType) { + case BlinkGC::GCWithSweep: + case BlinkGC::GCWithoutSweep: + m_visitor = adoptPtr(new MarkingVisitor<Visitor::GlobalMarking>()); + break; + case BlinkGC::TakeSnapshot: + m_visitor = adoptPtr(new MarkingVisitor<Visitor::SnapshotMarking>()); + break; + case BlinkGC::ThreadTerminationGC: + m_visitor = adoptPtr(new MarkingVisitor<Visitor::ThreadLocalMarking>()); + break; + case BlinkGC::ThreadLocalWeakProcessing: + m_visitor = adoptPtr(new MarkingVisitor<Visitor::WeakProcessing>()); + break; + default: + ASSERT_NOT_REACHED(); + } +} + +VisitorScope::~VisitorScope() +{ + m_state->leaveGCForbiddenScope(); +} + +} // namespace blink diff --git a/third_party/WebKit/Source/platform/heap/Visitor.h b/third_party/WebKit/Source/platform/heap/Visitor.h index 0465bad..7700ca0 100644 --- a/third_party/WebKit/Source/platform/heap/Visitor.h +++ b/third_party/WebKit/Source/platform/heap/Visitor.h @@ -52,6 +52,7 @@ class HeapObjectHeader; class InlinedGlobalMarkingVisitor; template<typename T> class TraceTrait; template<typename T> class TraceEagerlyTrait; +class ThreadState; class Visitor; // The TraceMethodDelegate is used to convert a trace method for type T to a TraceCallback. @@ -387,6 +388,18 @@ private: bool m_isGlobalMarkingVisitor; }; +class VisitorScope final { + STACK_ALLOCATED(); +public: + VisitorScope(ThreadState*, BlinkGC::GCType); + ~VisitorScope(); + Visitor* visitor() const { return m_visitor.get(); } + +private: + ThreadState* m_state; + OwnPtr<Visitor> m_visitor; +}; + #if ENABLE(DETAILED_MEMORY_INFRA) template<typename T> struct TypenameStringTrait { diff --git a/third_party/WebKit/Source/platform/heap/blink_heap.gypi b/third_party/WebKit/Source/platform/heap/blink_heap.gypi index c609d1d..40320ad 100644 --- a/third_party/WebKit/Source/platform/heap/blink_heap.gypi +++ b/third_party/WebKit/Source/platform/heap/blink_heap.gypi @@ -66,6 +66,7 @@ 'ThreadState.h', 'ThreadingTraits.h', 'TraceTraits.h', + 'Visitor.cpp', 'Visitor.h', ], 'platform_heap_test_files': [ |
