Bug 1662254 - Add a new Canceled state to stop overusing Inactive and thereby allow asserting that the state machine has been initialized r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D95951
This commit is contained in:
Steve Fink 2020-11-12 19:06:48 +00:00
Родитель 064371a36c
Коммит b5d8c4bd2c
1 изменённых файлов: 19 добавлений и 5 удалений

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

@ -251,12 +251,19 @@ class CCGCScheduler {
CleanupDeferred,
StartCycleCollection,
CycleCollecting,
Canceled,
NumStates
};
void InitCCRunnerStateMachine(CCRunnerState initialState) {
MOZ_ASSERT(mCCRunnerState == CCRunnerState::Inactive);
// The state machine should always have been deactivated after the previous
// collection, however far that collection may have gone.
MOZ_ASSERT(mCCRunnerState == CCRunnerState::Inactive,
"DeactivateCCRunner should have been called");
mCCRunnerState = initialState;
// Currently, there are only two entry points to the non-Inactive part of
// the state machine.
if (initialState == CCRunnerState::ReducePurple) {
mCCDelay = kCCDelay;
mCCRunnerEarlyFireCount = 0;
@ -423,6 +430,9 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
bool mTryFinalForgetSkippable;
};
// The state descriptors for Inactive and Canceled will never actually be
// used. We will never call this function while Inactive, and Canceled is
// handled specially at the beginning.
constexpr StateDescriptor stateDescriptors[] = {
{false, false}, /* CCRunnerState::Inactive */
{false, false}, /* CCRunnerState::ReducePurple */
@ -430,17 +440,21 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
{true, false}, /* CCRunnerState::CleanupContentUnbinder */
{false, false}, /* CCRunnerState::CleanupDeferred */
{false, false}, /* CCRunnerState::StartCycleCollection */
{false, false}}; /* CCRunnerState::CycleCollecting */
{false, false}, /* CCRunnerState::CycleCollecting */
{false, false}}; /* CCRunnerState::Canceled */
static_assert(mozilla::ArrayLength(stateDescriptors) ==
size_t(CCRunnerState::NumStates),
"need one state descriptor per state");
const StateDescriptor& desc = stateDescriptors[int(mCCRunnerState)];
// Make sure we initialized the state machine.
MOZ_ASSERT(mCCRunnerState != CCRunnerState::Inactive);
if (mDidShutdown) {
return {CCRunnerAction::StopRunning, Yield};
}
if (mCCRunnerState == CCRunnerState::Inactive) {
if (mCCRunnerState == CCRunnerState::Canceled) {
// When we cancel a cycle, there may have been a final ForgetSkippable.
return {CCRunnerAction::StopRunning, Yield};
}
@ -484,13 +498,13 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
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;
mCCRunnerState = CCRunnerState::Canceled;
NoteForgetSkippableOnlyCycle();
// Preserve the previous code's idea of when to check whether a
// ForgetSkippable should be fired.
if (desc.mTryFinalForgetSkippable && ShouldForgetSkippable(aSuspected)) {
// The Inactive state will make us StopRunning after this action is
// The Canceled state will make us StopRunning after this action is
// performed (see conditional at top of function).
return {CCRunnerAction::ForgetSkippable, Yield, KeepChildless};
}