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, CleanupDeferred,
StartCycleCollection, StartCycleCollection,
CycleCollecting, CycleCollecting,
Canceled,
NumStates NumStates
}; };
void InitCCRunnerStateMachine(CCRunnerState initialState) { 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; mCCRunnerState = initialState;
// Currently, there are only two entry points to the non-Inactive part of
// the state machine.
if (initialState == CCRunnerState::ReducePurple) { if (initialState == CCRunnerState::ReducePurple) {
mCCDelay = kCCDelay; mCCDelay = kCCDelay;
mCCRunnerEarlyFireCount = 0; mCCRunnerEarlyFireCount = 0;
@ -423,6 +430,9 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
bool mTryFinalForgetSkippable; 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[] = { constexpr StateDescriptor stateDescriptors[] = {
{false, false}, /* CCRunnerState::Inactive */ {false, false}, /* CCRunnerState::Inactive */
{false, false}, /* CCRunnerState::ReducePurple */ {false, false}, /* CCRunnerState::ReducePurple */
@ -430,17 +440,21 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
{true, false}, /* CCRunnerState::CleanupContentUnbinder */ {true, false}, /* CCRunnerState::CleanupContentUnbinder */
{false, false}, /* CCRunnerState::CleanupDeferred */ {false, false}, /* CCRunnerState::CleanupDeferred */
{false, false}, /* CCRunnerState::StartCycleCollection */ {false, false}, /* CCRunnerState::StartCycleCollection */
{false, false}}; /* CCRunnerState::CycleCollecting */ {false, false}, /* CCRunnerState::CycleCollecting */
{false, false}}; /* CCRunnerState::Canceled */
static_assert(mozilla::ArrayLength(stateDescriptors) == static_assert(mozilla::ArrayLength(stateDescriptors) ==
size_t(CCRunnerState::NumStates), size_t(CCRunnerState::NumStates),
"need one state descriptor per state"); "need one state descriptor per state");
const StateDescriptor& desc = stateDescriptors[int(mCCRunnerState)]; const StateDescriptor& desc = stateDescriptors[int(mCCRunnerState)];
// Make sure we initialized the state machine.
MOZ_ASSERT(mCCRunnerState != CCRunnerState::Inactive);
if (mDidShutdown) { if (mDidShutdown) {
return {CCRunnerAction::StopRunning, Yield}; return {CCRunnerAction::StopRunning, Yield};
} }
if (mCCRunnerState == CCRunnerState::Inactive) { if (mCCRunnerState == CCRunnerState::Canceled) {
// When we cancel a cycle, there may have been a final ForgetSkippable. // When we cancel a cycle, there may have been a final ForgetSkippable.
return {CCRunnerAction::StopRunning, Yield}; return {CCRunnerAction::StopRunning, Yield};
} }
@ -484,13 +498,13 @@ CCRunnerStep CCGCScheduler::GetNextCCRunnerAction(TimeStamp aDeadline,
if (desc.mCanAbortCC && !IsCCNeeded(aSuspected, now)) { if (desc.mCanAbortCC && !IsCCNeeded(aSuspected, now)) {
// If we don't pass the threshold for wanting to cycle collect, stop now // If we don't pass the threshold for wanting to cycle collect, stop now
// (after possibly doing a final ForgetSkippable). // (after possibly doing a final ForgetSkippable).
mCCRunnerState = CCRunnerState::Inactive; mCCRunnerState = CCRunnerState::Canceled;
NoteForgetSkippableOnlyCycle(); NoteForgetSkippableOnlyCycle();
// Preserve the previous code's idea of when to check whether a // Preserve the previous code's idea of when to check whether a
// ForgetSkippable should be fired. // ForgetSkippable should be fired.
if (desc.mTryFinalForgetSkippable && ShouldForgetSkippable(aSuspected)) { 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). // performed (see conditional at top of function).
return {CCRunnerAction::ForgetSkippable, Yield, KeepChildless}; return {CCRunnerAction::ForgetSkippable, Yield, KeepChildless};
} }