Increase slice time for longer running CCs.

If a CC takes too long (around 50 slices) or gets interrupted by a GC,
we have to finish it synchronously, which can cause a big pause.
This patch tries to avoid that by eagerly increasing the slice budget
the longer a CC goes on. It linearly increases the slice time from 5ms
to 40ms as we approach the halfway point of a CC (1 second), matching
GC pauses, and then leaves it at 40ms.
This commit is contained in:
Andrew McCreight 2019-01-29 13:36:19 +01:00 committed by Roy Tam
commit 7b5e5f85de

View file

@ -1355,9 +1355,20 @@ nsJSContext::RunCycleCollectorSlice()
TimeStamp now = TimeStamp::Now();
// Only run a limited slice if we're within the max running time.
if (TimeBetween(gCCStats.mBeginTime, now) < kMaxICCDuration) {
float sliceMultiplier = std::max(TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay, 1.0f);
budget = js::SliceBudget(js::TimeBudget(kICCSliceBudget * sliceMultiplier));
uint32_t runningTime = TimeBetween(gCCStats.mBeginTime, now);
if (runningTime < kMaxICCDuration) {
// Try to make up for a delay in running this slice.
float sliceDelayMultiplier = TimeBetween(gCCStats.mEndSliceTime, now) / (float)kICCIntersliceDelay;
float delaySliceBudget = kICCSliceBudget * sliceDelayMultiplier;
// Increase slice budgets up to |maxLaterSlice| as we approach
// half way through the ICC, to avoid large sync CCs.
float percentToHalfDone = std::min(2.0f * runningTime / kMaxICCDuration, 1.0f);
const float maxLaterSlice = 40.0f;
float laterSliceBudget = maxLaterSlice * percentToHalfDone;
budget = js::SliceBudget(js::TimeBudget(std::max({delaySliceBudget,
laterSliceBudget, (float)kICCSliceBudget})));
}
}
}