author | Olli Pettay <Olli.Pettay@helsinki.fi> |
Tue, 22 Jan 2013 21:17:48 +0200 | |
changeset 119471 | 2876e73c9b6fa152ab8da2542adb4db678c13113 |
parent 119470 | 653199a8edea98b0eb8c6ec7c58c19260e3884cb |
child 119472 | 1bbce6c7e0069e732090dcb88adb771965ee8039 |
child 119532 | c2ae65f1d5705b2bda3f8f2dec95b4fedb86979b |
push id | 24206 |
push user | opettay@mozilla.com |
push date | Tue, 22 Jan 2013 20:35:02 +0000 |
treeherder | mozilla-central@2876e73c9b6f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 822849 |
milestone | 21.0a1 |
first release with | nightly linux32
2876e73c9b6f
/
21.0a1
/
20130123030907
/
files
nightly linux64
2876e73c9b6f
/
21.0a1
/
20130123030907
/
files
nightly mac
2876e73c9b6f
/
21.0a1
/
20130123030907
/
files
nightly win32
2876e73c9b6f
/
21.0a1
/
20130123030907
/
files
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
21.0a1
/
20130123030907
/
pushlog to previous
nightly linux64
21.0a1
/
20130123030907
/
pushlog to previous
nightly mac
21.0a1
/
20130123030907
/
pushlog to previous
nightly win32
21.0a1
/
20130123030907
/
pushlog to previous
|
--- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -181,61 +181,75 @@ JSRuntime *nsJSRuntime::sRuntime; static const char kJSRuntimeServiceContractID[] = "@mozilla.org/js/xpc/RuntimeService;1"; static PRTime sFirstCollectionTime; static bool sIsInitialized; static bool sDidShutdown; - +static bool sShuttingDown; static int32_t sContextCount; static PRTime sMaxScriptRunTime; 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. static bool sGCOnMemoryPressure; static PRTime GetCollectionTimeDelta() { PRTime now = PR_Now(); if (sFirstCollectionTime) { return now - sFirstCollectionTime; } sFirstCollectionTime = now; 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; } class nsRootedJSValueArray { public: explicit nsRootedJSValueArray(JSContext *cx) : avr(cx, vals.Length(), vals.Elements()) {} bool SetCapacity(JSContext *cx, size_t capacity) { @@ -3062,17 +3076,17 @@ nsJSContext::LoadEnd() sLoadingInProgress = false; PokeGC(js::gcreason::LOAD_END); } // static 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; } CallCreateInstance("@mozilla.org/timer;1", &sGCTimer); if (!sGCTimer) { // Failed to create timer (probably because we're in XPCOM shutdown) @@ -3091,17 +3105,17 @@ nsJSContext::PokeGC(js::gcreason::Reason first = false; } // static void nsJSContext::PokeShrinkGCBuffers() { - if (sShrinkGCBuffersTimer) { + if (sShrinkGCBuffersTimer || sShuttingDown) { return; } CallCreateInstance("@mozilla.org/timer;1", &sShrinkGCBuffersTimer); if (!sShrinkGCBuffersTimer) { // Failed to create timer (probably because we're in XPCOM shutdown) return; @@ -3111,17 +3125,17 @@ nsJSContext::PokeShrinkGCBuffers() NS_SHRINK_GC_BUFFERS_DELAY, nsITimer::TYPE_ONE_SHOT); } // static void nsJSContext::MaybePokeCC() { - if (sCCTimer || sDidShutdown) { + if (sCCTimer || sShuttingDown) { return; } if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) { sCCTimerFireCount = 0; CallCreateInstance("@mozilla.org/timer;1", &sCCTimer); if (!sCCTimer) { return; @@ -3254,35 +3268,37 @@ DOMGCSliceCallback(JSRuntime *aRt, js::G nsJSContext::KillShrinkGCBuffersTimer(); } else if (aProgress == js::GC_CYCLE_END) { sCCLockedOut = false; } // 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) { // May need to kill the inter-slice GC timer nsJSContext::KillInterSliceGCTimer(); sCCollectedWaitingForGC = 0; sCleanupsSinceLastGC = 0; sNeedsFullCC = true; nsJSContext::MaybePokeCC(); 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, reinterpret_cast<void *>(reason), NS_FULL_GC_DELAY, nsITimer::TYPE_ONE_SHOT); } } else { @@ -3398,16 +3414,17 @@ nsJSRuntime::Startup() sPostGCEventsToConsole = false; sDisableExplicitCompartmentGC = false; sNeedsFullCC = false; gNameSpaceManager = nullptr; sRuntimeService = nullptr; sRuntime = nullptr; sIsInitialized = false; sDidShutdown = false; + sShuttingDown = false; sContextCount = 0; sSecurityManager = nullptr; } static int MaxScriptRunTimePrefChangedCallback(const char *aPrefName, void *aClosure) { // Default limit on script run time to 10 seconds. 0 means let @@ -3714,19 +3731,19 @@ nsJSRuntime::Init() nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (!obs) return NS_ERROR_FAILURE; Preferences::AddBoolVarCache(&sGCOnMemoryPressure, "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; return NS_OK; } //static nsScriptNameSpaceManager* @@ -3745,32 +3762,29 @@ nsJSRuntime::GetNameSpaceManager() return gNameSpaceManager; } /* static */ void nsJSRuntime::Shutdown() { - nsJSContext::KillGCTimer(); - nsJSContext::KillShrinkGCBuffersTimer(); - nsJSContext::KillCCTimer(); - nsJSContext::KillFullGCTimer(); - nsJSContext::KillInterSliceGCTimer(); + KillTimers(); NS_IF_RELEASE(gNameSpaceManager); if (!sContextCount) { // We're being shutdown, and there are no more contexts // alive, release the JS runtime service and the security manager. NS_IF_RELEASE(sRuntimeService); NS_IF_RELEASE(sSecurityManager); } + sShuttingDown = true; sDidShutdown = true; } // Script object mananagement - note duplicate implementation // in nsJSContext above... nsresult nsJSRuntime::HoldScriptObject(void* aScriptObject) {