Bug 1457127 - Create common helpers for taking keyed histogram snapshots. r=chutten,janerik
authorAlessio Placitelli <alessio.placitelli@gmail.com>
Wed, 16 May 2018 13:09:33 +0200
changeset 419064 ae169019f9e4e1734f6ed63c0ef7430fe9a74e22
parent 419063 440073e5e466ea0662537569b6b1539b089b35fe
child 419065 164e7e5c55eb306781f813fc1d2de5853523b505
push id34025
push userapavel@mozilla.com
push dateMon, 21 May 2018 09:46:09 +0000
treeherdermozilla-central@8850728602d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschutten, janerik
bugs1457127
milestone62.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 1457127 - Create common helpers for taking keyed histogram snapshots. r=chutten,janerik MozReview-Commit-ID: 3JrMtOrefdS
toolkit/components/telemetry/TelemetryHistogram.cpp
--- a/toolkit/components/telemetry/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/TelemetryHistogram.cpp
@@ -166,16 +166,24 @@ struct HistogramSnapshotInfo {
 };
 
 typedef mozilla::Vector<HistogramSnapshotInfo> HistogramSnapshotsArray;
 typedef mozilla::Vector<HistogramSnapshotsArray> HistogramProcessSnapshotsArray;
 
 // The following is used to handle snapshot information for keyed histograms.
 typedef nsDataHashtable<nsCStringHashKey, HistogramSnapshotData> KeyedHistogramSnapshotData;
 
