Chromium Code Reviews| 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); |
|
tkent
2014/11/17 10:30:15
Other threads might not finish sweeping yet, and H
haraken
2014/11/17 10:43:36
m_lowCollectionRate is just a heurstic anyway, so
|
| 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) |