Bug 731890 - Convert the 12 "images" memory reporters to a single multi-reporter. r=jlebar.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 01 Mar 2012 16:05:32 -0800
changeset 91000 fed586e905ec0a8712ca6b9f8127e5133e690b30
parent 90999 46a1c807df2b929348214f023d766b9ba951ea84
child 91001 9613e21afa3425f13a8ff343f3ea581f9d1c17dc
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs731890
milestone13.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 731890 - Convert the 12 "images" memory reporters to a single multi-reporter. r=jlebar.
image/src/imgLoader.cpp
toolkit/components/telemetry/TelemetryPing.js
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -132,192 +132,204 @@ static void PrintImageDecoders()
         printf("Have decoder for mime type: %s\n", xcs.get()+decoderContract.Length());
       }
     }
   }
 }
 #endif
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf, "images")
- 
+
 class imgMemoryReporter MOZ_FINAL :
-  public nsIMemoryReporter
+  public nsIMemoryMultiReporter
 {
 public:
-  enum ReporterType {
-    CHROME_BIT = PR_BIT(0),
-    USED_BIT   = PR_BIT(1),
-    RAW_BIT    = PR_BIT(2),
-    HEAP_BIT   = PR_BIT(3),
-
-    ChromeUsedRaw                     = CHROME_BIT | USED_BIT | RAW_BIT | HEAP_BIT,
-    ChromeUsedUncompressedHeap        = CHROME_BIT | USED_BIT | HEAP_BIT,
-    ChromeUsedUncompressedNonheap     = CHROME_BIT | USED_BIT,
-    ChromeUnusedRaw                   = CHROME_BIT | RAW_BIT | HEAP_BIT,
-    ChromeUnusedUncompressedHeap      = CHROME_BIT | HEAP_BIT,
-    ChromeUnusedUncompressedNonheap   = CHROME_BIT,
-    ContentUsedRaw                    = USED_BIT | RAW_BIT | HEAP_BIT,
-    ContentUsedUncompressedHeap       = USED_BIT | HEAP_BIT,
-    ContentUsedUncompressedNonheap    = USED_BIT,
-    ContentUnusedRaw                  = RAW_BIT | HEAP_BIT,
-    ContentUnusedUncompressedHeap     = HEAP_BIT,
-    ContentUnusedUncompressedNonheap  = 0
-  };
-
-  imgMemoryReporter(ReporterType aType)
-    : mType(aType)
+  imgMemoryReporter()
   {
-    // If the RAW bit is set, HEAP should also be set, because we don't
-    // currently understand storing compressed image data off the heap.
-    NS_ASSERTION(!(aType & RAW_BIT) || (aType & HEAP_BIT),
-                 "RAW bit should imply HEAP bit.");
   }
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD GetProcess(nsACString &process)
-  {
-    process.Truncate();
-    return NS_OK;
-  }
-
-  NS_IMETHOD GetPath(nsACString &path)
+  NS_IMETHOD GetName(nsACString &name)
   {
-    if (mType == ChromeUsedRaw) {
-      path.AssignLiteral("explicit/images/chrome/used/raw");
-    } else if (mType == ChromeUsedUncompressedHeap) {
-      path.AssignLiteral("explicit/images/chrome/used/uncompressed-heap");
-    } else if (mType == ChromeUsedUncompressedNonheap) {
-      path.AssignLiteral("explicit/images/chrome/used/uncompressed-nonheap");
-    } else if (mType == ChromeUnusedRaw) {
-      path.AssignLiteral("explicit/images/chrome/unused/raw");
-    } else if (mType == ChromeUnusedUncompressedHeap) {
-      path.AssignLiteral("explicit/images/chrome/unused/uncompressed-heap");
-    } else if (mType == ChromeUnusedUncompressedNonheap) {
-      path.AssignLiteral("explicit/images/chrome/unused/uncompressed-nonheap");
-    } else if (mType == ContentUsedRaw) {
-      path.AssignLiteral("explicit/images/content/used/raw");
-    } else if (mType == ContentUsedUncompressedHeap) {
-      path.AssignLiteral("explicit/images/content/used/uncompressed-heap");
-    } else if (mType == ContentUsedUncompressedNonheap) {
-      path.AssignLiteral("explicit/images/content/used/uncompressed-nonheap");
-    } else if (mType == ContentUnusedRaw) {
-      path.AssignLiteral("explicit/images/content/unused/raw");
-    } else if (mType == ContentUnusedUncompressedHeap) {
-      path.AssignLiteral("explicit/images/content/unused/uncompressed-heap");
-    } else if (mType == ContentUnusedUncompressedNonheap) {
-      path.AssignLiteral("explicit/images/content/unused/uncompressed-nonheap");
-    }
+    name.Assign("images");
     return NS_OK;
   }
 
-  NS_IMETHOD GetKind(PRInt32 *kind)
+  NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback *callback,
+                            nsISupports *closure)
   {
-    if (mType & HEAP_BIT) {
-      *kind = KIND_HEAP;
-    }
-    else {
-      *kind = KIND_MAPPED;
-    }
-    return NS_OK;
-  }
+    AllSizes chrome;
+    AllSizes content;
+    imgLoader::sChromeCache.EnumerateRead(EntryAllSizes, &chrome);
+    imgLoader::sCache.EnumerateRead(EntryAllSizes, &content);
+
+#define REPORT(_path, _kind, _amount, _desc)                                  \
+    do {                                                                      \
+      nsresult rv;                                                            \
+      rv = callback->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path),      \
+                              _kind, nsIMemoryReporter::UNITS_BYTES, _amount, \
+                              NS_LITERAL_CSTRING(_desc), closure);            \
+      NS_ENSURE_SUCCESS(rv, rv);                                              \
+    } while (0)
+
+    REPORT("explicit/images/chrome/used/raw",
+           nsIMemoryReporter::KIND_HEAP, chrome.mUsedRaw,
+           "Memory used by in-use chrome images (compressed data).");
+
+    REPORT("explicit/images/chrome/used/uncompressed-heap",
+           nsIMemoryReporter::KIND_HEAP, chrome.mUsedUncompressedHeap,
+           "Memory used by in-use chrome images (uncompressed data).");
+
+    REPORT("explicit/images/chrome/used/uncompressed-nonheap",
+           nsIMemoryReporter::KIND_NONHEAP, chrome.mUsedUncompressedNonheap,
+           "Memory used by in-use chrome images (uncompressed data).");
+
+    REPORT("explicit/images/chrome/unused/raw",
+           nsIMemoryReporter::KIND_HEAP, chrome.mUnusedRaw,
+           "Memory used by not in-use chrome images (compressed data).");
 
