Bug 730753, call CC after full GC, r=mccr8
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Mon, 27 Feb 2012 16:49:59 +0200
changeset 90697 8ea5c983743fbb7d6bcac41acea8f124eaf15e73
parent 90696 53e10e2b327b64bf19d03902d3ca5e20feea6c99
child 90698 34c94825a18325b9b40fea1c884669683de78770
child 92575 0d4686de546aaf4755af9a95d6b90fd1af0d9a6c
child 112188 c757b4a747a5d92e54403998abe229cbff299a78
push idunknown
push userunknown
push dateunknown
reviewersmccr8
bugs730753
milestone13.0a1
Bug 730753, call CC after full GC, r=mccr8
dom/base/nsJSEnvironment.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -176,16 +176,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";
@@ -3335,16 +3336,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);
 
@@ -3390,17 +3392,18 @@ CCTimerFired(nsITimer *aTimer, void *aCl
       sMaxForgetSkippableTime = delta;
     }
     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
@@ -3488,17 +3491,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,
@@ -3603,16 +3607,17 @@ DOMGCSliceCallback(JSRuntime *aRt, js::G
 
         // 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 (!aDesc.isCompartment) {
         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) {
@@ -3716,16 +3721,17 @@ nsJSRuntime::Startup()
   sGCTimer = sCCTimer = nsnull;
   sGCHasRun = false;
   sCCLockedOut = 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;
 }