Bug 1711128 - Eliminate (rare) spurious GCs if we start and finish a new GC while waiting r=pbone,smaug

for a response from the parent. Before this patch, when the response arrived
from the parent we would unconditionally create a GCRunner and use the GCReason...

...remembered from when we made the request to the parent.

Differential Revision: https://phabricator.services.mozilla.com/D115098
This commit is contained in:
Steve Fink 2021-05-19 23:26:17 +00:00
Родитель c0e0fbb9aa
Коммит 9e8a02f439
2 изменённых файлов: 13 добавлений и 4 удалений

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

@ -167,8 +167,14 @@ class CCGCScheduler {
mNeedsGCAfterCC = true;
}
void NoteReadyForMajorGC() {
// Returns false if we started and finished a major GC while waiting for a
// response.
[[nodiscard]] bool NoteReadyForMajorGC() {
if (mMajorGCReason == JS::GCReason::NO_REASON) {
return false;
}
mReadyForMajorGC = true;
return true;
}
void NoteGCBegin() {
@ -681,6 +687,8 @@ CCRunnerStep CCGCScheduler::AdvanceCCRunner(TimeStamp aDeadline) {
}
GCRunnerStep CCGCScheduler::GetNextGCRunnerAction(TimeStamp aDeadline) {
MOZ_ASSERT(mMajorGCReason != JS::GCReason::NO_REASON);
if (InIncrementalGC()) {
return {GCRunnerAction::GCSlice, mMajorGCReason};
}

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

@ -1606,8 +1606,7 @@ bool GCRunnerFired(TimeStamp aDeadline, void* aClosure) {
GCRunnerStep step = sScheduler.GetNextGCRunnerAction(aDeadline);
switch (step.mAction) {
case GCRunnerAction::None:
nsJSContext::KillGCRunner();
return false;
MOZ_CRASH("Unexpected GCRunnerAction");
case GCRunnerAction::WaitToMajorGC: {
RefPtr<MayGCPromise> mbPromise = MayGCNow(step.mReason);
@ -1621,7 +1620,9 @@ bool GCRunnerFired(TimeStamp aDeadline, void* aClosure) {
mbPromise->Then(
GetMainThreadSerialEventTarget(), __func__,
[](bool aIgnored) {
sScheduler.NoteReadyForMajorGC();
if (!sScheduler.NoteReadyForMajorGC()) {
return; // Another GC completed while waiting.
}
// If a new runner was started, recreate it with a 0 delay. The new
// runner will continue in idle time.
nsJSContext::KillGCRunner();