Bug 935721, part 10 - Separate nsCycleCollector_collect and nsCycleCollector_scheduledCollect. r=smaug
authorAndrew McCreight <continuation@gmail.com>
Wed, 20 Nov 2013 14:35:17 -0800
changeset 156698 e597cdb674ea2a41d8616a0c8b28a73f69f4a845
parent 156697 e48c498dbe1814be0e49ac5ccd947f5516f5160f
child 156699 c7214775e476f174dc5a98ad93280d12ff9e8812
push id25684
push usercbook@mozilla.com
push dateThu, 21 Nov 2013 13:21:05 +0000
treeherdermozilla-central@7427eede548f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs935721
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 935721, part 10 - Separate nsCycleCollector_collect and nsCycleCollector_scheduledCollect. r=smaug
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/workers/RuntimeService.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/base/nsCycleCollector.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2011,28 +2011,20 @@ struct CycleCollectorStats
   uint32_t mMaxSkippableDuration;
 
   // True if we were locked out by the GC in any slice of the current CC.
   bool mAnyLockedOut;
 };
 
 CycleCollectorStats gCCStats;
 
-//static
-void
-nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
-                             int32_t aExtraForgetSkippableCalls,
-                             bool aManuallyTriggered)
+
+static void
+PrepareForCycleCollection(int32_t aExtraForgetSkippableCalls = 0)
 {
-  if (!NS_IsMainThread()) {
-    return;
-  }
-
-  PROFILER_LABEL("CC", "CycleCollectNow");
-
   gCCStats.mBeginSliceTime = PR_Now();
 
   // Before we begin the cycle collection, make sure there is no active GC.
   PRTime endGCTime;
   if (sCCLockedOut) {
     gCCStats.mAnyLockedOut = true;
     FinishAnyIncrementalGC();
     endGCTime = PR_Now();
@@ -2058,19 +2050,43 @@ nsJSContext::CycleCollectNow(nsICycleCol
 
     if (ranSyncForgetSkippable) {
       gCCStats.mMaxSkippableDuration =
         std::max(gCCStats.mMaxSkippableDuration, TimeBetween(endGCTime, PR_Now()));
       gCCStats.mRanSyncForgetSkippable = true;
     }
 
   }
-
-  nsCycleCollector_collect(aManuallyTriggered, aListener);
-
+}
+
+//static
+void
+nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
+                             int32_t aExtraForgetSkippableCalls)
+{
+  if (!NS_IsMainThread()) {
+    return;
+  }
+
+  PROFILER_LABEL("CC", "CycleCollectNow");
+  PrepareForCycleCollection(aExtraForgetSkippableCalls);
+  nsCycleCollector_collect(aListener);
+}
+
+//static
+void
+nsJSContext::ScheduledCycleCollectNow()
+{
+  if (!NS_IsMainThread()) {
+    return;
+  }
+
+  PROFILER_LABEL("CC", "ScheduledCycleCollectNow");
+  PrepareForCycleCollection();
+  nsCycleCollector_scheduledCollect();
 }
 
 //static
 void
 nsJSContext::BeginCycleCollectionCallback()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -2295,17 +2311,17 @@ CCTimerFired(nsITimer *aTimer, void *aCl
         // Our efforts to avoid a CC have failed, so we return to let the
         // timer fire once more to trigger a CC.
         return;
       }
     } else {
       // We are in the final timer fire and still meet the conditions for
       // triggering a CC. Let CycleCollectNow finish the current IGC, if any,
       // because that will allow us to include the GC time in the CC pause.
-      nsJSContext::CycleCollectNow(nullptr, 0, false);
+      nsJSContext::ScheduledCycleCollectNow();
     }
   } else if ((sPreviousSuspectedCount + 100) <= suspected) {
       // Only do a forget skippable if there are more than a few new objects.
       FireForgetSkippable(suspected, false);
   }
 
   if (isLateTimerFire) {
     ccDelay = NS_CC_DELAY;
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -99,18 +99,18 @@ public:
                                 IsIncremental aIncremental = NonIncrementalGC,
                                 IsCompartment aCompartment = NonCompartmentGC,
                                 IsShrinking aShrinking = NonShrinkingGC,
                                 int64_t aSliceMillis = 0);
   static void ShrinkGCBuffersNow();
   // If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
   // called even if the previous collection was GC.
   static void CycleCollectNow(nsICycleCollectorListener *aListener = nullptr,
-                              int32_t aExtraForgetSkippableCalls = 0,
-                              bool aManuallyTriggered = true);
+                              int32_t aExtraForgetSkippableCalls = 0);
+  static void ScheduledCycleCollectNow();
   static void BeginCycleCollectionCallback();
   static void EndCycleCollectionCallback(mozilla::CycleCollectorResults &aResults);
 
   static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
   static void KillGCTimer();
 
   static void PokeShrinkGCBuffers();
   static void KillShrinkGCBuffersTimer();
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -909,17 +909,17 @@ public:
     if (!mWorkerPrivate) {
       // We're shutting down, no need to do anything.
       return;
     }
 
     mWorkerPrivate->AssertIsOnWorkerThread();
 
     if (aStatus == JSGC_END) {
-      nsCycleCollector_collect(true, nullptr);
+      nsCycleCollector_collect(nullptr);
     }
   }
 
 private:
   WorkerPrivate* mWorkerPrivate;
 };
 
 class WorkerThreadRunnable : public nsRunnable
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -3165,29 +3165,39 @@ nsCycleCollector_doDeferredDeletion()
     MOZ_ASSERT(data);
     MOZ_ASSERT(data->mCollector);
     MOZ_ASSERT(data->mRuntime);
 
     return data->mCollector->FreeSnowWhite(false);
 }
 
 void
