| 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:
|
|
|