| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index deaa5135d82c09596854b74a0164c6e37fec1fe5..82fde716f1971ffe6a40ceb7aa311dcbbb05416c 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -857,13 +857,26 @@ void ThreadState::completeSweep()
|
| m_heaps[i]->completeSweep();
|
| }
|
|
|
| - if (isMainThread()) {
|
| + if (isMainThread() && m_allocatedObjectSizeBeforeGC) {
|
| // FIXME: Heap::markedObjectSize() may not be accurate because other
|
| // threads may not have finished sweeping.
|
| - m_collectionRate = 1.0 * Heap::markedObjectSize() / m_allocatedObjectSizeBeforeSweeping;
|
| + m_collectionRate = 1.0 * Heap::markedObjectSize() / m_allocatedObjectSizeBeforeGC;
|
| + ASSERT(m_collectionRate >= 0);
|
| +
|
| + // The main thread might be at a safe point, with other
|
| + // threads leaving theirs and accumulating marked object size
|
| + // while continuing to sweep. That accumulated size might end up
|
| + // exceeding what the main thread sampled in preGC() (recorded
|
| + // in m_allocatedObjectSizeBeforeGC), resulting in a non-sensical
|
| + // > 1.0 rate.
|
| + //
|
| + // This is rare (cf. HeapTest.Threading for a case though);
|
| + // reset the invalid rate if encountered.
|
| + //
|
| + if (m_collectionRate > 1.0)
|
| + m_collectionRate = 1.0;
|
| } else {
|
| - // FIXME: We should make m_lowCollectionRate available in non-main
|
| - // threads.
|
| + // FIXME: We should make m_collectionRate available in non-main threads.
|
| m_collectionRate = 1.0;
|
| }
|
|
|
| @@ -893,6 +906,8 @@ void ThreadState::preGC()
|
| makeConsistentForSweeping();
|
| prepareRegionTree();
|
| flushHeapDoesNotContainCacheIfNeeded();
|
| + if (isMainThread())
|
| + m_allocatedObjectSizeBeforeGC = Heap::allocatedObjectSize() + Heap::markedObjectSize();
|
| }
|
|
|
| void ThreadState::postGC(GCType gcType)
|
| @@ -1037,8 +1052,6 @@ void ThreadState::postGCProcessing()
|
| return;
|
|
|
| m_didV8GCAfterLastGC = false;
|
| - if (isMainThread())
|
| - m_allocatedObjectSizeBeforeSweeping = Heap::allocatedObjectSize();
|
|
|
| #if ENABLE(GC_PROFILE_HEAP)
|
| // We snapshot the heap prior to sweeping to get numbers for both resources
|
|
|