Bug 913666, part 3 - Sink cycle collector listener selection into Collect. r=smaug
authorAndrew McCreight <continuation@gmail.com>
Tue, 10 Sep 2013 16:33:40 -0700
changeset 159378 1dab5dad3be9b4b92c66661286627fcbfda8c438
parent 159377 b7fb9b9c128340e13ff18b8816ed88b77bf6209d
child 159379 8d949fc41ef17ade910f6e58761e35e4f88a9d83
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs913666
milestone26.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 913666, part 3 - Sink cycle collector listener selection into Collect. r=smaug Move the two places we check global flags to decide if we want to use a listener, even if we aren't passed in one. A later patch renames aListener to aForcedListener to make it less confusing.
xpcom/base/nsCycleCollector.cpp
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -917,20 +917,18 @@ class nsCycleCollector
     TimeStamp mCollectionStart;
 
     CycleCollectedJSRuntime *mJSRuntime;
 
     GCGraph mGraph;
 
     nsIThread* mThread;
 
-public:
     nsCycleCollectorParams mParams;
 
-private:
     nsTArray<PtrInfo*> *mWhiteNodes;
     uint32_t mWhiteNodeCount;
 
     // mVisitedRefCounted and mVisitedGCed are only used for telemetry
     uint32_t mVisitedRefCounted;
     uint32_t mVisitedGCed;
 
     CC_BeforeUnlinkCallback mBeforeUnlinkCB;
@@ -979,17 +977,17 @@ public:
                              size_t *aGraphNodesSize,
                              size_t *aGraphEdgesSize,
                              size_t *aWeakMapsSize,
                              size_t *aWhiteNodeSize,
                              size_t *aPurpleBufferSize) const;
 
 private:
     void CheckThreadSafety();
-    void ShutdownCollect(nsICycleCollectorListener *aListener);
+    void ShutdownCollect();
 
     void PrepareForCollection(nsCycleCollectorResults *aResults,
                               nsTArray<PtrInfo*> *aWhiteNodes);
     void FixGrayBits(bool aForceGC);
     bool ShouldMergeZones(ccType aCCType);
 
     void BeginCollection(ccType aCCType, nsICycleCollectorListener *aListener);
     void MarkRoots(GCGraphBuilder &aBuilder);
@@ -2675,23 +2673,23 @@ nsCycleCollector::CleanupAfterCollection
     }
     CC_TELEMETRY( , interval);
     CC_TELEMETRY(_VISITED_REF_COUNTED, mVisitedRefCounted);
     CC_TELEMETRY(_VISITED_GCED, mVisitedGCed);
     CC_TELEMETRY(_COLLECTED, mWhiteNodeCount);
 }
 
 void
-nsCycleCollector::ShutdownCollect(nsICycleCollectorListener *aListener)
+nsCycleCollector::ShutdownCollect()
 {
     nsAutoTArray<PtrInfo*, 4000> whiteNodes;
 
     for (uint32_t i = 0; i < DEFAULT_SHUTDOWN_COLLECTIONS; ++i) {
         NS_ASSERTION(i < NORMAL_SHUTDOWN_COLLECTIONS, "Extra shutdown CC");
-        if (!Collect(ShutdownCC, &whiteNodes, nullptr, aListener)) {
+        if (!Collect(ShutdownCC, &whiteNodes, nullptr, nullptr)) {
             break;
         }
     }
 }
 
 bool
 nsCycleCollector::Collect(ccType aCCType,
                           nsTArray<PtrInfo*> *aWhiteNodes,
@@ -2702,31 +2700,47 @@ nsCycleCollector::Collect(ccType aCCType
 
     // This can legitimately happen in a few cases. See bug 383651.
     if (mCollectionInProgress) {
         return false;
     }
 
     PrepareForCollection(aResults, aWhiteNodes);
 
-    bool forceGC = (aCCType == ShutdownCC);
-    if (!forceGC && aListener) {
+    bool isShutdown = (aCCType == ShutdownCC);
+
+    // Set up the listener for this CC.
+    MOZ_ASSERT_IF(isShutdown, !aListener);
+    nsCOMPtr<nsICycleCollectorListener> listener(aListener);
+    aListener = nullptr;
+    if (!listener) {
+        if (mParams.mLogAll || (isShutdown && mParams.mLogShutdown)) {
+            nsRefPtr<nsCycleCollectorLogger> logger = new nsCycleCollectorLogger();
+            if (isShutdown && mParams.mAllTracesAtShutdown) {
+                logger->SetAllTraces();
+            }
+            listener = logger.forget();
+        }
+    }
+
+    bool forceGC = isShutdown;
+    if (!forceGC && listener) {
         // On a WantAllTraces CC, force a synchronous global GC to prevent
         // hijinks from ForgetSkippable and compartmental GCs.
-        aListener->GetWantAllTraces(&forceGC);
+        listener->GetWantAllTraces(&forceGC);
     }
     FixGrayBits(forceGC);
 
     FreeSnowWhite(true);
 
-    if (aListener && NS_FAILED(aListener->Begin())) {
-        aListener = nullptr;
+    if (listener && NS_FAILED(listener->Begin())) {
+        listener = nullptr;
     }
 
-    BeginCollection(aCCType, aListener);
+    BeginCollection(aCCType, listener);
     bool collectedAny = CollectWhite();
     CleanupAfterCollection();
     return collectedAny;
 }
 
 // Don't merge too many times in a row, and do at least a minimum
 // number of unmerged CCs in a row.
 static const uint32_t kMinConsecutiveUnmerged = 3;
@@ -2810,24 +2824,17 @@ nsCycleCollector::Shutdown()
 
     // Always delete snow white objects.
     FreeSnowWhite(true);
 
 #ifndef DEBUG
     if (PR_GetEnv("XPCOM_CC_RUN_DURING_SHUTDOWN"))
 #endif
     {
-        nsCOMPtr<nsCycleCollectorLogger> listener;
-        if (mParams.mLogAll || mParams.mLogShutdown) {
-            listener = new nsCycleCollectorLogger();
-            if (mParams.mAllTracesAtShutdown) {
-                listener->SetAllTraces();
-            }
-        }
-        ShutdownCollect(listener);
+        ShutdownCollect();
     }
 }
 
 void
 nsCycleCollector::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
                                       size_t *aObjectSize,
                                       size_t *aGraphNodesSize,
                                       size_t *aGraphEdgesSize,
@@ -3155,24 +3162,20 @@ nsCycleCollector_collect(bool aManuallyT
 {
     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");
-    nsCOMPtr<nsICycleCollectorListener> listener(aListener);
-    if (!aListener && data->mCollector->mParams.mLogAll) {
-        listener = new nsCycleCollectorLogger();
-    }
 
     nsAutoTArray<PtrInfo*, 4000> whiteNodes;
     data->mCollector->Collect(aManuallyTriggered ? ManualCC : ScheduledCC,
-                              &whiteNodes, aResults, listener);
+                              &whiteNodes, aResults, aListener);
 }
 
 void
 nsCycleCollector_shutdown()
 {
     CollectorData *data = sCollectorData.get();
 
     if (data) {