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..097330f8d57ec9f4cabecfb0e36983e087b3180c 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" |
@@ -1034,12 +1035,54 @@ void ThreadState::flushHeapDoesNotContainCacheIfNeeded() { |
} |
void ThreadState::makeConsistentForGC() { |
+ if (isMainThread()) { |
+ // For the main thread, report heap + freelist residency to the |
+ // heap compactor. It uses the data to determine if compactions |
+ // is now worthwhile for one or more of the sub heaps/arenas it can |
+ // compact. |
+ size_t heapSize = 0; |
+ size_t freeSize = 0; |
+ using Residency = std::pair<size_t, size_t>; |
+ Vector<Residency> residencies; |
+ NormalPageArena* arena; |
+ for (int i = BlinkGC::Vector1ArenaIndex; i <= BlinkGC::HashTableArenaIndex; |
+ ++i) { |
+ arena = static_cast<NormalPageArena*>(m_arenas[i]); |
+ heapSize += arena->arenaSize(); |
+ freeSize += arena->freeListSize(); |
+ residencies.append(Residency(arena->arenaSize(), arena->freeListSize())); |
+ } |
+ heap().compaction()->setHeapResidency(heapSize, freeSize, residencies); |
+ } |
ASSERT(isInGC()); |
TRACE_EVENT0("blink_gc", "ThreadState::makeConsistentForGC"); |
for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) |
m_arenas[i]->makeConsistentForGC(); |
} |
+void ThreadState::compact() { |
+ if (!heap().compaction()->isCompacting()) |
+ return; |
+ |
+ // 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.) |
+ // |
+ heap().compaction()->startCompacting(this); |
+ // TODO: implement bail out wrt any overall deadline, not |
+ // compacting heaps if the time budget has been exceeded. |
+ static_cast<NormalPageArena*>(m_arenas[BlinkGC::HashTableArenaIndex]) |
+ ->sweepCompact(); |
+ for (int i = BlinkGC::Vector1ArenaIndex; i <= BlinkGC::InlineVectorArenaIndex; |
+ ++i) |
+ static_cast<NormalPageArena*>(m_arenas[i])->sweepCompact(); |
+ heap().compaction()->finishedCompacting(this); |
+} |
+ |
void ThreadState::makeConsistentForMutator() { |
ASSERT(isInGC()); |
for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) |
@@ -1123,9 +1166,12 @@ void ThreadState::preSweep() { |
eagerSweep(); |
+ compact(); |
haraken
2016/11/30 06:29:53
- Is there any reason you put compact() after pre-
sof
2016/11/30 06:52:44
I had stability problems doing it a step or two ea
haraken
2016/11/30 07:09:49
BTW, do you know why we need to run the heap compa
sof
2016/11/30 07:26:38
We cannot run compaction before the liveness of th
haraken
2016/11/30 08:51:19
The liveness should have been determined by the en
sof
2016/11/30 09:22:14
Yes, could do that then also. I don't know if you
sof
2016/11/30 10:47:41
Ah, now I remember the issue: if you finalize cont
|
+ |
#if defined(ADDRESS_SANITIZER) |
poisonAllHeaps(); |
#endif |
+ |
if (previousGCState == EagerSweepScheduled) { |
// Eager sweeping should happen only in testing. |
completeSweep(); |
@@ -1685,6 +1731,9 @@ void ThreadState::collectGarbage(BlinkGC::StackState stackState, |
if (!parkThreadsScope.parkThreads()) |
return; |
+ heap().compaction()->checkIfCompacting(&heap(), visitor.get(), gcType, |
+ reason); |
+ |
ScriptForbiddenIfMainThreadScope scriptForbidden; |
TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", "lazySweeping", |