зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1661293 - Give CCGCScheduler an mEagerMajorGCReason field (set in a later patch) to indicate that we would like to do a major GC when convenient. This is in addition to the usual mMajorGCReason for when we definitely want to do a GC. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D139206
This commit is contained in:
Родитель
b0023fb190
Коммит
9a89af097f
|
@ -109,7 +109,7 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
void CCGCScheduler::NoteGCBegin() {
|
||||
void CCGCScheduler::NoteGCBegin(JS::GCReason aReason) {
|
||||
// Treat all GC as incremental here; non-incremental GC will just appear to
|
||||
// be one slice.
|
||||
mInIncrementalGC = true;
|
||||
|
@ -122,10 +122,19 @@ void CCGCScheduler::NoteGCBegin() {
|
|||
if (child) {
|
||||
child->StartedGC();
|
||||
}
|
||||
|
||||
// The reason might have come from mMajorReason, mEagerMajorGCReason, or
|
||||
// in the case of an internally-generated GC, it might come from the
|
||||
// internal logic (and be passed in here). It's easier to manage a single
|
||||
// reason state variable, so merge all sources into mMajorGCReason.
|
||||
MOZ_ASSERT(aReason != JS::GCReason::NO_REASON);
|
||||
mMajorGCReason = aReason;
|
||||
mEagerMajorGCReason = JS::GCReason::NO_REASON;
|
||||
}
|
||||
|
||||
void CCGCScheduler::NoteGCEnd() {
|
||||
mMajorGCReason = JS::GCReason::NO_REASON;
|
||||
mEagerMajorGCReason = JS::GCReason::NO_REASON;
|
||||
|
||||
mInIncrementalGC = false;
|
||||
mCCBlockStart = TimeStamp();
|
||||
|
@ -205,6 +214,7 @@ void CCGCScheduler::NoteCCEnd(TimeStamp aWhen) {
|
|||
void CCGCScheduler::NoteWontGC() {
|
||||
mReadyForMajorGC = !mAskParentBeforeMajorGC;
|
||||
mMajorGCReason = JS::GCReason::NO_REASON;
|
||||
mEagerMajorGCReason = JS::GCReason::NO_REASON;
|
||||
mWantAtLeastRegularGC = false;
|
||||
// Don't clear the WantFullGC state, we will do a full GC the next time a
|
||||
// GC happens for any other reason.
|
||||
|
@ -213,10 +223,11 @@ void CCGCScheduler::NoteWontGC() {
|
|||
bool CCGCScheduler::GCRunnerFired(TimeStamp aDeadline) {
|
||||
MOZ_ASSERT(!mDidShutdown, "GCRunner still alive during shutdown");
|
||||
|
||||
GCRunnerStep step = GetNextGCRunnerAction();
|
||||
GCRunnerStep step = GetNextGCRunnerAction(aDeadline);
|
||||
switch (step.mAction) {
|
||||
case GCRunnerAction::None:
|
||||
MOZ_CRASH("Unexpected GCRunnerAction");
|
||||
KillGCRunner();
|
||||
return false;
|
||||
|
||||
case GCRunnerAction::WaitToMajorGC: {
|
||||
MOZ_ASSERT(!mHaveAskedParent, "GCRunner alive after asking the parent");
|
||||
|
@ -882,18 +893,29 @@ CCRunnerStep CCGCScheduler::AdvanceCCRunner(TimeStamp aDeadline, TimeStamp aNow,
|
|||
};
|
||||
}
|
||||
|
||||
GCRunnerStep CCGCScheduler::GetNextGCRunnerAction() const {
|
||||
MOZ_ASSERT(mMajorGCReason != JS::GCReason::NO_REASON);
|
||||
|
||||
GCRunnerStep CCGCScheduler::GetNextGCRunnerAction(TimeStamp aDeadline) const {
|
||||
if (InIncrementalGC()) {
|
||||
MOZ_ASSERT(mMajorGCReason != JS::GCReason::NO_REASON);
|
||||
return {GCRunnerAction::GCSlice, mMajorGCReason};
|
||||
}
|
||||
|
||||
if (mReadyForMajorGC) {
|
||||
return {GCRunnerAction::StartMajorGC, mMajorGCReason};
|
||||
// Service a non-eager GC request first, even if it requires waiting.
|
||||
if (mMajorGCReason != JS::GCReason::NO_REASON) {
|
||||
return {mReadyForMajorGC ? GCRunnerAction::StartMajorGC
|
||||
: GCRunnerAction::WaitToMajorGC,
|
||||
mMajorGCReason};
|
||||
}
|
||||
|
||||
return {GCRunnerAction::WaitToMajorGC, mMajorGCReason};
|
||||
// Now for eager requests, which are ignored unless we're idle.
|
||||
if (!aDeadline.IsNull()) {
|
||||
if (mEagerMajorGCReason != JS::GCReason::NO_REASON) {
|
||||
return {mReadyForMajorGC ? GCRunnerAction::StartMajorGC
|
||||
: GCRunnerAction::WaitToMajorGC,
|
||||
mEagerMajorGCReason};
|
||||
}
|
||||
}
|
||||
|
||||
return {GCRunnerAction::None, JS::GCReason::NO_REASON};
|
||||
}
|
||||
|
||||
js::SliceBudget CCGCScheduler::ComputeForgetSkippableBudget(
|
||||
|
|
|
@ -235,7 +235,7 @@ class CCGCScheduler {
|
|||
}
|
||||
|
||||
// Starting a major GC (incremental or non-incremental).
|
||||
void NoteGCBegin();
|
||||
void NoteGCBegin(JS::GCReason aReason);
|
||||
|
||||
// Major GC completed.
|
||||
void NoteGCEnd();
|
||||
|
@ -424,7 +424,7 @@ class CCGCScheduler {
|
|||
mCCReason = CCReason::NO_REASON;
|
||||
}
|
||||
|
||||
GCRunnerStep GetNextGCRunnerAction() const;
|
||||
GCRunnerStep GetNextGCRunnerAction(TimeStamp aDeadline) const;
|
||||
|
||||
CCRunnerStep AdvanceCCRunner(TimeStamp aDeadline, TimeStamp aNow,
|
||||
uint32_t aSuspectedCCObjects);
|
||||
|
@ -496,6 +496,7 @@ class CCGCScheduler {
|
|||
|
||||
mozilla::CCReason mCCReason = mozilla::CCReason::NO_REASON;
|
||||
JS::GCReason mMajorGCReason = JS::GCReason::NO_REASON;
|
||||
JS::GCReason mEagerMajorGCReason = JS::GCReason::NO_REASON;
|
||||
|
||||
bool mIsCompactingOnUserInactive = false;
|
||||
bool mIsCollectingCycles = false;
|
||||
|
|
|
@ -1691,7 +1691,7 @@ static void DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress,
|
|||
switch (aProgress) {
|
||||
case JS::GC_CYCLE_BEGIN: {
|
||||
// Prevent cycle collections and shrinking during incremental GC.
|
||||
sScheduler.NoteGCBegin();
|
||||
sScheduler.NoteGCBegin(aDesc.reason_);
|
||||
sCurrentGCStartTime = TimeStamp::Now();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ void TestGC::Run(int aNumSlices) {
|
|||
CCReason neededCCAtStartOfGC =
|
||||
mScheduler.IsCCNeeded(Now(), SuspectedCCObjects());
|
||||
|
||||
mScheduler.NoteGCBegin();
|
||||
mScheduler.NoteGCBegin(JS::GCReason::API);
|
||||
|
||||
for (int slice = 0; slice < aNumSlices; slice++) {
|
||||
EXPECT_TRUE(mScheduler.InIncrementalGC());
|
||||
|
|
Загрузка…
Ссылка в новой задаче