-nsCycleCollector_collect(bool aManuallyTriggered,
-                         nsICycleCollectorListener *aManualListener)
+nsCycleCollector_collect(nsICycleCollectorListener *aManualListener)
 {
     CollectorData *data = sCollectorData.get();
 
     // We should have started the cycle collector by now.
     MOZ_ASSERT(data);
     MOZ_ASSERT(data->mCollector);
 
     PROFILER_LABEL("CC", "nsCycleCollector_collect");
-
-    MOZ_ASSERT_IF(aManualListener, aManuallyTriggered);
-    data->mCollector->Collect(aManuallyTriggered ? ManualCC : ScheduledCC, aManualListener);
+    data->mCollector->Collect(ManualCC, aManualListener);
+}
+
+void
+nsCycleCollector_scheduledCollect()
+{
+    CollectorData *data = sCollectorData.get();
+
+    // We should have started the cycle collector by now.
+    MOZ_ASSERT(data);
+    MOZ_ASSERT(data->mCollector);
+
+    PROFILER_LABEL("CC", "nsCycleCollector_scheduledCollect");
+    data->mCollector->Collect(ScheduledCC, nullptr);
 }
 
 void
 nsCycleCollector_shutdown()
 {
     CollectorData *data = sCollectorData.get();
 
     if (data) {
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -33,18 +33,19 @@ typedef void (*CC_ForgetSkippableCallbac
 void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB);
 
 void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false,
                                       bool aAsyncSnowWhiteFreeing = false);
 
 void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false);
 bool nsCycleCollector_doDeferredDeletion();
 
-void nsCycleCollector_collect(bool aManuallyTriggered,
-                              nsICycleCollectorListener *aManualListener);
+void nsCycleCollector_collect(nsICycleCollectorListener *aManualListener);
+void nsCycleCollector_scheduledCollect();
+
 uint32_t nsCycleCollector_suspectedCount();
 void nsCycleCollector_shutdown();
 
 // Helpers for interacting with JS
 void nsCycleCollector_registerJSRuntime(mozilla::CycleCollectedJSRuntime *aRt);
 void nsCycleCollector_forgetJSRuntime();
 
 #define NS_CYCLE_COLLECTOR_LOGGER_CID \