Bug 911829 - Separate main thread and worker cycle collector telemetry. r=smaug
authorAndrew McCreight <amccreight@mozilla.com>
Tue, 10 Sep 2013 08:29:45 -0700
changeset 146429 a90d8624e03ddc14e1cfe60b9b981aa8811e91f3
parent 146428 f4804e82856f82089e9457b61dc3ee305c2ba535
child 146430 2b76eb674066a5182e9be5e47365e41e70277636
push id25260
push userryanvm@gmail.com
push dateWed, 11 Sep 2013 00:29:30 +0000
treeherdermozilla-central@f73bed2856a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs911829
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 911829 - Separate main thread and worker cycle collector telemetry. r=smaug
toolkit/components/telemetry/Histograms.json
xpcom/base/nsCycleCollector.cpp
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -29,16 +29,22 @@
     "description": "Maximum number of concurrent threads reached during a given download session"
   },
   "CYCLE_COLLECTOR": {
     "kind": "exponential",
     "high": "10000",
     "n_buckets": 50,
     "description": "Time spent on one cycle collection (ms)"
   },
+  "CYCLE_COLLECTOR_WORKER": {
+    "kind": "exponential",
+    "high": "10000",
+    "n_buckets": 50,
+    "description": "Time spent on one cycle collection in a worker (ms)"
+  },
   "CYCLE_COLLECTOR_FULL": {
     "kind": "exponential",
     "high": "10000",
     "n_buckets": 50,
     "description": "Full pause time for one cycle collection, including preparation (ms)"
   },
   "CYCLE_COLLECTOR_FINISH_IGC": {
     "kind": "boolean",
@@ -49,48 +55,74 @@
     "description": "Cycle collection synchronously ran forget skippable"
   },
   "CYCLE_COLLECTOR_VISITED_REF_COUNTED": {
     "kind": "exponential",
     "high": "300000",
     "n_buckets": 50,
     "description": "Number of ref counted objects visited by the cycle collector"
   },
+  "CYCLE_COLLECTOR_WORKER_VISITED_REF_COUNTED": {
+    "kind": "exponential",
+    "high": "300000",
+    "n_buckets": 50,
+    "description": "Number of ref counted objects visited by the cycle collector in a worker"
+  },
   "CYCLE_COLLECTOR_VISITED_GCED": {
     "kind": "exponential",
     "high": "300000",
     "n_buckets": 50,
     "description": "Number of JS objects visited by the cycle collector"
   },
+  "CYCLE_COLLECTOR_WORKER_VISITED_GCED": {
+    "kind": "exponential",
+    "high": "300000",
+    "n_buckets": 50,
+    "description": "Number of JS objects visited by the cycle collector in a worker"
+  },
   "CYCLE_COLLECTOR_COLLECTED": {
     "kind": "exponential",
     "high": "100000",
     "n_buckets": 50,
     "description": "Number of objects collected by the cycle collector"
   },
+  "CYCLE_COLLECTOR_WORKER_COLLECTED": {
+    "kind": "exponential",
+    "high": "100000",
+    "n_buckets": 50,
+    "description": "Number of objects collected by the cycle collector in a worker"
+  },
   "CYCLE_COLLECTOR_NEED_GC": {
     "kind": "boolean",
     "description": "Needed garbage collection before cycle collection."
   },
+  "CYCLE_COLLECTOR_WORKER_NEED_GC": {
+    "kind": "boolean",
+    "description": "Needed garbage collection before cycle collection in a worker."
+  },
   "CYCLE_COLLECTOR_TIME_BETWEEN": {
     "kind": "exponential",
     "high": "120",
     "n_buckets": 50,
     "description": "Time spent in between cycle collections (seconds)"
   },
   "CYCLE_COLLECTOR_CONTENT_UNBIND": {
     "kind": "exponential",
     "high": "10000",
     "n_buckets": 50,
     "description": "Time spent on one ContentUnbinder (ms)"
   },
   "CYCLE_COLLECTOR_OOM": {
     "kind": "flag",
     "description": "Set if the cycle collector ran out of memory at some point"
   },
+  "CYCLE_COLLECTOR_WORKER_OOM": {
+    "kind": "flag",
+    "description": "Set if the cycle collector in a worker ran out of memory at some point"
+  },
   "CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING": {
     "kind": "exponential",
     "high": "10000",
     "n_buckets": 50,
     "description": "Time spent on one asynchronous SnowWhite freeing (ms)"
   },
   "FORGET_SKIPPABLE_MAX": {
     "kind": "exponential",
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -372,16 +372,25 @@ public:
 };
 
 #ifdef DEBUG_CC_GRAPH
 #define CC_GRAPH_ASSERT(b) MOZ_ASSERT(b)
 #else
 #define CC_GRAPH_ASSERT(b)
 #endif
 
