зеркало из https://github.com/mozilla/gecko-dev.git
Bug 937960, part 2 - Add ICC slice timer and scheduling. r=smaug
This commit is contained in:
Родитель
7db6607fa1
Коммит
9d296c7f10
|
@ -121,6 +121,9 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||||
|
|
||||||
#define NS_CC_SKIPPABLE_DELAY 400 // ms
|
#define NS_CC_SKIPPABLE_DELAY 400 // ms
|
||||||
|
|
||||||
|
// Maximum amount of time that should elapse between incremental CC slices
|
||||||
|
static const int64_t kICCIntersliceDelay = 32; // ms
|
||||||
|
|
||||||
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
|
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
|
||||||
// objects in the purple buffer.
|
// objects in the purple buffer.
|
||||||
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
|
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
|
||||||
|
@ -144,6 +147,7 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||||
static nsITimer *sGCTimer;
|
static nsITimer *sGCTimer;
|
||||||
static nsITimer *sShrinkGCBuffersTimer;
|
static nsITimer *sShrinkGCBuffersTimer;
|
||||||
static nsITimer *sCCTimer;
|
static nsITimer *sCCTimer;
|
||||||
|
static nsITimer *sICCTimer;
|
||||||
static nsITimer *sFullGCTimer;
|
static nsITimer *sFullGCTimer;
|
||||||
static nsITimer *sInterSliceGCTimer;
|
static nsITimer *sInterSliceGCTimer;
|
||||||
|
|
||||||
|
@ -223,6 +227,7 @@ KillTimers()
|
||||||
nsJSContext::KillGCTimer();
|
nsJSContext::KillGCTimer();
|
||||||
nsJSContext::KillShrinkGCBuffersTimer();
|
nsJSContext::KillShrinkGCBuffersTimer();
|
||||||
nsJSContext::KillCCTimer();
|
nsJSContext::KillCCTimer();
|
||||||
|
nsJSContext::KillICCTimer();
|
||||||
nsJSContext::KillFullGCTimer();
|
nsJSContext::KillFullGCTimer();
|
||||||
nsJSContext::KillInterSliceGCTimer();
|
nsJSContext::KillInterSliceGCTimer();
|
||||||
}
|
}
|
||||||
|
@ -2082,6 +2087,30 @@ nsJSContext::ScheduledCycleCollectNow()
|
||||||
nsCycleCollector_scheduledCollect();
|
nsCycleCollector_scheduledCollect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ICCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
if (sDidShutdown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore ICC timer fires during IGC. Running ICC during an IGC will cause us
|
||||||
|
// to synchronously finish the GC, which is bad.
|
||||||
|
|
||||||
|
if (sCCLockedOut) {
|
||||||
|
PRTime now = PR_Now();
|
||||||
|
if (sCCLockedOutTime == 0) {
|
||||||
|
sCCLockedOutTime = now;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (now - sCCLockedOutTime < NS_MAX_CC_LOCKEDOUT_TIME) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsJSContext::ScheduledCycleCollectNow();
|
||||||
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void
|
void
|
||||||
nsJSContext::BeginCycleCollectionCallback()
|
nsJSContext::BeginCycleCollectionCallback()
|
||||||
|
@ -2092,6 +2121,20 @@ nsJSContext::BeginCycleCollectionCallback()
|
||||||
gCCStats.mSuspected = nsCycleCollector_suspectedCount();
|
gCCStats.mSuspected = nsCycleCollector_suspectedCount();
|
||||||
|
|
||||||
KillCCTimer();
|
KillCCTimer();
|
||||||
|
|
||||||
|
MOZ_ASSERT(!sICCTimer, "Tried to create a new ICC timer when one already existed.");
|
||||||
|
|
||||||
|
if (!sIncrementalCC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallCreateInstance("@mozilla.org/timer;1", &sICCTimer);
|
||||||
|
if (sICCTimer) {
|
||||||
|
sICCTimer->InitWithFuncCallback(ICCTimerFired,
|
||||||
|
nullptr,
|
||||||
|
kICCIntersliceDelay,
|
||||||
|
nsITimer::TYPE_REPEATING_SLACK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
|
@ -2100,6 +2143,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
nsJSContext::KillICCTimer();
|
||||||
|
|
||||||
sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed;
|
sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed;
|
||||||
|
|
||||||
// If we collected a substantial amount of cycles, poke the GC since more objects
|
// If we collected a substantial amount of cycles, poke the GC since more objects
|
||||||
|
@ -2298,7 +2343,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||||
|
|
||||||
// During early timer fires, we only run forgetSkippable. During the first
|
// During early timer fires, we only run forgetSkippable. During the first
|
||||||
// late timer fire, we decide if we are going to have a second and final
|
// late timer fire, we decide if we are going to have a second and final
|
||||||
// late timer fire, where we may run the CC.
|
// late timer fire, where we may begin to run the CC.
|
||||||
const uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
|
const uint32_t numEarlyTimerFires = ccDelay / NS_CC_SKIPPABLE_DELAY - 2;
|
||||||
bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires;
|
bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires;
|
||||||
uint32_t suspected = nsCycleCollector_suspectedCount();
|
uint32_t suspected = nsCycleCollector_suspectedCount();
|
||||||
|
@ -2426,7 +2471,7 @@ nsJSContext::PokeShrinkGCBuffers()
|
||||||
void
|
void
|
||||||
nsJSContext::MaybePokeCC()
|
nsJSContext::MaybePokeCC()
|
||||||
{
|
{
|
||||||
if (sCCTimer || sShuttingDown || !sHasRunGC) {
|
if (sCCTimer || sICCTimer || sShuttingDown || !sHasRunGC) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2498,6 +2543,19 @@ nsJSContext::KillCCTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void
|
||||||
|
nsJSContext::KillICCTimer()
|
||||||
|
{
|
||||||
|
sCCLockedOutTime = 0;
|
||||||
|
|
||||||
|
if (sICCTimer) {
|
||||||
|
sICCTimer->Cancel();
|
||||||
|
|
||||||
|
NS_RELEASE(sICCTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsJSContext::GC(JS::gcreason::Reason aReason)
|
nsJSContext::GC(JS::gcreason::Reason aReason)
|
||||||
{
|
{
|
||||||
|
@ -2659,7 +2717,7 @@ void
|
||||||
mozilla::dom::StartupJSEnvironment()
|
mozilla::dom::StartupJSEnvironment()
|
||||||
{
|
{
|
||||||
// initialize all our statics, so that we can restart XPCOM
|
// initialize all our statics, so that we can restart XPCOM
|
||||||
sGCTimer = sFullGCTimer = sCCTimer = nullptr;
|
sGCTimer = sFullGCTimer = sCCTimer = sICCTimer = nullptr;
|
||||||
sCCLockedOut = false;
|
sCCLockedOut = false;
|
||||||
sCCLockedOutTime = 0;
|
sCCLockedOutTime = 0;
|
||||||
sLastCCEndTime = 0;
|
sLastCCEndTime = 0;
|
||||||
|
|
|
@ -117,6 +117,7 @@ public:
|
||||||
|
|
||||||
static void MaybePokeCC();
|
static void MaybePokeCC();
|
||||||
static void KillCCTimer();
|
static void KillCCTimer();
|
||||||
|
static void KillICCTimer();
|
||||||
static void KillFullGCTimer();
|
static void KillFullGCTimer();
|
||||||
static void KillInterSliceGCTimer();
|
static void KillInterSliceGCTimer();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче