Bug 683149: Break out layout memory reporters on a per-shell basis. r=bz
authorKyle Huey <khuey@kylehuey.com>
Wed, 31 Aug 2011 06:38:03 -0400
changeset 77599 94b987001b3819f8ac50a13a9814ed1a346b2592
parent 77598 19a5f6177257f59a9c565f1a6630782aed8f5b5d
child 77600 95a55b2253c5a0e176f5c4123ac9a2561db6045d
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs683149
milestone9.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 683149: Break out layout memory reporters on a per-shell basis. r=bz
layout/base/nsPresShell.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1417,56 +1417,110 @@ public:
 
     result += sizeof(PresShell);
     result += mStackArena.Size();
     result += mFrameArena.Size();
 
     return result;
   }
 
-  static PLDHashOperator LiveShellSizeEnumerator(PresShellPtrKey *aEntry,
-                                                 void *userArg)
-  {
-    PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey());
-    PRUint32 *val = (PRUint32*)userArg;
-    *val += aShell->EstimateMemoryUsed();
-    *val += aShell->mPresContext->EstimateMemoryUsed();
-    return PL_DHASH_NEXT;
-  }
-
-  static PLDHashOperator StyleSizeEnumerator(PresShellPtrKey *aEntry,
-                                             void *userArg)
+  class MemoryReporter : public nsIMemoryMultiReporter
   {
-    PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey());
-    PRUint32 *val = (PRUint32*)userArg;
-    *val += aShell->StyleSet()->SizeOf();
-    return PL_DHASH_NEXT;
-  }
-
-  static PRUint32
-  EstimateShellsMemory(nsTHashtable<PresShellPtrKey>::Enumerator aEnumerator)
-  {
-    PRUint32 result = 0;
-    sLiveShells->EnumerateEntries(aEnumerator, &result);
-    return result;
-  }
-
-  static PRInt64 SizeOfLayoutMemoryReporter() {
-    return EstimateShellsMemory(LiveShellSizeEnumerator);
-  }
-
-  static PRInt64 SizeOfStyleMemoryReporter() {
-    return EstimateShellsMemory(StyleSizeEnumerator);
-  }
+  public:
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIMEMORYMULTIREPORTER
+  protected:
+    static PLDHashOperator SizeEnumerator(PresShellPtrKey *aEntry, void *userArg);
+  };
 
 protected:
   void QueryIsActive();
   nsresult UpdateImageLockingState();
 };
 
+NS_IMPL_ISUPPORTS1(PresShell::MemoryReporter, nsIMemoryMultiReporter)
+
+namespace {
+
+struct MemoryReporterData
+{
+  nsIMemoryMultiReporterCallback* callback;
+  nsISupports* closure;
+};
+
+} // anonymous namespace
+
+/* static */ PLDHashOperator
+PresShell::MemoryReporter::SizeEnumerator(PresShellPtrKey *aEntry,
+                                          void *userArg)
+{
+  PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey());
+  MemoryReporterData *data = (MemoryReporterData*)userArg;
+
+  // Build the string "explicit/layout/shell(<uri of the document>)"
+  nsCAutoString str("explicit/layout/shell(");
+
+  nsIDocument* doc = aShell->GetDocument();
+  if (doc) {
+    nsIURI* docURI = doc->GetDocumentURI();
+
+    if (docURI) {
+      nsCString spec;
+      docURI->GetSpec(spec);
+
+      // A hack: replace forward slashes with '\\' so they aren't
+      // treated as path separators.  Users of the reporters
+      // (such as about:memory) have to undo this change.
+      spec.ReplaceChar('/', '\\');
+
+      str += spec;
+    }
+  }
+
+  str += NS_LITERAL_CSTRING(")");
+
+  NS_NAMED_LITERAL_CSTRING(kArenaDesc, "Memory used by layout PresShell, PresContext, and other related areas.");
+  NS_NAMED_LITERAL_CSTRING(kStyleDesc, "Memory used by the style system.");
+
+  nsCAutoString arenaPath = str + NS_LITERAL_CSTRING("/arenas");
+  nsCAutoString stylePath = str + NS_LITERAL_CSTRING("/styledata");
+
+  PRUint32 arenasSize;
+  arenasSize = aShell->EstimateMemoryUsed();
+  arenasSize += aShell->mPresContext->EstimateMemoryUsed();
+
+  PRUint32 styleSize;
+  styleSize = aShell->StyleSet()->SizeOf();
+
+  data->callback->
+    Callback(EmptyCString(), arenaPath, nsIMemoryReporter::KIND_HEAP,
+             nsIMemoryReporter::UNITS_BYTES, arenasSize, kArenaDesc,
+             data->closure);
+
+  data->callback->
+    Callback(EmptyCString(), stylePath, nsIMemoryReporter::KIND_HEAP,
+             nsIMemoryReporter::UNITS_BYTES, styleSize, kStyleDesc,
+             data->closure);
+
+  return PL_DHASH_NEXT;
+}
+
+NS_IMETHODIMP
+PresShell::MemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
+                                          nsISupports* aClosure)
+{
+  MemoryReporterData data;
+  data.callback = aCb;
+  data.closure = aClosure;
+
+  sLiveShells->EnumerateEntries(SizeEnumerator, &data);
+
+  return NS_OK;
+}
+
 class nsAutoCauseReflowNotifier
 {
 public:
   nsAutoCauseReflowNotifier(PresShell* aShell)
     : mShell(aShell)
   {
     mShell->WillCauseReflow();
   }
@@ -1660,30 +1714,16 @@ NS_NewPresShell(nsIPresShell** aInstance
 
   NS_ADDREF(*aInstancePtrResult);
   return NS_OK;
 }
 
 nsTHashtable<PresShell::PresShellPtrKey> *nsIPresShell::sLiveShells = 0;
 static PRBool sSynthMouseMove = PR_TRUE;
 
-NS_MEMORY_REPORTER_IMPLEMENT(LayoutPresShell,
-    "explicit/layout/arenas",
-    KIND_HEAP,
-    UNITS_BYTES,
-    PresShell::SizeOfLayoutMemoryReporter,
-    "Memory used by layout PresShell, PresContext, and other related areas.")
-
-NS_MEMORY_REPORTER_IMPLEMENT(LayoutStyle,
-    "explicit/layout/styledata",
-    KIND_HEAP,
-    UNITS_BYTES,
-    PresShell::SizeOfStyleMemoryReporter,
-    "Memory used by the style system.")
-
 PresShell::PresShell()
   : mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)
 {
   mSelection = nsnull;
 #ifdef MOZ_REFLOW_PERF
   mReflowCountMgr = new ReflowCountMgr();
   mReflowCountMgr->SetPresContext(mPresContext);
   mReflowCountMgr->SetPresShell(this);
@@ -1701,18 +1741,17 @@ PresShell::PresShell()
 #endif
   mRenderFlags = 0;
   mXResolution = 1.0;
   mYResolution = 1.0;
   mViewportOverridden = PR_FALSE;
 
   static bool registeredReporter = false;
   if (!registeredReporter) {
-    NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(LayoutPresShell));
-    NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(LayoutStyle));
+    NS_RegisterMemoryMultiReporter(new MemoryReporter);
     Preferences::AddBoolVarCache(&sSynthMouseMove,
                                  "layout.reflow.synthMouseMove", PR_TRUE);
     registeredReporter = true;
   }
 
   new (this) nsFrameManager();
 
   sLiveShells->PutEntry(this);