Bug 1703443 - pt 4. Move the CC runner into CCGCScheduler r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D118339
This commit is contained in:
@@ -227,4 +227,30 @@ void CCGCScheduler::KillGCRunner() {
|
||||
}
|
||||
}
|
||||
|
||||
void CCGCScheduler::EnsureCCRunner(TimeDuration aDelay, TimeDuration aBudget) {
|
||||
MOZ_ASSERT(!mDidShutdown);
|
||||
|
||||
if (!mCCRunner) {
|
||||
mCCRunner = IdleTaskRunner::Create(
|
||||
CCRunnerFired, "EnsureCCRunner::CCRunnerFired", 0,
|
||||
aDelay.ToMilliseconds(), aBudget.ToMilliseconds(), true,
|
||||
[this] { return mDidShutdown; });
|
||||
} else {
|
||||
mCCRunner->SetMinimumUsefulBudget(aBudget.ToMilliseconds());
|
||||
nsIEventTarget* target = mozilla::GetCurrentEventTarget();
|
||||
if (target) {
|
||||
mCCRunner->SetTimer(aDelay.ToMilliseconds(), target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCGCScheduler::KillCCRunner() {
|
||||
UnblockCC();
|
||||
DeactivateCCRunner();
|
||||
if (mCCRunner) {
|
||||
mCCRunner->Cancel();
|
||||
mCCRunner = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -121,6 +121,8 @@ class CCGCScheduler {
|
||||
// "suspected" of being members of cyclic garbage.
|
||||
static inline uint32_t SuspectedCCObjects();
|
||||
|
||||
static bool CCRunnerFired(TimeStamp aDeadline);
|
||||
|
||||
// Parameter setting
|
||||
|
||||
void SetActiveIntersliceGCBudget(TimeDuration aDuration) {
|
||||
@@ -151,6 +153,9 @@ class CCGCScheduler {
|
||||
void KillShrinkingGCTimer();
|
||||
void KillFullGCTimer();
|
||||
void KillGCRunner();
|
||||
void KillCCRunner();
|
||||
|
||||
void EnsureCCRunner(TimeDuration aDelay, TimeDuration aBudget);
|
||||
|
||||
// State modification
|
||||
|
||||
@@ -342,6 +347,10 @@ class CCGCScheduler {
|
||||
};
|
||||
|
||||
void InitCCRunnerStateMachine(CCRunnerState initialState) {
|
||||
if (mCCRunner) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The state machine should always have been deactivated after the previous
|
||||
// collection, however far that collection may have gone.
|
||||
MOZ_ASSERT(mCCRunnerState == CCRunnerState::Inactive,
|
||||
@@ -412,6 +421,7 @@ class CCGCScheduler {
|
||||
|
||||
public: // XXX
|
||||
RefPtr<IdleTaskRunner> mGCRunner;
|
||||
RefPtr<IdleTaskRunner> mCCRunner;
|
||||
|
||||
private:
|
||||
nsITimer* mShrinkingGCTimer = nullptr;
|
||||
|
||||
@@ -92,8 +92,6 @@ using namespace mozilla::dom;
|
||||
# undef CompareString
|
||||
#endif
|
||||
|
||||
static StaticRefPtr<IdleTaskRunner> sCCRunner;
|
||||
|
||||
static JS::GCSliceCallback sPrevGCSliceCallback;
|
||||
|
||||
static bool sIncrementalCC = false;
|
||||
@@ -275,7 +273,7 @@ static TimeDuration GetCollectionTimeDelta() {
|
||||
|
||||
static void KillTimers() {
|
||||
sScheduler.KillShrinkingGCTimer();
|
||||
nsJSContext::KillCCRunner();
|
||||
sScheduler.KillCCRunner();
|
||||
sScheduler.KillFullGCTimer();
|
||||
sScheduler.KillGCRunner();
|
||||
}
|
||||
@@ -1485,18 +1483,16 @@ void nsJSContext::BeginCycleCollectionCallback() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sCCRunner) {
|
||||
sScheduler.InitCCRunnerStateMachine(
|
||||
mozilla::CCGCScheduler::CCRunnerState::CycleCollecting);
|
||||
}
|
||||
EnsureCCRunner(kICCIntersliceDelay, kIdleICCSliceBudget);
|
||||
sScheduler.InitCCRunnerStateMachine(
|
||||
mozilla::CCGCScheduler::CCRunnerState::CycleCollecting);
|
||||
sScheduler.EnsureCCRunner(kICCIntersliceDelay, kIdleICCSliceBudget);
|
||||
}
|
||||
|
||||
// static
|
||||
void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsJSContext::KillCCRunner();
|
||||
sScheduler.KillCCRunner();
|
||||
|
||||
// Update timing information for the current slice before we log it, if
|
||||
// we previously called PrepareForCycleCollectionSlice(). During shutdown
|
||||
@@ -1532,7 +1528,8 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||
sCCStats.Clear();
|
||||
}
|
||||
|
||||
static bool CCRunnerFired(TimeStamp aDeadline) {
|
||||
/* static */
|
||||
bool CCGCScheduler::CCRunnerFired(TimeStamp aDeadline) {
|
||||
bool didDoWork = false;
|
||||
|
||||
// The CC/GC scheduler (sScheduler) decides what action(s) to take during
|
||||
@@ -1572,7 +1569,7 @@ static bool CCRunnerFired(TimeStamp aDeadline) {
|
||||
case CCRunnerAction::StopRunning:
|
||||
// End this CC, either because we have run a cycle collection slice, or
|
||||
// because a CC is no longer needed.
|
||||
nsJSContext::KillCCRunner();
|
||||
sScheduler.KillCCRunner();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1584,24 +1581,6 @@ static bool CCRunnerFired(TimeStamp aDeadline) {
|
||||
return didDoWork;
|
||||
}
|
||||
|
||||
// static
|
||||
void nsJSContext::EnsureCCRunner(TimeDuration aDelay, TimeDuration aBudget) {
|
||||
MOZ_ASSERT(!sShuttingDown);
|
||||
|
||||
if (!sCCRunner) {
|
||||
sCCRunner = IdleTaskRunner::Create(
|
||||
CCRunnerFired, "EnsureCCRunner::CCRunnerFired", 0,
|
||||
aDelay.ToMilliseconds(), aBudget.ToMilliseconds(), true,
|
||||
[] { return sShuttingDown; });
|
||||
} else {
|
||||
sCCRunner->SetMinimumUsefulBudget(aBudget.ToMilliseconds());
|
||||
nsIEventTarget* target = mozilla::GetCurrentEventTarget();
|
||||
if (target) {
|
||||
sCCRunner->SetTimer(aDelay.ToMilliseconds(), target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsJSContext::HasHadCleanupSinceLastGC() {
|
||||
return sScheduler.IsEarlyForgetSkippable(1);
|
||||
@@ -1626,8 +1605,8 @@ void nsJSContext::RunNextCollectorTimer(JS::GCReason aReason,
|
||||
if (sScheduler.mGCRunner) {
|
||||
sScheduler.SetWantMajorGC(aReason);
|
||||
runner = sScheduler.mGCRunner;
|
||||
} else if (sCCRunner) {
|
||||
runner = sCCRunner;
|
||||
} else if (sScheduler.mCCRunner) {
|
||||
runner = sScheduler.mCCRunner;
|
||||
}
|
||||
|
||||
if (runner) {
|
||||
@@ -1715,7 +1694,7 @@ void nsJSContext::PokeGC(JS::GCReason aReason, JSObject* aObj,
|
||||
|
||||
sScheduler.SetWantMajorGC(aReason);
|
||||
|
||||
if (sCCRunner) {
|
||||
if (sScheduler.mCCRunner) {
|
||||
// Make sure CC is called regardless of the size of the purple buffer, and
|
||||
// GC after it.
|
||||
sScheduler.EnsureCCThenGC();
|
||||
@@ -1774,7 +1753,7 @@ void nsJSContext::LowMemoryGC() {
|
||||
|
||||
// static
|
||||
void nsJSContext::MaybePokeCC() {
|
||||
if (sCCRunner || sShuttingDown) {
|
||||
if (sScheduler.mCCRunner || sShuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1782,21 +1761,11 @@ void nsJSContext::MaybePokeCC() {
|
||||
// We can kill some objects before running forgetSkippable.
|
||||
nsCycleCollector_dispatchDeferredDeletion();
|
||||
|
||||
if (!sCCRunner) {
|
||||
if (!sScheduler.mCCRunner) {
|
||||
sScheduler.InitCCRunnerStateMachine(
|
||||
mozilla::CCGCScheduler::CCRunnerState::ReducePurple);
|
||||
}
|
||||
EnsureCCRunner(kCCSkippableDelay, kForgetSkippableSliceDuration);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void nsJSContext::KillCCRunner() {
|
||||
sScheduler.UnblockCC();
|
||||
sScheduler.DeactivateCCRunner();
|
||||
if (sCCRunner) {
|
||||
sCCRunner->Cancel();
|
||||
sCCRunner = nullptr;
|
||||
sScheduler.EnsureCCRunner(kCCSkippableDelay, kForgetSkippableSliceDuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,9 +111,6 @@ class nsJSContext : public nsIScriptContext {
|
||||
static void LowMemoryGC();
|
||||
|
||||
static void MaybePokeCC();
|
||||
static void EnsureCCRunner(mozilla::TimeDuration aDelay,
|
||||
mozilla::TimeDuration aBudget);
|
||||
static void KillCCRunner();
|
||||
|
||||
// Calling LikelyShortLivingObjectCreated() makes a GC more likely.
|
||||
static void LikelyShortLivingObjectCreated();
|
||||
|
||||
Reference in New Issue
Block a user