-  NS_IMETHOD GetUnits(PRInt32 *units)
-  {
-    *units = UNITS_BYTES;
+    REPORT("explicit/images/chrome/unused/uncompressed-heap",
+           nsIMemoryReporter::KIND_HEAP, chrome.mUnusedUncompressedHeap,
+           "Memory used by not in-use chrome images (uncompressed data).");
+
+    REPORT("explicit/images/chrome/unused/uncompressed-nonheap",
+           nsIMemoryReporter::KIND_NONHEAP, chrome.mUnusedUncompressedNonheap,
+           "Memory used by not in-use chrome images (uncompressed data).");
+
+    REPORT("explicit/images/content/used/raw",
+           nsIMemoryReporter::KIND_HEAP, content.mUsedRaw,
+           "Memory used by in-use content images (compressed data).");
+
+    REPORT("explicit/images/content/used/uncompressed-heap",
+           nsIMemoryReporter::KIND_HEAP, content.mUsedUncompressedHeap,
+           "Memory used by in-use content images (uncompressed data).");
+
+    REPORT("explicit/images/content/used/uncompressed-nonheap",
+           nsIMemoryReporter::KIND_NONHEAP, content.mUsedUncompressedNonheap,
+           "Memory used by in-use content images (uncompressed data).");
+
+    REPORT("explicit/images/content/unused/raw",
+           nsIMemoryReporter::KIND_HEAP, content.mUnusedRaw,
+           "Memory used by not in-use content images (compressed data).");
+
+    REPORT("explicit/images/content/unused/uncompressed-heap",
+           nsIMemoryReporter::KIND_HEAP, content.mUnusedUncompressedHeap,
+           "Memory used by not in-use content images (uncompressed data).");
+
+    REPORT("explicit/images/content/unused/uncompressed-nonheap",
+           nsIMemoryReporter::KIND_NONHEAP, content.mUnusedUncompressedNonheap,
+           "Memory used by not in-use content images (uncompressed data).");
+
+#undef REPORT
+
     return NS_OK;
   }
 
