Bug 1346486 - Add a memory reporter for PSM DataStorage caches; r=keeler
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 11 Mar 2017 14:57:46 -0500
changeset 347658 038dece45ca86de6cb0c77811266cf1dab9d8306
parent 347657 bb0dc3ec81a559f88102dc9fc03f6aa3e53cf981
child 347659 7568383eb18d76198fb8df0a1f9ae57c1d9dd309
push id31502
push usercbook@mozilla.com
push dateWed, 15 Mar 2017 12:13:00 +0000
treeherdermozilla-central@48006b970731 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1346486
milestone55.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 1346486 - Add a memory reporter for PSM DataStorage caches; r=keeler
security/manager/ssl/DataStorage.cpp
security/manager/ssl/DataStorage.h
--- a/security/manager/ssl/DataStorage.cpp
+++ b/security/manager/ssl/DataStorage.cpp
@@ -12,37 +12,67 @@
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
+#include "nsIMemoryReporter.h"
 #include "nsIObserverService.h"
 #include "nsITimer.h"
 #include "nsNetUtil.h"
+#include "nsPrintfCString.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 
 // NB: Read DataStorage.h first.
 
 // The default time between data changing and a write, in milliseconds.
 static const uint32_t sDataStorageDefaultTimerDelay = 5u * 60u * 1000u;
 // The maximum score an entry can have (prevents overflow)
 static const uint32_t sMaxScore = UINT32_MAX;
 // The maximum number of entries per type of data (limits resource use)
 static const uint32_t sMaxDataEntries = 1024;
 static const int64_t sOneDayInMicroseconds = int64_t(24 * 60 * 60) *
                                              PR_USEC_PER_SEC;
 
 namespace mozilla {
 
-NS_IMPL_ISUPPORTS(DataStorage,
-                  nsIObserver)
+class DataStorageMemoryReporter final : public nsIMemoryReporter
+{
+  MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
+  ~DataStorageMemoryReporter() = default;
+
+public:
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
+                            nsISupports* aData, bool aAnonymize) final
+  {
+    nsTArray<nsString> fileNames;
+    DataStorage::GetAllFileNames(fileNames);
+    for (const auto& file: fileNames) {
+      RefPtr<DataStorage> ds = DataStorage::Get(file);
+      size_t amount = ds->SizeOfIncludingThis(MallocSizeOf);
+      nsPrintfCString path("explicit/data-storage/%s",
+                           NS_ConvertUTF16toUTF8(file).get());
+      Unused << aHandleReport->Callback(EmptyCString(), path, KIND_HEAP,
+        UNITS_BYTES, amount,
+        NS_LITERAL_CSTRING("Memory used by PSM data storage cache."),
+        aData);
+    }
+    return NS_OK;
+  }
+};
+
+NS_IMPL_ISUPPORTS(DataStorageMemoryReporter, nsIMemoryReporter)
+
+NS_IMPL_ISUPPORTS(DataStorage, nsIObserver)
 
 StaticAutoPtr<DataStorage::DataStorages> DataStorage::sDataStorages;
 
 DataStorage::DataStorage(const nsString& aFilename)
   : mMutex("DataStorage::mMutex")
   , mPendingWrite(false)
   , mShuttingDown(false)
   , mInitCalled(false)
@@ -108,16 +138,27 @@ DataStorage::SetCachedStorageEntries(
 
   for (auto& entry : aEntries) {
     RefPtr<DataStorage> storage = DataStorage::Get(entry.filename());
     bool dataWillPersist = false;
     storage->Init(dataWillPersist, &entry.items());
   }
 }
 
+size_t
+DataStorage::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+{
+  size_t sizeOfExcludingThis =
+    mPersistentDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+    mTemporaryDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+    mPrivateDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) +
+    mFilename.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+  return aMallocSizeOf(this) + sizeOfExcludingThis;
+}
+
 nsresult
 DataStorage::Init(bool& aDataWillPersist,
                   const InfallibleTArray<mozilla::dom::DataStorageItem>* aItems)
 {
   // Don't access the observer service or preferences off the main thread.
   if (!NS_IsMainThread()) {
     MOZ_ASSERT_UNREACHABLE("DataStorage::Init called off main thread");
     return NS_ERROR_NOT_SAME_THREAD;
@@ -127,16 +168,26 @@ DataStorage::Init(bool& aDataWillPersist
 
   // Ignore attempts to initialize several times.
   if (mInitCalled) {
     return NS_OK;
   }
 
   mInitCalled = true;
 
+  static bool memoryReporterRegistered = false;
+  if (!memoryReporterRegistered) {
+    nsresult rv =
+      RegisterStrongMemoryReporter(new DataStorageMemoryReporter());
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    memoryReporterRegistered = true;
+  }
+
   nsresult rv;
   if (XRE_IsParentProcess()) {
     MOZ_ASSERT(!aItems);
 
     rv = NS_NewNamedThread("DataStorage", getter_AddRefs(mWorkerThread));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
--- a/security/manager/ssl/DataStorage.h
+++ b/security/manager/ssl/DataStorage.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_DataStorage_h
 #define mozilla_DataStorage_h
 
 #include "mozilla/Atomics.h"
+#include "mozilla/MemoryReporting.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/StaticPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDataHashtable.h"
 #include "nsIObserver.h"
 #include "nsIThread.h"
 #include "nsITimer.h"
@@ -127,16 +128,18 @@ public:
   static void GetAllFileNames(nsTArray<nsString>& aItems);
 
   // Read all of the data items.
   void GetAll(InfallibleTArray<DataStorageItem>* aItems);
 
   // Set the cached copy of our DataStorage entries in the content process.
   static void SetCachedStorageEntries(const InfallibleTArray<mozilla::dom::DataStorageEntry>& aEntries);
 
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
+
 private:
   explicit DataStorage(const nsString& aFilename);
   virtual ~DataStorage();
 
   class Writer;
   class Reader;
 
   class Entry