| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index 9d552de2b04b487780f2488bd62458f8907cd17a..dff6eeb5c3bbcd95ea1a0ec9a2253b70adc9504c 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -606,13 +606,35 @@ void ThreadState::performIdleGC(double deadlineSeconds)
|
| Heap::collectGarbage(NoHeapPointersOnStack, GCWithoutSweep, Heap::IdleGC);
|
| }
|
|
|
| -void ThreadState::performIdleCompleteSweep(double deadlineSeconds)
|
| +void ThreadState::performIdleLazySweep(double deadlineSeconds)
|
| {
|
| ASSERT(isMainThread());
|
| - // The completeSweep() does nothing if the sweeping is already done.
|
| - // TODO(haraken): Split the sweeping task into chunks so that each chunk fits
|
| - // in the deadlineSeconds.
|
| - completeSweep();
|
| +
|
| + // If we are not in a sweeping phase, there is nothing to do here.
|
| + if (!isSweepingInProgress())
|
| + return;
|
| +
|
| + // This check is here to prevent performIdleLazySweep() from being called
|
| + // recursively. I'm not sure if it can happen but it would be safer to have
|
| + // the check just in case.
|
| + if (sweepForbidden())
|
| + return;
|
| +
|
| + ThreadState::SweepForbiddenScope scope(this);
|
| + {
|
| + for (int i = 0; i < NumberOfHeaps; i++) {
|
| + double remainingBudget = deadlineSeconds - Platform::current()->monotonicallyIncreasingTime();
|
| + if (remainingBudget <= 0 || !m_heaps[i]->lazySweepWithDeadline(deadlineSeconds)) {
|
| + // We couldn't finish the sweeping within the deadline.
|
| + // We request another idle task for the remaining sweeping.
|
| + scheduleIdleLazySweep();
|
| + return;
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Now we have finished the sweeping.
|
| + postSweep();
|
| }
|
|
|
| void ThreadState::scheduleIdleGC()
|
| @@ -630,18 +652,15 @@ void ThreadState::scheduleIdleGC()
|
| setGCState(IdleGCScheduled);
|
| }
|
|
|
| -void ThreadState::scheduleIdleCompleteSweep()
|
| +void ThreadState::scheduleIdleLazySweep()
|
| {
|
| // Idle complete sweep is supported only in the main thread.
|
| if (!isMainThread())
|
| return;
|
|
|
| - // TODO(haraken): Temporarily disable complete sweeping in idle tasks
|
| - // because it turned out that it has a risk of violating the idle task
|
| - // deadline and thus regressing queueing_durations. We'll enable this
|
| - // once we finish collecting performance numbers.
|
| -#if 0
|
| - Scheduler::shared()->postIdleTask(FROM_HERE, WTF::bind<double>(&ThreadState::performIdleCompleteSweep, this));
|
| + // TODO(haraken): Remove this. Lazy sweeping is not yet enabled in non-oilpan builds.
|
| +#if ENABLE(OILPAN)
|
| + Scheduler::shared()->postIdleTask(FROM_HERE, WTF::bind<double>(&ThreadState::performIdleLazySweep, this));
|
| #endif
|
| }
|
|
|
| @@ -795,6 +814,11 @@ void ThreadState::completeSweep()
|
| }
|
| }
|
|
|
| + postSweep();
|
| +}
|
| +
|
| +void ThreadState::postSweep()
|
| +{
|
| if (isMainThread() && m_allocatedObjectSizeBeforeGC) {
|
| // FIXME: Heap::markedObjectSize() may not be accurate because other
|
| // threads may not have finished sweeping.
|
| @@ -1056,7 +1080,7 @@ void ThreadState::preSweep()
|
| } else {
|
| // The default behavior is lazy sweeping.
|
| setGCState(Sweeping);
|
| - scheduleIdleCompleteSweep();
|
| + scheduleIdleLazySweep();
|
| }
|
| #else
|
| // FIXME: For now, we disable lazy sweeping in non-oilpan builds
|
|
|