-  struct EnumArg {
-    EnumArg(ReporterType aType)
-      : rtype(aType), n(0)
-    { }
+  NS_IMETHOD GetExplicitNonHeap(PRInt64 *n)
+  {
+    size_t n2 = 0;
+    imgLoader::sChromeCache.EnumerateRead(EntryExplicitNonHeapSize, &n2);
+    imgLoader::sCache.EnumerateRead(EntryExplicitNonHeapSize, &n2);
+    *n = n2;
+    return NS_OK;
+  }
 
-    ReporterType rtype;
-    size_t n;
+  static PRInt64 GetImagesContentUsedUncompressed()
+  {
+    size_t n = 0;
+    imgLoader::sCache.EnumerateRead(EntryUsedUncompressedSize, &n);
+    return n;
+  }
+
+private:
+  struct AllSizes {
+    size_t mUsedRaw;
+    size_t mUsedUncompressedHeap;
+    size_t mUsedUncompressedNonheap;
+    size_t mUnusedRaw;
+    size_t mUnusedUncompressedHeap;
+    size_t mUnusedUncompressedNonheap;
+
+    AllSizes() {
+      memset(this, 0, sizeof(*this));
+    }
   };
 
-  static PLDHashOperator EnumEntries(const nsACString&,
-                                     imgCacheEntry *entry,
-                                     void *userArg)
+  static PLDHashOperator EntryAllSizes(const nsACString&,
+                                       imgCacheEntry *entry,
+                                       void *userArg)
   {
-    EnumArg *arg = static_cast<EnumArg*>(userArg);
-    ReporterType rtype = arg->rtype;
-
-    if (rtype & USED_BIT) {
-      if (entry->HasNoProxies())
-        return PL_DHASH_NEXT;
-    } else {
-      if (!entry->HasNoProxies())
-        return PL_DHASH_NEXT;
-    }
-
     nsRefPtr<imgRequest> req = entry->GetRequest();
     Image *image = static_cast<Image*>(req->mImage.get());
-    if (!image)
-      return PL_DHASH_NEXT;
-
-    if (rtype & RAW_BIT) {
-      arg->n += image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf);
-    } else if (rtype & HEAP_BIT) {
-      arg->n += image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
-    } else {
-      arg->n += image->NonHeapSizeOfDecoded();
+    if (image) {
+      AllSizes *sizes = static_cast<AllSizes*>(userArg);
+      if (entry->HasNoProxies()) {
+        sizes->mUnusedRaw +=
+          image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf);
+        sizes->mUnusedUncompressedHeap +=
+          image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
+        sizes->mUnusedUncompressedNonheap += image->NonHeapSizeOfDecoded();
+      } else {
+        sizes->mUsedRaw +=
+          image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf);
+        sizes->mUsedUncompressedHeap +=
+          image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
+        sizes->mUsedUncompressedNonheap += image->NonHeapSizeOfDecoded();
+      }
     }
 
     return PL_DHASH_NEXT;
   }
 