+struct KeyedHistogramSnapshotInfo {
+  KeyedHistogramSnapshotData data;
+  HistogramID histogramId;
+};
+
+typedef mozilla::Vector<KeyedHistogramSnapshotInfo> KeyedHistogramSnapshotsArray;
+typedef mozilla::Vector<KeyedHistogramSnapshotsArray> KeyedHistogramProcessSnapshotsArray;
+
 class KeyedHistogram {
 public:
   KeyedHistogram(HistogramID id, const HistogramInfo& info);
   ~KeyedHistogram();
   nsresult GetHistogram(const nsCString& name, Histogram** histogram);
   Histogram* GetHistogram(const nsCString& name);
   uint32_t GetHistogramType() const { return mHistogramInfo.histogramType; }
   nsresult GetJSKeys(JSContext* cx, JS::CallArgs& args);
@@ -1043,16 +1051,80 @@ KeyedHistogram::GetSnapshot(const Static
 
   if (aClearSubsession) {
     Clear();
   }
 
   return NS_OK;
 }
 
+
+/**
+ * Helper function to get a snapshot of the keyed histograms.
+ *
+ * @param {aLock} the lock proof.
+ * @param {aDataset} the dataset for which the snapshot is being requested.
+ * @param {aClearSubsession} whether or not to clear the data after
+ *        taking the snapshot.
+ * @param {aIncludeGPU} whether or not to include data for the GPU.
+ * @param {aOutSnapshot} the container in which the snapshot data will be stored.
+ * @return {nsresult} NS_OK if the snapshot was successfully taken or
+ *         NS_ERROR_OUT_OF_MEMORY if it failed to allocate memory.
+ */
+nsresult
+internal_GetKeyedHistogramsSnapshot(const StaticMutexAutoLock& aLock,
+                                    unsigned int aDataset,
+                                    bool aClearSubsession,
+                                    bool aIncludeGPU,
+                                    KeyedHistogramProcessSnapshotsArray& aOutSnapshot)
+{
+  if (!aOutSnapshot.resize(static_cast<uint32_t>(ProcessID::Count))) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  for (uint32_t process = 0; process < static_cast<uint32_t>(ProcessID::Count); ++process) {
+    KeyedHistogramSnapshotsArray& hArray = aOutSnapshot[process];
+
+    for (size_t i = 0; i < HistogramCount; ++i) {
+      HistogramID id = HistogramID(i);
+      const HistogramInfo& info = gHistogramInfos[id];
+      if (!info.keyed) {
+        continue;
+      }
+
+      if (!CanRecordInProcess(info.record_in_processes, ProcessID(process)) ||
+        ((ProcessID(process) == ProcessID::Gpu) && !aIncludeGPU)) {
+        continue;
+      }
+
+      if (!IsInDataset(info.dataset, aDataset)) {
+        continue;
+      }
+
+      KeyedHistogram* keyed = internal_GetKeyedHistogramById(id,
+                                                             ProcessID(process),
+                                                             /* instantiate = */ false);
+      if (!keyed) {
+        continue;
+      }
+
+      // Take a snapshot of the keyed histogram data!
+      KeyedHistogramSnapshotData snapshot;
+      if (!NS_SUCCEEDED(keyed->GetSnapshot(aLock, snapshot, aClearSubsession))) {
+        return NS_ERROR_FAILURE;
+      }
+
+      if (!hArray.emplaceBack(KeyedHistogramSnapshotInfo{mozilla::Move(snapshot), id})) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+    }
+  }
+  return NS_OK;
+}
+
 } // namespace
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: thread-unsafe helpers for the external interface
 
 namespace {
@@ -2365,83 +2437,42 @@ TelemetryHistogram::GetKeyedHistogramSna
 
   // Include the GPU process in histogram snapshots only if we actually tried
   // to launch a process for it.
   bool includeGPUProcess = false;
   if (auto gpm = mozilla::gfx::GPUProcessManager::Get()) {
     includeGPUProcess = gpm->AttemptedGPUProcess();
   }
 
-  struct KeyedHistogramProcessInfo {
-    KeyedHistogramSnapshotData data;
-    HistogramID histogramId;
-  };
-
   // Get a snapshot of all the data while holding the mutex.
-  mozilla::Vector<mozilla::Vector<KeyedHistogramProcessInfo>> dataSnapshot;
+  KeyedHistogramProcessSnapshotsArray processHistArray;
   {
-    if (!dataSnapshot.resize(static_cast<uint32_t>(ProcessID::Count))) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
     StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-
-    for (uint32_t process = 0; process < static_cast<uint32_t>(ProcessID::Count); ++process) {
-      mozilla::Vector<KeyedHistogramProcessInfo>& hArray = dataSnapshot[process];
-
-      for (size_t i = 0; i < HistogramCount; ++i) {
-        HistogramID id = HistogramID(i);
-        const HistogramInfo& info = gHistogramInfos[id];
-        if (!info.keyed) {
-          continue;
-        }
-
-        if (!CanRecordInProcess(info.record_in_processes, ProcessID(process)) ||
-          ((ProcessID(process) == ProcessID::Gpu) && !includeGPUProcess)) {
-          continue;
-        }
-
-        if (!IsInDataset(info.dataset, aDataset)) {
-          continue;
-        }
-
-        KeyedHistogram* keyed = internal_GetKeyedHistogramById(id,
-                                                               ProcessID(process),
-                                                               /* instantiate = */ false);
-        if (!keyed) {
-          continue;
-        }
-
-        // Take a snapshot of the keyed histogram data!
-        KeyedHistogramSnapshotData snapshot;
-        if (!NS_SUCCEEDED(keyed->GetSnapshot(locker, snapshot, aClearSubsession))) {
-          return NS_ERROR_FAILURE;
-        }
-
-        if (!hArray.emplaceBack(KeyedHistogramProcessInfo{mozilla::Move(snapshot), id})) {
-          return NS_ERROR_OUT_OF_MEMORY;
-        }
-      }
+    nsresult rv = internal_GetKeyedHistogramsSnapshot(locker,
+                                                      aDataset,
+                                                      aClearSubsession,
+                                                      includeGPUProcess,
+                                                      processHistArray);
+    if (NS_FAILED(rv)) {
+      return rv;
     }
   }
 
   // Mirror the snapshot data to JS, now that we released the mutex.
-  for (uint32_t process = 0; process < dataSnapshot.length(); ++process) {
-    const mozilla::Vector<KeyedHistogramProcessInfo>& hArray = dataSnapshot[process];
-
+  for (uint32_t process = 0; process < processHistArray.length(); ++process) {
     JS::Rooted<JSObject*> processObject(aCx, JS_NewPlainObject(aCx));
     if (!processObject) {
       return NS_ERROR_FAILURE;
     }
     if (!JS_DefineProperty(aCx, obj, GetNameForProcessID(ProcessID(process)),
                            processObject, JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
-    for (size_t i = 0; i < hArray.length(); ++i) {
-      const KeyedHistogramProcessInfo& hData = hArray[i];
+
+    for (const KeyedHistogramSnapshotInfo& hData : processHistArray[process]) {
       const HistogramInfo& info = gHistogramInfos[hData.histogramId];
 
       JS::RootedObject snapshot(aCx, JS_NewPlainObject(aCx));
       if (!snapshot) {
         return NS_ERROR_FAILURE;
       }
 
       if (!NS_SUCCEEDED(internal_ReflectKeyedHistogram(hData.data, info, aCx, snapshot))) {