diff --git a/content/base/src/nsCCUncollectableMarker.cpp b/content/base/src/nsCCUncollectableMarker.cpp index 432fec70f88a..decbeaff20de 100644 --- a/content/base/src/nsCCUncollectableMarker.cpp +++ b/content/base/src/nsCCUncollectableMarker.cpp @@ -317,7 +317,7 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic, // JS cleanup can be slow. Do it only if there has been a GC. bool cleanupJS = - !nsJSContext::CleanupSinceLastGC() && + nsJSContext::CleanupsSinceLastGC() == 0 && !strcmp(aTopic, "cycle-collector-forget-skippable"); bool prepareForCC = !strcmp(aTopic, "cycle-collector-begin"); diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index c27346195329..27625e5f8a7c 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -186,7 +186,7 @@ static PRUint32 sRemovedPurples = 0; static PRUint32 sForgetSkippableBeforeCC = 0; static PRUint32 sPreviousSuspectedCount = 0; -static bool sCleanupSinceLastGC = true; +static PRUint32 sCleanupsSinceLastGC = PR_UINT32_MAX; static bool sNeedsFullCC = false; nsScriptNameSpaceManager *gNameSpaceManager; @@ -2951,14 +2951,18 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener, PRUint32 suspected = nsCycleCollector_suspectedCount(); - for (PRInt32 i = 0; i < aExtraForgetSkippableCalls; ++i) { - nsCycleCollector_forgetSkippable(); + // nsCycleCollector_forgetSkippable may mark some gray js to black. + if (sCleanupsSinceLastGC < 2 && aExtraForgetSkippableCalls >= 0) { + for (;sCleanupsSinceLastGC < 2; ++sCleanupsSinceLastGC) { + nsCycleCollector_forgetSkippable(); + } } - // nsCycleCollector_forgetSkippable may mark some gray js to black. - if (!sCleanupSinceLastGC && aExtraForgetSkippableCalls >= 0) { + for (PRInt32 i = 0; i < aExtraForgetSkippableCalls; ++i) { nsCycleCollector_forgetSkippable(); + ++sCleanupsSinceLastGC; } + nsCycleCollectorResults ccResults; nsCycleCollector_collect(&ccResults, aListener); sCCollectedWaitingForGC += ccResults.mFreedRefCounted + ccResults.mFreedGCed; @@ -3062,7 +3066,6 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener, sTotalForgetSkippableTime = 0; sRemovedPurples = 0; sForgetSkippableBeforeCC = 0; - sCleanupSinceLastGC = true; sNeedsFullCC = false; } @@ -3098,7 +3101,7 @@ TimerFireForgetSkippable(PRUint32 aSuspected, bool aRemoveChildless) PRTime startTime = PR_Now(); nsCycleCollector_forgetSkippable(aRemoveChildless); sPreviousSuspectedCount = nsCycleCollector_suspectedCount(); - sCleanupSinceLastGC = true; + ++sCleanupsSinceLastGC; PRTime delta = PR_Now() - startTime; if (sMinForgetSkippableTime > delta) { sMinForgetSkippableTime = delta; @@ -3167,10 +3170,10 @@ CCTimerFired(nsITimer *aTimer, void *aClosure) } // static -bool -nsJSContext::CleanupSinceLastGC() +PRUint32 +nsJSContext::CleanupsSinceLastGC() { - return sCleanupSinceLastGC; + return sCleanupsSinceLastGC; } // static @@ -3389,7 +3392,7 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip nsJSContext::KillGCTimer(); sCCollectedWaitingForGC = 0; - sCleanupSinceLastGC = false; + sCleanupsSinceLastGC = 0; if (aDesc.isCompartment) { // If this is a compartment GC, restart it. We still want diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index aa2b3534683c..bf03a9a3215c 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -202,7 +202,7 @@ public: virtual void GC(js::gcreason::Reason aReason); - static bool CleanupSinceLastGC(); + static PRUint32 CleanupsSinceLastGC(); nsIScriptGlobalObject* GetCachedGlobalObject() {