-  NS_IMETHOD GetAmount(PRInt64 *amount)
+  static PLDHashOperator EntryExplicitNonHeapSize(const nsACString&,
+                                                  imgCacheEntry *entry,
+                                                  void *userArg)
   {
-    EnumArg arg(mType);
-    if (mType & CHROME_BIT) {
-      imgLoader::sChromeCache.EnumerateRead(EnumEntries, &arg);
-    } else {
-      imgLoader::sCache.EnumerateRead(EnumEntries, &arg);
+    size_t *n = static_cast<size_t*>(userArg);
+    nsRefPtr<imgRequest> req = entry->GetRequest();
+    Image *image = static_cast<Image*>(req->mImage.get());
+    if (image) {
+      *n += image->NonHeapSizeOfDecoded();
     }
 
-    *amount = arg.n;
-    return NS_OK;
+    return PL_DHASH_NEXT;
   }
 
-  NS_IMETHOD GetDescription(nsACString &desc)
+  static PLDHashOperator EntryUsedUncompressedSize(const nsACString&,
+                                                   imgCacheEntry *entry,
+                                                   void *userArg)
   {
-    if (mType == ChromeUsedRaw) {
-      desc.AssignLiteral("Memory used by in-use chrome images (compressed data).");
-    } else if (mType == ChromeUsedUncompressedHeap) {
-      desc.AssignLiteral("Memory used by in-use chrome images (uncompressed data).");
-    } else if (mType == ChromeUsedUncompressedNonheap) {
-      desc.AssignLiteral("Memory used by in-use chrome images (uncompressed data).");
-    } else if (mType == ChromeUnusedRaw) {
-      desc.AssignLiteral("Memory used by not in-use chrome images (compressed data).");
-    } else if (mType == ChromeUnusedUncompressedHeap) {
-      desc.AssignLiteral("Memory used by not in-use chrome images (uncompressed data).");
-    } else if (mType == ChromeUnusedUncompressedNonheap) {
-      desc.AssignLiteral("Memory used by not in-use chrome images (uncompressed data).");
-    } else if (mType == ContentUsedRaw) {
-      desc.AssignLiteral("Memory used by in-use content images (compressed data).");
-    } else if (mType == ContentUsedUncompressedHeap) {
-      desc.AssignLiteral("Memory used by in-use content images (uncompressed data).");
-    } else if (mType == ContentUsedUncompressedNonheap) {
-      desc.AssignLiteral("Memory used by in-use content images (uncompressed data).");
-    } else if (mType == ContentUnusedRaw) {
-      desc.AssignLiteral("Memory used by not in-use content images (compressed data).");
-    } else if (mType == ContentUnusedUncompressedHeap) {
-      desc.AssignLiteral("Memory used by not in-use content images (uncompressed data).");
-    } else if (mType == ContentUnusedUncompressedNonheap) {
-      desc.AssignLiteral("Memory used by not in-use content images (uncompressed data).");
+    if (!entry->HasNoProxies()) {
+      size_t *n = static_cast<size_t*>(userArg);
+      nsRefPtr<imgRequest> req = entry->GetRequest();
+      Image *image = static_cast<Image*>(req->mImage.get());
+      if (image) {
+        *n += image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
+        *n += image->NonHeapSizeOfDecoded();
+      }
     }
-    return NS_OK;
+
+    return PL_DHASH_NEXT;
   }
-
-  ReporterType mType;
 };
 
-NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryReporter)
+// This is used by telemetry.
+NS_MEMORY_REPORTER_IMPLEMENT(
+  ImagesContentUsedUncompressed,
+  "images-content-used-uncompressed",
+  KIND_OTHER,
+  UNITS_BYTES,
+  imgMemoryReporter::GetImagesContentUsedUncompressed,
+  "This is the sum of the 'explicit/images/content/used/uncompressed-heap' "
+  "and 'explicit/images/content/used/uncompressed-nonheap' numbers.  However, "
+  "it is measured at a different time and so may give slightly different "
+  "results.")
+
+NS_IMPL_ISUPPORTS1(imgMemoryReporter, nsIMemoryMultiReporter)
 
 NS_IMPL_ISUPPORTS3(nsProgressNotificationProxy,
                      nsIProgressEventSink,
                      nsIChannelEventSink,
                      nsIInterfaceRequestor)
 
 NS_IMETHODIMP
 nsProgressNotificationProxy::OnProgress(nsIRequest* request,
@@ -917,28 +929,18 @@ nsresult imgLoader::InitCache()
 
   PRInt32 cachesize;
   rv = Preferences::GetInt("image.cache.size", &cachesize);
   if (NS_SUCCEEDED(rv))
     sCacheMaxSize = cachesize;
   else
     sCacheMaxSize = 5 * 1024 * 1024;
 
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedRaw));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedUncompressedHeap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUsedUncompressedNonheap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedRaw));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedUncompressedHeap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ChromeUnusedUncompressedNonheap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedRaw));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedUncompressedHeap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUsedUncompressedNonheap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedRaw));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedUncompressedHeap));
-  NS_RegisterMemoryReporter(new imgMemoryReporter(imgMemoryReporter::ContentUnusedUncompressedNonheap));
+  NS_RegisterMemoryMultiReporter(new imgMemoryReporter());
+  NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(ImagesContentUsedUncompressed));
   
   return NS_OK;
 }
 
 nsresult imgLoader::Init()
 {
   ReadAcceptHeaderPref();
 
--- a/toolkit/components/telemetry/TelemetryPing.js
+++ b/toolkit/components/telemetry/TelemetryPing.js
@@ -57,17 +57,17 @@ const TELEMETRY_DELAY = 60000;
 // about:memory values to turn into histograms
 const MEM_HISTOGRAMS = {
   "js-gc-heap": "MEMORY_JS_GC_HEAP",
   "js-compartments-system": "MEMORY_JS_COMPARTMENTS_SYSTEM",
   "js-compartments-user": "MEMORY_JS_COMPARTMENTS_USER",
   "explicit": "MEMORY_EXPLICIT",
   "resident": "MEMORY_RESIDENT",
   "storage-sqlite": "MEMORY_STORAGE_SQLITE",
-  "explicit/images/content/used/uncompressed":
+  "images-content-used-uncompressed":
     "MEMORY_IMAGES_CONTENT_USED_UNCOMPRESSED",
   "heap-allocated": "MEMORY_HEAP_ALLOCATED",
   "page-faults-hard": "PAGE_FAULTS_HARD",
   "low-memory-events-virtual": "LOW_MEMORY_EVENTS_VIRTUAL",
   "low-memory-events-physical": "LOW_MEMORY_EVENTS_PHYSICAL"
 };
 // Seconds of idle time before pinging.
 // On idle-daily a gather-telemetry notification is fired, during it probes can