Bug 624549, don't always do a global gc before cc, r=gal, a=approved
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Wed, 12 Jan 2011 22:44:41 +0200
changeset 60431 54184cfa6f0e458352f455144430c564bddb1a0a
parent 60430 de5d3839b7e50c02d6dfd8408da20b2245349f68
child 60432 b0fe7e0df71af70eefc367aa9c336e1c243a78ac
push id17987
push useropettay@mozilla.com
push dateThu, 13 Jan 2011 07:33:09 +0000
treeherdermozilla-central@54184cfa6f0e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal, approved
bugs624549
milestone2.0b10pre
first release with
nightly linux32
54184cfa6f0e / 4.0b10pre / 20110113030355 / files
nightly linux64
54184cfa6f0e / 4.0b10pre / 20110113030355 / files
nightly mac
54184cfa6f0e / 4.0b10pre / 20110113030355 / files
nightly win32
54184cfa6f0e / 4.0b10pre / 20110113030355 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 624549, don't always do a global gc before cc, r=gal, a=approved
dom/base/nsDOMWindowUtils.cpp
dom/base/nsJSEnvironment.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -650,16 +650,19 @@ nsDOMWindowUtils::GarbageCollect(nsICycl
 {
   // Always permit this in debug builds.
 #ifndef DEBUG
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 #endif
 
+  if (nsContentUtils::XPConnect()) {
+    nsContentUtils::XPConnect()->GarbageCollect();
+  }
   nsJSContext::CC(aListener);
 
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsDOMWindowUtils::ProcessUpdates()
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -164,24 +164,26 @@ static PRLogModuleInfo* gJSDiagnostics;
 // is multiplied with this number.
 #define NS_PROBABILITY_MULTIPLIER   3
 // Cycle collector is never called more often than every NS_MIN_CC_INTERVAL
 // milliseconds. Exceptions are low memory situation and memory pressure
 // notification.
 #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
 
 static PRUint32 sDelayedCCollectCount;
 static PRUint32 sCCollectCount;
 static PRBool sUserIsActive;
 static PRTime sPreviousCCTime;
 static PRUint32 sCollectedObjectsCounts;
@@ -266,17 +268,17 @@ nsUserActivityObserver::Observe(nsISuppo
   ++mUserActivityCounter;
   if (!strcmp(aTopic, "user-interaction-inactive")) {
 #ifdef DEBUG_smaug
     printf("user-interaction-inactive\n");
 #endif
     if (sUserIsActive) {
       sUserIsActive = PR_FALSE;
       if (!sGCTimer) {
-        nsJSContext::IntervalCC();
+        nsJSContext::MaybeCC(PR_FALSE);
         return NS_OK;
       }
     }
     higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_INACTIVE);
   } else if (!strcmp(aTopic, "user-interaction-active")) {
 #ifdef DEBUG_smaug
     printf("user-interaction-active\n");
 #endif
@@ -3605,62 +3607,64 @@ nsJSContext::SetGCOnDestruction(PRBool a
 NS_IMETHODIMP
 nsJSContext::ScriptExecuted()
 {
   ScriptEvaluated(!::JS_IsRunning(mContext));
 
   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)
 {
   NS_TIME_FUNCTION_MIN(1.0);
 
   ++sCCollectCount;
 #ifdef DEBUG_smaug
   printf("Will run cycle collector (%i), %lldms since previous.\n",
          sCCollectCount, (PR_Now() - sPreviousCCTime) / PR_USEC_PER_MSEC);
 #endif
   sPreviousCCTime = PR_Now();
   sDelayedCCollectCount = 0;
   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);
   sCCSuspectedCount = nsCycleCollector_suspectedCount();
   if (nsJSRuntime::sRuntime) {
     sSavedGCCount = JS_GetGCParameter(nsJSRuntime::sRuntime, JSGC_NUMBER);
   }
 #ifdef DEBUG_smaug
   printf("Collected %u objects, %u suspected objects, took %lldms\n",
          sCollectedObjectsCounts, sCCSuspectedCount,
          (PR_Now() - sPreviousCCTime) / PR_USEC_PER_MSEC);
 #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)
 {
   ++sDelayedCCollectCount;
 
   // Don't check suspected count if CC will be called anyway.
   if (sCCSuspectChanges <= NS_MIN_SUSPECT_CHANGES ||