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
Родитель d6a34e1cd6
Коммит 9d51d0bb41
1 изменённых файлов: 38 добавлений и 24 удалений

Просмотреть файл

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