зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662254 - Use a state descriptor table to control when to check for CC aborts and ForgetSkippable runs r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D90902
This commit is contained in:
Родитель
c6c29e644b
Коммит
51eec46175
|
@ -248,7 +248,7 @@ class CCGCScheduler {
|
|||
std::max({delaySliceBudget, laterSliceBudget, baseBudget}));
|
||||
}
|
||||
|
||||
bool ShouldFireForgetSkippable(uint32_t aSuspected) const {
|
||||
bool ShouldForgetSkippable(uint32_t aSuspected) const {
|
||||
// Only do a forget skippable if there are more than a few new objects
|
||||
// or we're doing the initial forget skippables.
|
||||
return ((mPreviousSuspectedCount + 100) <= aSuspected) ||
|
||||
|
@ -363,6 +363,29 @@ class CCGCScheduler {
|
|||
void DeactivateCCRunner() { mCCRunnerState = CCRunnerState::Inactive; }
|
||||
|
||||
CCRunnerStep GetNextCCRunnerAction(TimeStamp aDeadline, uint32_t aSuspected) {
|
||||
struct StateDescriptor {
|
||||
// When in this state, should we first check to see if we still have
|
||||
// enough reason to CC?
|
||||
bool mCanAbortCC;
|
||||
|
||||
// If we do decide to abort the CC, should we still try to forget
|
||||
// skippables one more time?
|
||||
bool mTryFinalForgetSkippable;
|
||||
};
|
||||
|
||||
constexpr StateDescriptor stateDescriptors[] = {
|
||||
/* clang-format off */
|
||||
[int(CCRunnerState::Inactive)] = {false, false},
|
||||
[int(CCRunnerState::ReducePurple)] = {false, false},
|
||||
[int(CCRunnerState::CleanupChildless)] = {true, true},
|
||||
[int(CCRunnerState::CleanupContentUnbinder)] = {true, false},
|
||||
[int(CCRunnerState::CleanupDeferred)] = {false, false},
|
||||
[int(CCRunnerState::StartCycleCollection)] = {false, false},
|
||||
[int(CCRunnerState::CycleCollecting)] = {false, false}
|
||||
/* clang-format on */
|
||||
};
|
||||
const StateDescriptor& desc = stateDescriptors[int(mCCRunnerState)];
|
||||
|
||||
if (mDidShutdown) {
|
||||
return {CCRunnerAction::StopRunning, Yield};
|
||||
}
|
||||
|
@ -408,31 +431,22 @@ class CCGCScheduler {
|
|||
// For states that aren't just continuations of previous states, check
|
||||
// whether a CC is still needed (after doing various things to reduce the
|
||||
// purple buffer).
|
||||
switch (mCCRunnerState) {
|
||||
case CCRunnerState::ReducePurple:
|
||||
case CCRunnerState::CleanupDeferred:
|
||||
case CCRunnerState::StartCycleCollection:
|
||||
case CCRunnerState::CycleCollecting:
|
||||
break;
|
||||
|
||||
default:
|
||||
// If we don't pass the threshold for wanting to cycle collect, stop
|
||||
// now (after possibly doing a final ForgetSkippable).
|
||||
if (!IsCCNeeded(aSuspected, now)) {
|
||||
if (desc.mCanAbortCC && !IsCCNeeded(aSuspected, now)) {
|
||||
// If we don't pass the threshold for wanting to cycle collect, stop now
|
||||
// (after possibly doing a final ForgetSkippable).
|
||||
mCCRunnerState = CCRunnerState::Inactive;
|
||||
NoteForgetSkippableOnlyCycle();
|
||||
|
||||
// Preserve the previous code's idea of when to check whether a
|
||||
// ForgetSkippable should be fired.
|
||||
if (mCCRunnerState != CCRunnerState::CleanupContentUnbinder &&
|
||||
ShouldFireForgetSkippable(aSuspected)) {
|
||||
if (desc.mTryFinalForgetSkippable && ShouldForgetSkippable(aSuspected)) {
|
||||
// The Inactive state will make us StopRunning after this action is
|
||||
// performed (see conditional at top of function).
|
||||
return {CCRunnerAction::ForgetSkippable, Yield, KeepChildless};
|
||||
}
|
||||
|
||||
return {CCRunnerAction::StopRunning, Yield};
|
||||
}
|
||||
}
|
||||
|
||||
switch (mCCRunnerState) {
|
||||
// ReducePurple: a GC ran (or we otherwise decided to try CC'ing). Wait
|
||||
|
@ -445,7 +459,7 @@ class CCGCScheduler {
|
|||
mCCRunnerState = CCRunnerState::CleanupChildless;
|
||||
}
|
||||
|
||||
if (ShouldFireForgetSkippable(aSuspected)) {
|
||||
if (ShouldForgetSkippable(aSuspected)) {
|
||||
return {CCRunnerAction::ForgetSkippable, Yield, KeepChildless};
|
||||
}
|
||||
|
||||
|
@ -460,7 +474,7 @@ class CCGCScheduler {
|
|||
|
||||
// Continue on to CleanupChildless, but only after checking IsCCNeeded
|
||||
// again.
|
||||
return GetNextCCRunnerAction(aDeadline, aSuspected);
|
||||
return {CCRunnerAction::None, Continue};
|
||||
|
||||
// CleanupChildless: do a stronger ForgetSkippable that removes nodes
|
||||
// with no children in the cycle collector graph. This state is split
|
||||
|
|
Загрузка…
Ссылка в новой задаче