| 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 9057cec1faf2a469839695d299c41d01ff2d33ec..a433dff585f7b32e4e3816e19b1fd34e005af7f0 100644
|
| --- a/third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| +++ b/third_party/WebKit/Source/platform/heap/ThreadState.cpp
|
| @@ -38,6 +38,7 @@
|
| #include "platform/heap/CallbackStack.h"
|
| #include "platform/heap/Handle.h"
|
| #include "platform/heap/Heap.h"
|
| +#include "platform/heap/HeapCompact.h"
|
| #include "platform/heap/PagePool.h"
|
| #include "platform/heap/SafePoint.h"
|
| #include "platform/heap/Visitor.h"
|
| @@ -79,7 +80,7 @@ uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)];
|
|
|
| const size_t defaultAllocatedObjectSizeThreshold = 100 * 1024;
|
|
|
| -const char* gcReasonString(BlinkGC::GCReason reason) {
|
| +const char* ThreadState::gcReasonString(BlinkGC::GCReason reason) {
|
| switch (reason) {
|
| case BlinkGC::IdleGC:
|
| return "IdleGC";
|
| @@ -504,6 +505,7 @@ void ThreadState::threadLocalWeakProcessing() {
|
| // Due to the complexity, we just forbid allocations.
|
| NoAllocationScope noAllocationScope(this);
|
|
|
| + GCForbiddenScope gcForbiddenScope(this);
|
| std::unique_ptr<Visitor> visitor =
|
| Visitor::create(this, BlinkGC::ThreadLocalWeakProcessing);
|
|
|
| @@ -1040,6 +1042,33 @@ void ThreadState::makeConsistentForGC() {
|
| m_arenas[i]->makeConsistentForGC();
|
| }
|
|
|
| +void ThreadState::compact() {
|
| + if (!heap().compaction()->isCompacting())
|
| + return;
|
| +
|
| + SweepForbiddenScope scope(this);
|
| + ScriptForbiddenIfMainThreadScope scriptForbiddenScope;
|
| +
|
| + // Compaction is done eagerly and before the mutator threads get
|
| + // to run again. Doing it lazily is problematic, as the mutator's
|
| + // references to live objects could suddenly be invalidated by
|
| + // compaction of a page/heap. We do know all the references to
|
| + // the relocating objects just after marking, but won't later.
|
| + // (e.g., stack references could have been created, new objects
|
| + // created which refer to old collection objects, and so on.)
|
| +
|
| + // Compact the hash table backing store arena first, it usually has
|
| + // higher fragmentation and is larger.
|
| + //
|
| + // TODO: implement bail out wrt any overall deadline, not compacting
|
| + // the remaining arenas if the time budget has been exceeded.
|
| + heap().compaction()->startThreadCompaction(this);
|
| + for (int i = BlinkGC::HashTableArenaIndex; i >= BlinkGC::Vector1ArenaIndex;
|
| + --i)
|
| + static_cast<NormalPageArena*>(m_arenas[i])->sweepAndCompact();
|
| + heap().compaction()->finishedThreadCompaction(this);
|
| +}
|
| +
|
| void ThreadState::makeConsistentForMutator() {
|
| ASSERT(isInGC());
|
| for (int i = 0; i < BlinkGC::NumberOfArenas; ++i)
|
| @@ -1123,9 +1152,12 @@ void ThreadState::preSweep() {
|
|
|
| eagerSweep();
|
|
|
| + compact();
|
| +
|
| #if defined(ADDRESS_SANITIZER)
|
| poisonAllHeaps();
|
| #endif
|
| +
|
| if (previousGCState == EagerSweepScheduled) {
|
| // Eager sweeping should happen only in testing.
|
| completeSweep();
|
| @@ -1674,7 +1706,7 @@ void ThreadState::collectGarbage(BlinkGC::StackState stackState,
|
| RELEASE_ASSERT(!isGCForbidden());
|
| completeSweep();
|
|
|
| - std::unique_ptr<Visitor> visitor = Visitor::create(this, gcType);
|
| + GCForbiddenScope gcForbiddenScope(this);
|
|
|
| SafePointScope safePointScope(stackState, this);
|
|
|
| @@ -1685,6 +1717,12 @@ void ThreadState::collectGarbage(BlinkGC::StackState stackState,
|
| if (!parkThreadsScope.parkThreads())
|
| return;
|
|
|
| + BlinkGC::GCType visitorType = gcType;
|
| + if (heap().compaction()->shouldCompact(this, gcType, reason))
|
| + visitorType = heap().compaction()->initialize(this);
|
| +
|
| + std::unique_ptr<Visitor> visitor = Visitor::create(this, visitorType);
|
| +
|
| ScriptForbiddenIfMainThreadScope scriptForbidden;
|
|
|
| TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping",
|
| @@ -1785,6 +1823,7 @@ void ThreadState::collectGarbageForTerminatingThread() {
|
| // ahead while it is running, hence the termination GC does not enter a
|
| // safepoint. VisitorScope will not enter also a safepoint scope for
|
| // ThreadTerminationGC.
|
| + GCForbiddenScope gcForbiddenScope(this);
|
| std::unique_ptr<Visitor> visitor =
|
| Visitor::create(this, BlinkGC::ThreadTerminationGC);
|
|
|
|
|