diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index aabc07c4f3e..e761367fea1 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -655,6 +655,9 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener) } #endif + if (nsContentUtils::XPConnect()) { + nsContentUtils::XPConnect()->GarbageCollect(); + } nsJSContext::CC(aListener); return NS_OK; diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index ef34dd48e63..ff4f32787a1 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -169,14 +169,16 @@ static PRLogModuleInfo* gJSDiagnostics; #define NS_MIN_CC_INTERVAL 10000 // ms // If previous cycle collection collected more than this number of objects, // the next collection will happen somewhat soon. +// Also, if there are more than this number suspected objects, GC will be called +// right before CC, if it wasn't called after last CC. #define NS_COLLECTED_OBJECTS_LIMIT 5000 // CC will be called if GC has been called at least this number of times and // there are at least NS_MIN_SUSPECT_CHANGES new suspected objects. #define NS_MAX_GC_COUNT 5 -#define NS_MIN_SUSPECT_CHANGES 10 +#define NS_MIN_SUSPECT_CHANGES 100 // CC will be called if there are at least NS_MAX_SUSPECT_CHANGES new suspected // objects. -#define NS_MAX_SUSPECT_CHANGES 100 +#define NS_MAX_SUSPECT_CHANGES 1000 // if you add statics here, add them to the list in nsJSRuntime::Startup @@ -271,7 +273,7 @@ nsUserActivityObserver::Observe(nsISupports* aSubject, const char* aTopic, if (sUserIsActive) { sUserIsActive = PR_FALSE; if (!sGCTimer) { - nsJSContext::IntervalCC(); + nsJSContext::MaybeCC(PR_FALSE); return NS_OK; } } @@ -3610,6 +3612,21 @@ nsJSContext::ScriptExecuted() return NS_OK; } +static inline uint32 +GetGCRunsSinceLastCC() +{ + // To avoid crash if nsJSRuntime is not properly initialized. + // See the bug 474586 + if (!nsJSRuntime::sRuntime) + return 0; + + // Since JS_GetGCParameter() and sSavedGCCount are unsigned, the following + // gives the correct result even when the GC counter wraps around + // UINT32_MAX since the last call to JS_GetGCParameter(). + return JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER) - + sSavedGCCount; +} + //static void nsJSContext::CC(nsICycleCollectorListener *aListener) @@ -3626,7 +3643,9 @@ nsJSContext::CC(nsICycleCollectorListener *aListener) sCCSuspectChanges = 0; // nsCycleCollector_collect() no longer forces a JS garbage collection, // so we have to do it ourselves here. - if (nsContentUtils::XPConnect()) { + if (nsContentUtils::XPConnect() && + !GetGCRunsSinceLastCC() && + sCCSuspectedCount > NS_COLLECTED_OBJECTS_LIMIT) { nsContentUtils::XPConnect()->GarbageCollect(); } sCollectedObjectsCounts = nsCycleCollector_collect(aListener); @@ -3641,21 +3660,6 @@ nsJSContext::CC(nsICycleCollectorListener *aListener) #endif } -static inline uint32 -GetGCRunsSinceLastCC() -{ - // To avoid crash if nsJSRuntime is not properly initialized. - // See the bug 474586 - if (!nsJSRuntime::sRuntime) - return 0; - - // Since JS_GetGCParameter() and sSavedGCCount are unsigned, the following - // gives the correct result even when the GC counter wraps around - // UINT32_MAX since the last call to JS_GetGCParameter(). - return JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER) - - sSavedGCCount; -} - //static PRBool nsJSContext::MaybeCC(PRBool aHigherProbability)