зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1544885 - Don't immediately run another GC slice in idle time if there's no work to do on the main thread r=smaug r=pbone
Differential Revision: https://phabricator.services.mozilla.com/D27889
This commit is contained in:
Родитель
bda8d7ed6b
Коммит
3538d42c33
|
@ -1769,12 +1769,11 @@ bool InterSliceGCRunnerFired(TimeStamp aDeadline, void* aData) {
|
|||
Telemetry::Accumulate(Telemetry::GC_SLICE_DURING_IDLE, percent);
|
||||
}
|
||||
|
||||
// If we didn't use the whole budget, we're past the foreground sweeping slice
|
||||
// and will need to wait for the background tasks to finish, or we're at the
|
||||
// last slice. Return value on the latter case doesn't matter, and on the
|
||||
// former we want to wait a bit before polling again.
|
||||
// Returning false makes IdleTaskRunner postpone the next call a bit.
|
||||
return int64_t(sliceDuration.ToMilliseconds()) >= budget;
|
||||
// If the GC doesn't have any more work to do on the foreground thread (and
|
||||
// e.g. is waiting for background sweeping to finish) then return false to
|
||||
// make IdleTaskRunner postpone the next call a bit.
|
||||
JSContext* cx = danger::GetJSContext();
|
||||
return JS::IncrementalGCHasForegroundWork(cx);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -565,6 +565,14 @@ extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx,
|
|||
extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, GCReason reason,
|
||||
int64_t millis = 0);
|
||||
|
||||
/**
|
||||
* Return whether an incremental GC has work to do on the foreground thread and
|
||||
* would make progress if a slice was run now. If this returns false then the GC
|
||||
* is waiting for background threads to finish their work and a slice started
|
||||
* now would return immediately.
|
||||
*/
|
||||
extern JS_PUBLIC_API bool IncrementalGCHasForegroundWork(JSContext* cx);
|
||||
|
||||
/**
|
||||
* If IsIncrementalGCInProgress(cx), this call finishes the ongoing collection
|
||||
* by performing an arbitrarily long slice. If !IsIncrementalGCInProgress(cx),
|
||||
|
|
|
@ -7190,6 +7190,23 @@ void GCRuntime::incrementalSlice(SliceBudget& budget, JS::GCReason reason,
|
|||
MOZ_ASSERT(marker.markColor() == MarkColor::Black);
|
||||
}
|
||||
|
||||
bool GCRuntime::hasForegroundWork() const {
|
||||
switch (incrementalState) {
|
||||
case State::NotActive:
|
||||
// Incremental GC is not running and no work is pending.
|
||||
return false;
|
||||
case State::Finalize:
|
||||
// We yield in the Finalize state to wait for background sweeping.
|
||||
return !isBackgroundSweeping();
|
||||
case State::Decommit:
|
||||
// We yield in the Decommit state to wait for background decommit.
|
||||
return !decommitTask.isRunning();
|
||||
default:
|
||||
// In all other states there is still work to do.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
gc::AbortReason gc::IsIncrementalGCUnsafe(JSRuntime* rt) {
|
||||
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
|
||||
|
||||
|
@ -8564,6 +8581,12 @@ JS_PUBLIC_API void JS::IncrementalGCSlice(JSContext* cx, GCReason reason,
|
|||
cx->runtime()->gc.gcSlice(reason, millis);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::IncrementalGCHasForegroundWork(JSContext* cx) {
|
||||
MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
|
||||
CHECK_THREAD(cx);
|
||||
return cx->runtime()->gc.hasForegroundWork();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void JS::FinishIncrementalGC(JSContext* cx, GCReason reason) {
|
||||
cx->runtime()->gc.finishGC(reason);
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ class GCRuntime {
|
|||
State state() const { return incrementalState; }
|
||||
bool isHeapCompacting() const { return state() == State::Compact; }
|
||||
bool isForegroundSweeping() const { return state() == State::Sweep; }
|
||||
bool isBackgroundSweeping() { return sweepTask.isRunning(); }
|
||||
bool isBackgroundSweeping() const { return sweepTask.isRunning(); }
|
||||
void waitBackgroundSweepEnd();
|
||||
void waitBackgroundAllocEnd() { allocTask.cancelAndWait(); }
|
||||
void waitBackgroundFreeEnd();
|
||||
|
@ -332,6 +332,7 @@ class GCRuntime {
|
|||
incrementalAllowed;
|
||||
}
|
||||
bool isIncrementalGCInProgress() const { return state() != State::NotActive; }
|
||||
bool hasForegroundWork() const;
|
||||
|
||||
bool isCompactingGCEnabled() const;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче