| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index 7ed2986a17c949a0a5a09d2c44f8d16593653a70..3cf140a7ffc3b7e3c73e411cfaf5d9cb4d7b5444 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -663,8 +663,8 @@ void ThreadState::snapshot()
|
| json->endArray();
|
| #undef SNAPSHOT_HEAP
|
|
|
| - json->setInteger("allocatedSpace", m_stats.totalAllocatedSpace());
|
| - json->setInteger("objectSpace", m_stats.totalObjectSpace());
|
| + json->setInteger("allocatedSpace", Heap::allocatedSpace());
|
| + json->setInteger("objectSpace", Heap::allocatedObjectSize());
|
| json->setInteger("pageCount", info.pageCount);
|
| json->setInteger("freeSize", info.freeSize);
|
|
|
| @@ -731,47 +731,35 @@ Mutex& ThreadState::globalRootsMutex()
|
| return mutex;
|
| }
|
|
|
| -// Trigger garbage collection on a 50% increase in size, but not for
|
| -// less than 512kbytes.
|
| -bool ThreadState::increasedEnoughToGC(size_t newSize, size_t oldSize)
|
| -{
|
| - if (newSize < 1 << 19)
|
| - return false;
|
| - size_t limit = oldSize + (oldSize >> 1);
|
| - return newSize > limit;
|
| -}
|
| -
|
| -// FIXME: The heuristics are local for a thread at this
|
| -// point. Consider using heuristics that take memory for all threads
|
| -// into account.
|
| bool ThreadState::shouldGC()
|
| {
|
| - // Do not GC during sweeping. We allow allocation during
|
| - // finalization, but those allocations are not allowed
|
| - // to lead to nested garbage collections.
|
| - return !m_sweepInProgress && increasedEnoughToGC(m_stats.totalObjectSpace(), m_statsAfterLastGC.totalObjectSpace());
|
| -}
|
| + // Do not GC during sweeping. We allow allocation during finalization,
|
| + // but those allocations are not allowed to lead to nested GCs.
|
| + if (m_sweepInProgress)
|
| + return false;
|
|
|
| -// Trigger conservative garbage collection on a 100% increase in size,
|
| -// but not for less than 4Mbytes. If the system currently has a low
|
| -// collection rate, then require a 300% increase in size.
|
| -bool ThreadState::increasedEnoughToForceConservativeGC(size_t newSize, size_t oldSize)
|
| -{
|
| - if (newSize < 1 << 22)
|
| + // Trigger garbage collection on a 50% increase in size,
|
| + // but not for less than 512 KB.
|
| + if (Heap::allocatedObjectSize() < 1 << 19)
|
| return false;
|
| - size_t limit = (m_lowCollectionRate ? 4 : 2) * oldSize;
|
| - return newSize > limit;
|
| + size_t limit = Heap::liveObjectSize() + Heap::liveObjectSize() / 2;
|
| + return Heap::allocatedObjectSize() > limit;
|
| }
|
|
|
| -// FIXME: The heuristics are local for a thread at this
|
| -// point. Consider using heuristics that take memory for all threads
|
| -// into account.
|
| bool ThreadState::shouldForceConservativeGC()
|
| {
|
| - // Do not GC during sweeping. We allow allocation during
|
| - // finalization, but those allocations are not allowed
|
| - // to lead to nested garbage collections.
|
| - return !m_sweepInProgress && increasedEnoughToForceConservativeGC(m_stats.totalObjectSpace(), m_statsAfterLastGC.totalObjectSpace());
|
| + // Do not GC during sweeping. We allow allocation during finalization,
|
| + // but those allocations are not allowed to lead to nested GCs.
|
| + if (m_sweepInProgress)
|
| + return false;
|
| +
|
| + // Trigger conservative garbage collection on a 100% increase in size,
|
| + // but not for less than 4Mbytes. If the system currently has a low
|
| + // collection rate, then require a 300% increase in size.
|
| + if (Heap::allocatedObjectSize() < 1 << 22)
|
| + return false;
|
| + size_t limit = (m_lowCollectionRate ? 4 : 2) * Heap::liveObjectSize();
|
| + return Heap::allocatedObjectSize() > limit;
|
| }
|
|
|
| bool ThreadState::sweepRequested()
|
| @@ -904,16 +892,13 @@ BaseHeapPage* ThreadState::heapPageFromAddress(Address address)
|
| return 0;
|
| }
|
|
|
| -void ThreadState::getStats(HeapStats& stats)
|
| -{
|
| - stats = m_stats;
|
| -}
|
| -
|
| -void ThreadState::getStatsForTesting(HeapStats& stats)
|
| +size_t ThreadState::objectPayloadSizeForTesting()
|
| {
|
| ASSERT(isConsistentForSweeping());
|
| + size_t objectPayloadSize = 0;
|
| for (int i = 0; i < NumberOfHeaps; i++)
|
| - m_heaps[i]->getStatsForTesting(stats);
|
| + objectPayloadSize += m_heaps[i]->objectPayloadSizeForTesting();
|
| + return objectPayloadSize;
|
| }
|
|
|
| bool ThreadState::stopThreads()
|
| @@ -1042,10 +1027,9 @@ void ThreadState::waitUntilSweepersDone()
|
|
|
| class SweepNonFinalizedHeapTask final : public WebThread::Task {
|
| public:
|
| - SweepNonFinalizedHeapTask(ThreadState* state, BaseHeap* heap, HeapStats* stats)
|
| + SweepNonFinalizedHeapTask(ThreadState* state, BaseHeap* heap)
|
| : m_threadState(state)
|
| , m_heap(heap)
|
| - , m_stats(stats)
|
| {
|
| m_threadState->registerSweepingTask();
|
| }
|
| @@ -1058,13 +1042,12 @@ public:
|
| virtual void run()
|
| {
|
| TRACE_EVENT0("blink_gc", "ThreadState::sweepNonFinalizedHeaps");
|
| - m_heap->sweep(m_stats);
|
| + m_heap->sweep();
|
| }
|
|
|
| private:
|
| ThreadState* m_threadState;
|
| BaseHeap* m_heap;
|
| - HeapStats* m_stats;
|
| };
|
|
|
| void ThreadState::performPendingSweep()
|
| @@ -1078,7 +1061,7 @@ void ThreadState::performPendingSweep()
|
| // going to be freed.
|
| bool gcTracingEnabled;
|
| TRACE_EVENT_CATEGORY_GROUP_ENABLED("blink_gc", &gcTracingEnabled);
|
| - if (gcTracingEnabled && m_stats.totalObjectSpace() > 0)
|
| + if (gcTracingEnabled)
|
| snapshot();
|
| #endif
|
|
|
| @@ -1091,7 +1074,7 @@ void ThreadState::performPendingSweep()
|
| TRACE_EVENT_SET_SAMPLING_STATE("blink", "BlinkGCSweeping");
|
| }
|
|
|
| - size_t objectSpaceBeforeSweep = m_stats.totalObjectSpace();
|
| + size_t allocatedObjectSizeBeforeSweeping = Heap::allocatedObjectSize();
|
| {
|
| NoSweepScope scope(this);
|
|
|
| @@ -1114,10 +1097,12 @@ void ThreadState::performPendingSweep()
|
|
|
| clearGCRequested();
|
| clearSweepRequested();
|
| - // If we collected less than 50% of objects, record that the
|
| - // collection rate is low which we use to determine when to
|
| - // perform the next GC.
|
| - setLowCollectionRate(m_stats.totalObjectSpace() > (objectSpaceBeforeSweep / 2));
|
| +
|
| + // If we collected less than 50% of objects, record that the collection rate
|
| + // is low which we use to determine when to perform the next GC.
|
| + // FIXME: m_lowCollectionRate should be available in non-main threads.
|
| + if (isMainThread())
|
| + m_lowCollectionRate = Heap::liveObjectSize() > (allocatedObjectSizeBeforeSweeping / 2);
|
|
|
| if (Platform::current()) {
|
| Platform::current()->histogramCustomCounts("BlinkGC.PerformPendingSweep", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50);
|
| @@ -1131,9 +1116,6 @@ void ThreadState::performPendingSweep()
|
|
|
| void ThreadState::performPendingSweepInParallel()
|
| {
|
| - // Sweeping will recalculate the stats
|
| - m_stats.clear();
|
| -
|
| // Sweep the non-finalized heap pages on multiple threads.
|
| // Attempt to load-balance by having the sweeper thread sweep as
|
| // close to half of the pages as possible.
|
| @@ -1151,7 +1133,6 @@ void ThreadState::performPendingSweepInParallel()
|
| // finalizers need to run and therefore the pages can be
|
| // swept on other threads.
|
| static const int minNumberOfPagesForParallelSweep = 10;
|
| - HeapStats heapStatsVector[NumberOfNonFinalizedHeaps];
|
| OwnPtr<BaseHeap> splitOffHeaps[NumberOfNonFinalizedHeaps];
|
| for (int i = 0; i < NumberOfNonFinalizedHeaps && pagesToSweepInParallel > 0; i++) {
|
| BaseHeap* heap = m_heaps[FirstNonFinalizedHeap + i];
|
| @@ -1165,8 +1146,7 @@ void ThreadState::performPendingSweepInParallel()
|
| int pagesToSplitOff = std::min(pageCount, pagesToSweepInParallel);
|
| pagesToSweepInParallel -= pagesToSplitOff;
|
| splitOffHeaps[i] = heap->split(pagesToSplitOff);
|
| - HeapStats* stats = &heapStatsVector[i];
|
| - m_sweeperThread->postTask(new SweepNonFinalizedHeapTask(this, splitOffHeaps[i].get(), stats));
|
| + m_sweeperThread->postTask(new SweepNonFinalizedHeapTask(this, splitOffHeaps[i].get()));
|
| }
|
| }
|
|
|
| @@ -1175,9 +1155,7 @@ void ThreadState::performPendingSweepInParallel()
|
| // if there is no sweeper thread).
|
| TRACE_EVENT0("blink_gc", "ThreadState::sweepNonFinalizedHeaps");
|
| for (int i = 0; i < NumberOfNonFinalizedHeaps; i++) {
|
| - HeapStats stats;
|
| - m_heaps[FirstNonFinalizedHeap + i]->sweep(&stats);
|
| - m_stats.add(&stats);
|
| + m_heaps[FirstNonFinalizedHeap + i]->sweep();
|
| }
|
| }
|
|
|
| @@ -1185,25 +1163,18 @@ void ThreadState::performPendingSweepInParallel()
|
| // Sweep the finalized pages.
|
| TRACE_EVENT0("blink_gc", "ThreadState::sweepFinalizedHeaps");
|
| for (int i = 0; i < NumberOfFinalizedHeaps; i++) {
|
| - HeapStats stats;
|
| - m_heaps[FirstFinalizedHeap + i]->sweep(&stats);
|
| - m_stats.add(&stats);
|
| + m_heaps[FirstFinalizedHeap + i]->sweep();
|
| }
|
| }
|
|
|
| - // Wait for the sweeper threads and update the heap stats with the
|
| - // stats for the heap portions swept by those threads.
|
| waitUntilSweepersDone();
|
| for (int i = 0; i < NumberOfNonFinalizedHeaps; i++) {
|
| - m_stats.add(&heapStatsVector[i]);
|
| if (splitOffHeaps[i])
|
| m_heaps[FirstNonFinalizedHeap + i]->merge(splitOffHeaps[i].release());
|
| }
|
|
|
| for (int i = 0; i < NumberOfHeaps; i++)
|
| m_heaps[i]->postSweepProcessing();
|
| -
|
| - getStats(m_statsAfterLastGC);
|
| }
|
|
|
| void ThreadState::addInterruptor(Interruptor* interruptor)
|
|
|