+#define CC_TELEMETRY(_name, _value)                                            \
+    PR_BEGIN_MACRO                                                             \
+    if (NS_IsMainThread()) {                                                   \
+      Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR##_name, _value);        \
+    } else {                                                                   \
+      Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_WORKER##_name, _value); \
+    }                                                                          \
+    PR_END_MACRO
+
 enum NodeColor { black, white, grey };
 
 // This structure should be kept as small as possible; we may expect
 // hundreds of thousands of them to be allocated and touched
 // repeatedly during each cycle collection.
 
 struct PtrInfo
 {
@@ -2137,17 +2146,17 @@ nsCycleCollector::MarkRoots(GCGraphBuild
     }
     if (mGraph.mRootCount > 0) {
         aBuilder.SetLastChild();
     }
 
     if (aBuilder.RanOutOfMemory()) {
         NS_ASSERTION(false,
                      "Ran out of memory while building cycle collector graph");
-        Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_OOM, true);
+        CC_TELEMETRY(_OOM, true);
     }
 }
 
 
 ////////////////////////////////////////////////////////////////////////
 // Bacon & Rajan's |ScanRoots| routine.
 ////////////////////////////////////////////////////////////////////////
 
@@ -2254,34 +2263,34 @@ nsCycleCollector::ScanWeakMaps()
                 GraphWalker<ScanBlackVisitor>(ScanBlackVisitor(mWhiteNodeCount, failed)).Walk(wm->mVal);
                 anyChanged = true;
             }
         }
     } while (anyChanged);
 
     if (failed) {
         NS_ASSERTION(false, "Ran out of memory in ScanWeakMaps");
-        Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_OOM, true);
+        CC_TELEMETRY(_OOM, true);
     }
 }
 
 void
 nsCycleCollector::ScanRoots()
 {
     mWhiteNodeCount = 0;
 
     // On the assumption that most nodes will be black, it's
     // probably faster to use a GraphWalker than a
     // NodePool::Enumerator.
     bool failed = false;
     GraphWalker<scanVisitor>(scanVisitor(mWhiteNodeCount, failed)).WalkFromRoots(mGraph);
 
     if (failed) {
         NS_ASSERTION(false, "Ran out of memory in ScanRoots");
-        Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_OOM, true);
+        CC_TELEMETRY(_OOM, true);
     }
 
     ScanWeakMaps();
 }
 
 
 ////////////////////////////////////////////////////////////////////////
 // Bacon & Rajan's |CollectWhite| routine, somewhat modified.
@@ -2576,17 +2585,17 @@ nsCycleCollector::FixGrayBits(bool aForc
     if (!mJSRuntime)
         return;
 
     if (!aForceGC) {
         mJSRuntime->FixWeakMappingGrayBits();
 
         bool needGC = mJSRuntime->NeedCollect();
         // Only do a telemetry ping for non-shutdown CCs.
-        Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_NEED_GC, needGC);
+        CC_TELEMETRY(_NEED_GC, needGC);
         if (!needGC)
             return;
         if (mResults)
             mResults->mForcedGC = true;
     }
 
     TimeLog timeLog;
     mJSRuntime->Collect(aForceGC ? JS::gcreason::SHUTDOWN_CC : JS::gcreason::CC_FORCED);
@@ -2647,20 +2656,20 @@ nsCycleCollector::CleanupAfterCollection
     }
     printf("cc: \n");
 #endif
     if (mResults) {
         mResults->mVisitedRefCounted = mVisitedRefCounted;
         mResults->mVisitedGCed = mVisitedGCed;
         mResults = nullptr;
     }
-    Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR, interval);
-    Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_VISITED_REF_COUNTED, mVisitedRefCounted);
-    Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_VISITED_GCED, mVisitedGCed);
-    Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_COLLECTED, mWhiteNodeCount);
+    CC_TELEMETRY( , interval);
+    CC_TELEMETRY(_VISITED_REF_COUNTED, mVisitedRefCounted);
+    CC_TELEMETRY(_VISITED_GCED, mVisitedGCed);
+    CC_TELEMETRY(_COLLECTED, mWhiteNodeCount);
 }
 
 void
 nsCycleCollector::ShutdownCollect(nsICycleCollectorListener *aListener)
 {
     nsAutoTArray<PtrInfo*, 4000> whiteNodes;
 
     for (uint32_t i = 0; i < DEFAULT_SHUTDOWN_COLLECTIONS; ++i) {