Bug 965916 - Do an extra GC on memory pressure if it would be productive. r=smaug
authorAndrew McCreight <continuation@gmail.com>
Mon, 03 Feb 2014 07:31:11 -0800
changeset 166634 06095fccf046df3bcf7b835d1f9ef8c9e81ec0c7
parent 166633 ee98436d195d934c5e9aa765ed1589d606b57106
child 166635 ed88a1b7b429c57bf33ee20052db9bce4f8e1b72
push id4808
push userryanvm@gmail.com
push dateMon, 03 Feb 2014 23:16:15 +0000
treeherderfx-team@c150845d077d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs965916
milestone29.0a1
Bug 965916 - Do an extra GC on memory pressure if it would be productive. r=smaug
dom/base/nsJSEnvironment.cpp
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -233,16 +233,26 @@ KillTimers()
   nsJSContext::KillGCTimer();
   nsJSContext::KillShrinkGCBuffersTimer();
   nsJSContext::KillCCTimer();
   nsJSContext::KillICCTimer();
   nsJSContext::KillFullGCTimer();
   nsJSContext::KillInterSliceGCTimer();
 }
 
+// If we collected a substantial amount of cycles, poke the GC since more objects
+// might be unreachable now.
+static bool
+NeedsGCAfterCC()
+{
+  return sCCollectedWaitingForGC > 250 ||
+    sLikelyShortLivingObjectsNeedingGC > 2500 ||
+    sNeedsGCAfterCC;
+}
+
 class nsJSEnvironmentObserver MOZ_FINAL : public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 };
 
 NS_IMPL_ISUPPORTS1(nsJSEnvironmentObserver, nsIObserver)
@@ -258,16 +268,22 @@ nsJSEnvironmentObserver::Observe(nsISupp
       // slow and it likely won't help us anyway.
       return NS_OK;
     }
     nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
                                    nsJSContext::NonIncrementalGC,
                                    nsJSContext::NonCompartmentGC,
                                    nsJSContext::ShrinkingGC);
     nsJSContext::CycleCollectNow();
+    if (NeedsGCAfterCC()) {
+      nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
+                                     nsJSContext::NonIncrementalGC,
+                                     nsJSContext::NonCompartmentGC,
+                                     nsJSContext::ShrinkingGC);
+    }
   } else if (!nsCRT::strcmp(aTopic, "quit-application")) {
     sShuttingDown = true;
     KillTimers();
   }
 
   return NS_OK;
 }
 
@@ -2210,21 +2226,17 @@ nsJSContext::EndCycleCollectionCallback(
 
   nsJSContext::KillICCTimer();
 
   // Update timing information for the current slice before we log it.
   gCCStats.FinishCycleCollectionSlice();
 
   sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed;
 
-  // If we collected a substantial amount of cycles, poke the GC since more objects
-  // might be unreachable now.
-  if (sCCollectedWaitingForGC > 250 ||
-      sLikelyShortLivingObjectsNeedingGC > 2500 ||
-      sNeedsGCAfterCC) {
+  if (NeedsGCAfterCC()) {
     PokeGC(JS::gcreason::CC_WAITING);
   }
 
   TimeStamp endCCTime = TimeStamp::Now();
 
   // Log information about the CC via telemetry, JSON and the console.
   uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTime);
   Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FINISH_IGC, gCCStats.mAnyLockedOut);