Bug 822849 - Don't run CC/GC timers during shutdown, r=mccr8

--HG--
extra : rebase_source : 173e02106457b6867db8c4cf734a93366f4b31dd
This commit is contained in:
Olli Pettay 2013-01-22 21:17:48 +02:00
parent acb8bfaff9
commit e5d7c86f9b

View File

@ -186,7 +186,7 @@ static PRTime sFirstCollectionTime;
static bool sIsInitialized;
static bool sDidShutdown;
static bool sShuttingDown;
static int32_t sContextCount;
static PRTime sMaxScriptRunTime;
@ -194,7 +194,7 @@ static PRTime sMaxChromeScriptRunTime;
static nsIScriptSecurityManager *sSecurityManager;
// nsMemoryPressureObserver observes the memory-pressure notifications
// nsJSEnvironmentObserver observes the memory-pressure notifications
// and forces a garbage collection and cycle collection when it happens, if
// the appropriate pref is set.
@ -211,26 +211,40 @@ GetCollectionTimeDelta()
return 0;
}
class nsMemoryPressureObserver MOZ_FINAL : public nsIObserver
static void
KillTimers()
{
nsJSContext::KillGCTimer();
nsJSContext::KillShrinkGCBuffersTimer();
nsJSContext::KillCCTimer();
nsJSContext::KillFullGCTimer();
nsJSContext::KillInterSliceGCTimer();
}
class nsJSEnvironmentObserver MOZ_FINAL : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
};
NS_IMPL_ISUPPORTS1(nsMemoryPressureObserver, nsIObserver)
NS_IMPL_ISUPPORTS1(nsJSEnvironmentObserver, nsIObserver)
NS_IMETHODIMP
nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
const PRUnichar* aData)
{
if (sGCOnMemoryPressure) {
if (sGCOnMemoryPressure && !nsCRT::strcmp(aTopic, "memory-pressure")) {
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::NonCompartmentGC,
nsJSContext::ShrinkingGC);
nsJSContext::CycleCollectNow();
} else if (!nsCRT::strcmp(aTopic, "quit-application")) {
sShuttingDown = true;
KillTimers();
}
return NS_OK;
}
@ -3067,7 +3081,7 @@ nsJSContext::LoadEnd()
void
nsJSContext::PokeGC(js::gcreason::Reason aReason, int aDelay)
{
if (sGCTimer) {
if (sGCTimer || sShuttingDown) {
// There's already a timer for GC'ing, just return
return;
}
@ -3096,7 +3110,7 @@ nsJSContext::PokeGC(js::gcreason::Reason aReason, int aDelay)
void
nsJSContext::PokeShrinkGCBuffers()
{
if (sShrinkGCBuffersTimer) {
if (sShrinkGCBuffersTimer || sShuttingDown) {
return;
}
@ -3116,7 +3130,7 @@ nsJSContext::PokeShrinkGCBuffers()
void
nsJSContext::MaybePokeCC()
{
if (sCCTimer || sDidShutdown) {
if (sCCTimer || sShuttingDown) {
return;
}
@ -3259,11 +3273,13 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
// The GC has more work to do, so schedule another GC slice.
if (aProgress == js::GC_SLICE_END) {
nsJSContext::KillInterSliceGCTimer();
CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
sInterSliceGCTimer->InitWithFuncCallback(InterSliceGCTimerFired,
NULL,
NS_INTERSLICE_GC_DELAY,
nsITimer::TYPE_ONE_SHOT);
if (!sShuttingDown) {
CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
sInterSliceGCTimer->InitWithFuncCallback(InterSliceGCTimerFired,
NULL,
NS_INTERSLICE_GC_DELAY,
nsITimer::TYPE_ONE_SHOT);
}
}
if (aProgress == js::GC_CYCLE_END) {
@ -3277,7 +3293,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
if (aDesc.isCompartment) {
++sCompartmentGCCount;
if (!sFullGCTimer) {
if (!sFullGCTimer && !sShuttingDown) {
CallCreateInstance("@mozilla.org/timer;1", &sFullGCTimer);
js::gcreason::Reason reason = js::gcreason::FULL_GC_TIMER;
sFullGCTimer->InitWithFuncCallback(FullGCTimerFired,
@ -3403,6 +3419,7 @@ nsJSRuntime::Startup()
sRuntime = nullptr;
sIsInitialized = false;
sDidShutdown = false;
sShuttingDown = false;
sContextCount = 0;
sSecurityManager = nullptr;
}
@ -3719,9 +3736,9 @@ nsJSRuntime::Init()
"javascript.options.gc_on_memory_pressure",
true);
nsIObserver* memPressureObserver = new nsMemoryPressureObserver();
NS_ENSURE_TRUE(memPressureObserver, NS_ERROR_OUT_OF_MEMORY);
obs->AddObserver(memPressureObserver, "memory-pressure", false);
nsIObserver* observer = new nsJSEnvironmentObserver();
obs->AddObserver(observer, "memory-pressure", false);
obs->AddObserver(observer, "quit-application", false);
sIsInitialized = true;
@ -3750,11 +3767,7 @@ nsJSRuntime::GetNameSpaceManager()
void
nsJSRuntime::Shutdown()
{
nsJSContext::KillGCTimer();
nsJSContext::KillShrinkGCBuffersTimer();
nsJSContext::KillCCTimer();
nsJSContext::KillFullGCTimer();
nsJSContext::KillInterSliceGCTimer();
KillTimers();
NS_IF_RELEASE(gNameSpaceManager);
@ -3766,6 +3779,7 @@ nsJSRuntime::Shutdown()
NS_IF_RELEASE(sSecurityManager);
}
sShuttingDown = true;
sDidShutdown = true;
}