Bug 1868744 - If JS engine triggered a GC slice, don't trigger another too soon from CCGCScheduler, r=jonco

Differential Revision: https://phabricator.services.mozilla.com/D195755
This commit is contained in:
Olli Pettay 2023-12-07 12:34:33 +00:00
Родитель ae0dba02b3
Коммит 07c9e45ef3
5 изменённых файлов: 23 добавлений и 1 удалений

Просмотреть файл

@ -622,6 +622,16 @@ void CCGCScheduler::PokeMinorGC(JS::GCReason aReason) {
EnsureGCRunner(0); EnsureGCRunner(0);
} }
void CCGCScheduler::EnsureOrResetGCRunner() {
if (!mGCRunner) {
EnsureGCRunner(0);
return;
}
mGCRunner->ResetTimer(TimeDuration::FromMilliseconds(
StaticPrefs::javascript_options_gc_delay_interslice()));
}
void CCGCScheduler::EnsureGCRunner(TimeDuration aDelay) { void CCGCScheduler::EnsureGCRunner(TimeDuration aDelay) {
if (mGCRunner) { if (mGCRunner) {
return; return;

Просмотреть файл

@ -191,6 +191,10 @@ class CCGCScheduler {
*/ */
void EnsureGCRunner(TimeDuration aDelay); void EnsureGCRunner(TimeDuration aDelay);
// If GCRunner isn't active, this calls EnsureGCRunner(0). Otherwise the timer
// is reset.
void EnsureOrResetGCRunner();
void EnsureCCRunner(TimeDuration aDelay, TimeDuration aBudget); void EnsureCCRunner(TimeDuration aDelay, TimeDuration aBudget);
// State modification // State modification

Просмотреть файл

@ -1873,7 +1873,7 @@ static void DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress,
// If incremental GC wasn't triggered by GCTimerFired, we may not have a // If incremental GC wasn't triggered by GCTimerFired, we may not have a
// runner to ensure all the slices are handled. So, create the runner // runner to ensure all the slices are handled. So, create the runner
// here. // here.
sScheduler->EnsureGCRunner(0); sScheduler->EnsureOrResetGCRunner();
} }
if (sScheduler->IsCCNeeded(TimeStamp::Now(), if (sScheduler->IsCCNeeded(TimeStamp::Now(),

Просмотреть файл

@ -259,6 +259,11 @@ void IdleTaskRunner::SetTimerInternal(TimeDuration aDelay) {
if (mTimerActive) { if (mTimerActive) {
return; return;
} }
ResetTimer(aDelay);
}
void IdleTaskRunner::ResetTimer(TimeDuration aDelay) {
mTimerActive = false;
if (!mTimer) { if (!mTimer) {
mTimer = NS_NewTimer(); mTimer = NS_NewTimer();

Просмотреть файл

@ -69,8 +69,11 @@ class IdleTaskRunner {
// period, or null if not running during idle time. // period, or null if not running during idle time.
void SetIdleDeadline(mozilla::TimeStamp aDeadline); void SetIdleDeadline(mozilla::TimeStamp aDeadline);
// If the timer is already active, SetTimer doesn't do anything.
void SetTimer(TimeDuration aDelay, nsIEventTarget* aTarget); void SetTimer(TimeDuration aDelay, nsIEventTarget* aTarget);
void ResetTimer(TimeDuration aDelay);
// Update the minimum idle time that this callback would be invoked for. // Update the minimum idle time that this callback would be invoked for.
void SetMinimumUsefulBudget(int64_t aMinimumUsefulBudget); void SetMinimumUsefulBudget(int64_t aMinimumUsefulBudget);