Bug 1475988 - Track histogram memory usage r=gfritzsche
☠☠ backed out by ebc391c0f797 ☠ ☠
authorJan-Erik Rediger <jrediger@mozilla.com>
Wed, 18 Jul 2018 11:28:03 +0000
changeset 819842 c19e776269d896b011a6bdcd831605d3c6afe779
parent 819841 f32ce7c754f0180db94244ada289915c8f9c5b2e
child 819843 ebc391c0f797641205ed5cbf7e1062d35300e158
push id116678
push userbmo:nchevobbe@mozilla.com
push dateWed, 18 Jul 2018 18:05:12 +0000
reviewersgfritzsche
bugs1475988
milestone63.0a1
Bug 1475988 - Track histogram memory usage r=gfritzsche Differential Revision: https://phabricator.services.mozilla.com/D2160
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryHistogram.cpp
toolkit/components/telemetry/TelemetryHistogram.h
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -267,17 +267,17 @@ TelemetryImpl::CollectReports(nsIHandleR
         mLateWritesStacks.SizeOfExcludingThis(),
         "Memory used by the Telemetry LateWrites Stack capturer");
 
   COLLECT_REPORT("explicit/telemetry/Callbacks",
         mCallbacks.ShallowSizeOfExcludingThis(aMallocSizeOf),
         "Memory used by the Telemetry Callbacks array (shallow)");
 
   COLLECT_REPORT("explicit/telemetry/histogram/data",
-      TelemetryHistogram::GetHistogramSizesofIncludingThis(aMallocSizeOf),
+      TelemetryHistogram::GetHistogramSizesOfIncludingThis(aMallocSizeOf),
       "Memory used by Telemetry Histogram data");
 
   COLLECT_REPORT("explicit/telemetry/scalar/data",
       TelemetryScalar::GetScalarSizesOfIncludingThis(aMallocSizeOf),
       "Memory used by Telemetry Scalar data");
 
   COLLECT_REPORT("explicit/telemetry/event/data",
       TelemetryEvent::SizeOfIncludingThis(aMallocSizeOf),
@@ -309,17 +309,17 @@ TelemetryImpl::SizeOfIncludingThis(mozil
   }
 
 #if defined(MOZ_GECKO_PROFILER)
   n += mStackCapturer.SizeOfExcludingThis(aMallocSizeOf);
 #endif
   n += mLateWritesStacks.SizeOfExcludingThis();
   n += mCallbacks.ShallowSizeOfExcludingThis(aMallocSizeOf);
 
-  n += TelemetryHistogram::GetHistogramSizesofIncludingThis(aMallocSizeOf);
+  n += TelemetryHistogram::GetHistogramSizesOfIncludingThis(aMallocSizeOf);
   n += TelemetryScalar::GetScalarSizesOfIncludingThis(aMallocSizeOf);
   n += TelemetryEvent::SizeOfIncludingThis(aMallocSizeOf);
 
   return n;
 }
 
 void
 InitHistogramRecordingEnabled()
--- a/toolkit/components/telemetry/TelemetryHistogram.cpp
+++ b/toolkit/components/telemetry/TelemetryHistogram.cpp
@@ -195,16 +195,18 @@ public:
   void Clear();
 
   HistogramID GetHistogramID() const { return mId; }
 
   bool IsEmpty() const { return mHistogramMap.IsEmpty(); }
 
   bool IsExpired() const { return mIsExpired; }
 
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
+
 private:
   typedef nsBaseHashtableET<nsCStringHashKey, Histogram*> KeyedHistogramEntry;
   typedef AutoHashtable<KeyedHistogramEntry> KeyedHistogramMapType;
   KeyedHistogramMapType mHistogramMap;
 
   const HistogramID mId;
   const HistogramInfo& mHistogramInfo;
   bool mIsExpired;
@@ -1033,16 +1035,25 @@ KeyedHistogram::Clear()
     if (h == gExpiredHistogram) {
       continue;
     }
     delete h;
   }
   mHistogramMap.Clear();
 }
 
