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