Index: Source/platform/heap/ThreadState.cpp |
diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp |
index 4fc1e4fe9c25d3496400c0fa4a0b497278b20556..a390323a8712895efba9951b3ff0990f9c4775fc 100644 |
--- a/Source/platform/heap/ThreadState.cpp |
+++ b/Source/platform/heap/ThreadState.cpp |
@@ -42,6 +42,7 @@ |
#include "public/platform/Platform.h" |
#include "public/platform/WebThread.h" |
#include "public/platform/WebTraceLocation.h" |
+#include "wtf/Partitions.h" |
#include "wtf/ThreadingPrimitives.h" |
#if ENABLE(GC_PROFILING) |
#include "platform/TracedValue.h" |
@@ -500,7 +501,7 @@ Mutex& ThreadState::globalRootsMutex() |
return mutex; |
} |
-// FIXME: We should improve the GC heuristics. |
+// TODO(haraken): We should improve the GC heuristics. |
// These heuristics affect performance significantly. |
bool ThreadState::shouldScheduleIdleGC() |
{ |
@@ -511,17 +512,17 @@ bool ThreadState::shouldScheduleIdleGC() |
// sweeping. If this thread reaches here before the main thread finishes |
// lazy sweeping, the thread will use the estimated size of the last GC. |
size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); |
- // Schedule an idle GC if more than 512 KB has been allocated since |
+ // Schedule an idle GC if more than 1Mb has been allocated since |
// the last GC and the current memory usage (=allocated + estimated) |
// is >50% larger than the estimated live memory usage. |
- size_t allocatedObjectSize = Heap::allocatedObjectSize(); |
- return allocatedObjectSize >= 512 * 1024 && allocatedObjectSize > estimatedLiveObjectSize / 2; |
+ size_t currentObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSize(); |
+ return currentObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLiveObjectSize / 2; |
#else |
return false; |
#endif |
} |
-// FIXME: We should improve the GC heuristics. |
+// TODO(haraken): We should improve the GC heuristics. |
// These heuristics affect performance significantly. |
bool ThreadState::shouldSchedulePreciseGC() |
{ |
@@ -534,30 +535,30 @@ bool ThreadState::shouldSchedulePreciseGC() |
// sweeping. If this thread reaches here before the main thread finishes |
// lazy sweeping, the thread will use the estimated size of the last GC. |
size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); |
- // Schedule a precise GC if more than 512 KB has been allocated since |
+ // Schedule a precise GC if more than 1Mb has been allocated since |
// the last GC and the current memory usage (=allocated + estimated) |
// is >50% larger than the estimated live memory usage. |
- size_t allocatedObjectSize = Heap::allocatedObjectSize(); |
- return allocatedObjectSize >= 512 * 1024 && allocatedObjectSize > estimatedLiveObjectSize / 2; |
+ size_t currentObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSize(); |
+ return currentObjectSize >= 1024 * 1024 && currentObjectSize > estimatedLiveObjectSize / 2; |
#endif |
} |
-// FIXME: We should improve the GC heuristics. |
+// TODO(haraken): We should improve the GC heuristics. |
// These heuristics affect performance significantly. |
bool ThreadState::shouldForceConservativeGC() |
{ |
if (UNLIKELY(m_gcForbiddenCount)) |
return false; |
- if (Heap::isUrgentGCRequested()) |
- return true; |
- |
// The estimated size is updated when the main thread finishes lazy |
// sweeping. If this thread reaches here before the main thread finishes |
// lazy sweeping, the thread will use the estimated size of the last GC. |
size_t estimatedLiveObjectSize = Heap::estimatedLiveObjectSize(); |
size_t allocatedObjectSize = Heap::allocatedObjectSize(); |
- if (Heap::markedObjectSize() + allocatedObjectSize >= 300 * 1024 * 1024) { |
+ // Heap::markedObjectSize() may be underestimated if any thread has not |
+ // finished completeSweep(). |
+ size_t currentObjectSize = allocatedObjectSize + Heap::markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); |
+ if (currentObjectSize >= 300 * 1024 * 1024) { |
// If we're consuming too much memory, trigger a conservative GC |
// aggressively. This is a safe guard to avoid OOM. |
return allocatedObjectSize > estimatedLiveObjectSize / 2; |
@@ -572,19 +573,13 @@ void ThreadState::scheduleGCIfNeeded() |
{ |
checkThread(); |
// Allocation is allowed during sweeping, but those allocations should not |
- // trigger nested GCs. Does not apply if an urgent GC has been requested. |
- if (isSweepingInProgress() && UNLIKELY(!Heap::isUrgentGCRequested())) |
+ // trigger nested GCs. |
+ if (isSweepingInProgress()) |
return; |
ASSERT(!sweepForbidden()); |
if (shouldForceConservativeGC()) { |
- if (Heap::isUrgentGCRequested()) { |
- // If GC is deemed urgent, eagerly sweep and finalize any external allocations right away. |
- Heap::collectGarbage(HeapPointersOnStack, GCWithSweep, Heap::ConservativeGC); |
- } else { |
- // Otherwise, schedule a lazy sweeping in an idle task. |
- Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::ConservativeGC); |
- } |
+ Heap::collectGarbage(HeapPointersOnStack, GCWithoutSweep, Heap::ConservativeGC); |
return; |
} |
if (shouldSchedulePreciseGC()) |
@@ -846,8 +841,13 @@ void ThreadState::completeSweep() |
void ThreadState::postSweep() |
{ |
- if (isMainThread()) |
+ if (isMainThread()) { |
+ // At the point where the main thread finishes lazy sweeping, |
+ // we estimate the live object size. Heap::markedObjectSize() |
+ // may be underestimated if any other thread has not finished |
+ // lazy sweeping. |
Heap::setEstimatedLiveObjectSize(Heap::markedObjectSize()); |
+ } |
switch (gcState()) { |
case Sweeping: |