+size_t
+KeyedHistogram::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+{
+  size_t n = 0;
+  n += aMallocSizeOf(this);
+  n += mHistogramMap.SizeOfIncludingThis(aMallocSizeOf);
+  return n;
+}
+
 nsresult
 KeyedHistogram::GetJSKeys(JSContext* cx, JS::CallArgs& args)
 {
   JS::AutoValueVector keys(cx);
   if (!keys.reserve(mHistogramMap.Count())) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -2555,22 +2566,54 @@ size_t
 TelemetryHistogram::GetMapShallowSizesOfExcludingThis(mozilla::MallocSizeOf
                                                       aMallocSizeOf)
 {
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
   return gNameToHistogramIDMap.ShallowSizeOfExcludingThis(aMallocSizeOf);
 }
 
 size_t
-TelemetryHistogram::GetHistogramSizesofIncludingThis(mozilla::MallocSizeOf
+TelemetryHistogram::GetHistogramSizesOfIncludingThis(mozilla::MallocSizeOf
                                                      aMallocSizeOf)
 {
   StaticMutexAutoLock locker(gTelemetryHistogramMutex);
-  // TODO
-  return 0;
+
+  size_t n = 0;
+
+  // If we allocated the array, let's count the number of pointers in there and
+  // each entry's size.
+  if (gKeyedHistogramStorage) {
+    n += HistogramCount * size_t(ProcessID::Count) * sizeof(KeyedHistogram*);
+    for (size_t i = 0; i < HistogramCount * size_t(ProcessID::Count); ++i) {
+      if (gKeyedHistogramStorage[i] && gKeyedHistogramStorage[i] != gExpiredKeyedHistogram) {
+        n += gKeyedHistogramStorage[i]->SizeOfIncludingThis(aMallocSizeOf);
+      }
+    }
+  }
+
+  // If we allocated the array, let's count the number of pointers in there.
+  if (gHistogramStorage) {
+    n += HistogramCount * size_t(ProcessID::Count) * sizeof(Histogram*);
+    for (size_t i = 0; i < HistogramCount * size_t(ProcessID::Count); ++i) {
+      if (gHistogramStorage[i] && gHistogramStorage[i] != gExpiredHistogram) {
+        n += gHistogramStorage[i]->SizeOfIncludingThis(aMallocSizeOf);
+      }
+    }
+  }
+
+  // We only allocate the expired (keyed) histogram once.
+  if (gExpiredKeyedHistogram) {
+    n += gExpiredKeyedHistogram->SizeOfIncludingThis(aMallocSizeOf);
+  }
+
+  if (gExpiredHistogram) {
+    n += gExpiredHistogram->SizeOfIncludingThis(aMallocSizeOf);
+  }
+
+  return n;
 }
 
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 //
 // PRIVATE: GeckoView specific helpers
 
 namespace base {
--- a/toolkit/components/telemetry/TelemetryHistogram.h
+++ b/toolkit/components/telemetry/TelemetryHistogram.h
@@ -75,17 +75,17 @@ CreateHistogramSnapshots(JSContext* aCx,
 nsresult
 GetKeyedHistogramSnapshots(JSContext *aCx, JS::MutableHandleValue aResult, unsigned int aDataset,
                            bool aClearSubsession);
 
 size_t
 GetMapShallowSizesOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 size_t
-GetHistogramSizesofIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
+GetHistogramSizesOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 // These functions are only meant to be used for GeckoView persistence.
 // They are responsible for updating in-memory probes with the data persisted
 // on the disk and vice-versa.
 nsresult SerializeHistograms(mozilla::JSONWriter &aWriter);
 nsresult SerializeKeyedHistograms(mozilla::JSONWriter &aWriter);
 nsresult DeserializeHistograms(JSContext* aCx, JS::HandleValue aData);
 nsresult DeserializeKeyedHistograms(JSContext* aCx, JS::HandleValue aData);