Bug 730753, call CC after full GC, r=mccr8, a=akeybl
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 28 Feb 2012 12:40:36 +0200
changeset 88490 04c1060b1a978ca9cef937b92510ac19fc26bc28
parent 88489 41a90075bca830a121ed08938c58ba9fc5360942
child 88491 8655ba93f381cd743cf077864e60ee9653bc1017
push idunknown
push userunknown
push dateunknown
reviewersmccr8, akeybl
bugs730753
milestone12.0a2
Bug 730753, call CC after full GC, r=mccr8, a=akeybl
dom/base/nsJSEnvironment.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -170,16 +170,17 @@ static PRUint32 sCCTimerFireCount = 0;
 static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
 static PRUint32 sMaxForgetSkippableTime = 0;
 static PRUint32 sTotalForgetSkippableTime = 0;
 static PRUint32 sRemovedPurples = 0;
 static PRUint32 sForgetSkippableBeforeCC = 0;
 static PRUint32 sPreviousSuspectedCount = 0;
 
 static bool sCleanupSinceLastGC = true;
+static bool sNeedsFullCC = false;
 
 nsScriptNameSpaceManager *gNameSpaceManager;
 
 static nsIJSRuntimeService *sRuntimeService;
 JSRuntime *nsJSRuntime::sRuntime;
 
 static const char kJSRuntimeServiceContractID[] =
   "@mozilla.org/js/xpc/RuntimeService;1";
@@ -3315,16 +3316,17 @@ nsJSContext::CycleCollectNow(nsICycleCol
     }
   }
   sMinForgetSkippableTime = PR_UINT32_MAX;
   sMaxForgetSkippableTime = 0;
   sTotalForgetSkippableTime = 0;
   sRemovedPurples = 0;
   sForgetSkippableBeforeCC = 0;
   sCleanupSinceLastGC = true;
+  sNeedsFullCC = false;
 }
 
 // static
 void
 GCTimerFired(nsITimer *aTimer, void *aClosure)
 {
   NS_RELEASE(sGCTimer);
 
@@ -3372,17 +3374,18 @@ CCTimerFired(nsITimer *aTimer, void *aCl
       }
       sTotalForgetSkippableTime += delta;
       sRemovedPurples += (suspected - sPreviousSuspectedCount);
       ++sForgetSkippableBeforeCC;
     }
   } else {
     sPreviousSuspectedCount = 0;
     nsJSContext::KillCCTimer();
-    if (nsCycleCollector_suspectedCount() > 500 ||
+    if (sNeedsFullCC ||
+        nsCycleCollector_suspectedCount() > 500 ||
         sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
       nsJSContext::CycleCollectNow();
     }
   }
 }
 
 // static
 bool
@@ -3468,17 +3471,18 @@ nsJSContext::PokeShrinkGCBuffers()
 // static
 void
 nsJSContext::MaybePokeCC()
 {
   if (sCCTimer || sDidShutdown) {
     return;
   }
 
-  if (nsCycleCollector_suspectedCount() > 100 ||
+  if (sNeedsFullCC ||
+      nsCycleCollector_suspectedCount() > 100 ||
       sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
     sCCTimerFireCount = 0;
     CallCreateInstance("@mozilla.org/timer;1", &sCCTimer);
     if (!sCCTimer) {
       return;
     }
     sCCTimer->InitWithFuncCallback(CCTimerFired, nsnull,
                                    NS_CC_SKIPPABLE_DELAY,
@@ -3566,16 +3570,17 @@ DOMGCFinishedCallback(JSRuntime *rt, JSC
 
       // We poked the GC, so we can kill any pending CC here.
       nsJSContext::KillCCTimer();
     }
   } else {
     // If this was a full GC, poke the CC to run soon.
     if (!comp) {
       sGCHasRun = true;
+      sNeedsFullCC = true;
       nsJSContext::MaybePokeCC();
     }
   }
 
   // If we didn't end up scheduling a GC, make sure that we release GC buffers
   // soon after canceling previous shrinking attempt 
   nsJSContext::KillShrinkGCBuffersTimer();
   if (!sGCTimer) {
@@ -3674,16 +3679,17 @@ nsJSRuntime::Startup()
   // initialize all our statics, so that we can restart XPCOM
   sGCTimer = sCCTimer = nsnull;
   sGCHasRun = false;
   sLastCCEndTime = 0;
   sPendingLoadCount = 0;
   sLoadingInProgress = false;
   sCCollectedWaitingForGC = 0;
   sPostGCEventsToConsole = false;
+  sNeedsFullCC = false;
   gNameSpaceManager = nsnull;
   sRuntimeService = nsnull;
   sRuntime = nsnull;
   sIsInitialized = false;
   sDidShutdown = false;
   sContextCount = 0;
   sSecurityManager = nsnull;
 }