Bug 730181 (part 1) - Merge the "dom+style" and "layout" memory reporter trees. r=khuey.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 21 Feb 2012 07:10:11 -0800
changeset 88342 c12cfaf9cd4e869363cc5aef1ee9ea7155c31f2d
parent 88341 412c948ce10019d15cde747af6db85a91d131d77
child 88343 4069a04e8e819e095c064c270e367bb8f8850234
push id157
push userMs2ger@gmail.com
push dateWed, 07 Mar 2012 19:27:10 +0000
reviewerskhuey
bugs730181
milestone13.0a1
Bug 730181 (part 1) - Merge the "dom+style" and "layout" memory reporter trees. r=khuey.
content/base/src/nsDocument.cpp
dom/base/nsDOMMemoryReporter.cpp
dom/base/nsDOMMemoryReporter.h
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
toolkit/components/aboutmemory/tests/test_memoryReporters.xul
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -9144,16 +9144,23 @@ nsDocument::GetMozVisibilityState(nsAStr
 }
 
 /* virtual */ void
 nsIDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
 {
   aWindowSizes->mDOM +=
     nsINode::SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
 
+  if (mPresShell) {
+    mPresShell->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf,
+                                    &aWindowSizes->mLayoutArenas,
+                                    &aWindowSizes->mLayoutStyleSets,
+                                    &aWindowSizes->mLayoutTextRuns);
+  }
+
   // Measurement of the following members may be added later if DMD finds it
   // is worthwhile:
   // - many!
 }
 
 void
 nsIDocument::DocSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
 {
--- a/dom/base/nsDOMMemoryReporter.cpp
+++ b/dom/base/nsDOMMemoryReporter.cpp
@@ -83,28 +83,21 @@ AppendWindowURI(nsGlobalWindow *aWindow,
   // (such as about:memory) have to undo this change.
   spec.ReplaceChar('/', '\\');
 
   aStr += spec;
 
   return true;
 }
 
-struct WindowTotals
-{
-  WindowTotals() : mDom(0), mStyleSheets(0) {}
-  size_t mDom;
-  size_t mStyleSheets;
-};
-
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "dom+style")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
 
 static void
 CollectWindowReports(nsGlobalWindow *aWindow,
-                     WindowTotals *aWindowTotals,
+                     nsWindowSizes *aWindowTotalSizes,
                      nsIMemoryMultiReporterCallback *aCb,
                      nsISupports *aClosure)
 {
   // DOM window objects fall into one of three categories:
   // - "active" windows are currently either displayed in an active
   //   tab, or a child of such a window.
   // - "cached" windows are in the fastback cache.
   // - "other" windows are closed (or navigated away from w/o being
@@ -121,17 +114,17 @@ CollectWindowReports(nsGlobalWindow *aWi
   // For outer windows we simply group them all together and just show
   // the combined count and amount of memory used, which is generally
   // a constant amount per window (since all the actual data lives in
   // the inner window).
   //
   // The path we give to the reporter callback for inner windows are
   // as follows:
   //
-  //   explicit/dom+style/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
+  //   explicit/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
   //
   // Where:
   // - <category> is active, cached, or other, as described above.
   // - <top-outer-id> is the window id (nsPIDOMWindow::WindowID()) of
   //   the top outer window (i.e. tab, or top level chrome window).
   // - <top-inner-id> is the window id of the top window's inner
   //   window.
   // - <id> is the window id of the inner window in question.
@@ -140,22 +133,22 @@ CollectWindowReports(nsGlobalWindow *aWi
   // Exposing the window ids is done to get logical grouping in
   // about:memory, and also for debuggability since one can get to the
   // nsGlobalWindow for a window id by calling the static method
   // nsGlobalWindow::GetInnerWindowWithId(id) (or
   // GetOuterWindowWithId(id) in a debugger.
   //
   // For outer windows we simply use:
   // 
-  //   explicit/dom+style/window-objects/<category>/outer-windows
+  //   explicit/window-objects/<category>/outer-windows
   //
   // Which gives us simple counts of how many outer windows (and their
   // combined sizes) per category.
 
-  nsCAutoString windowPath("explicit/dom+style/window-objects/");
+  nsCAutoString windowPath("explicit/window-objects/");
 
   nsIDocShell *docShell = aWindow->GetDocShell();
 
   nsGlobalWindow *top = aWindow->GetTop();
   nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
   aWindow->SizeOfIncludingThis(&windowSizes);
 
   if (docShell && aWindow->IsFrozen()) {
@@ -194,55 +187,67 @@ CollectWindowReports(nsGlobalWindow *aWi
   } else {
     // Combine all outer windows per section (active/cached/other) as
     // they basically never contain anything of interest, and are
     // always pretty much the same size.
 
     windowPath += NS_LITERAL_CSTRING("outer-windows");
   }
 
-  if (windowSizes.mDOM > 0) {
-    nsCAutoString domPath(windowPath);
-    domPath += "/dom";
-    NS_NAMED_LITERAL_CSTRING(kWindowDesc,
-                             "Memory used by a window and the DOM within it.");
-    aCb->Callback(EmptyCString(), domPath, nsIMemoryReporter::KIND_HEAP,
-                  nsIMemoryReporter::UNITS_BYTES, windowSizes.mDOM,
-                  kWindowDesc, aClosure);
-    aWindowTotals->mDom += windowSizes.mDOM;
-  }
+#define REPORT(_path1, _path2, _amount, _desc)                                \
+  do {                                                                        \
+    if (_amount > 0) {                                                        \
+        nsCAutoString path(_path1);                                           \
+        path += _path2;                                                       \
+        aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP,     \
+                      nsIMemoryReporter::UNITS_BYTES, _amount,                \
+                      NS_LITERAL_CSTRING(_desc), aClosure);                   \
+    }                                                                         \
+  } while (0)
+
+  REPORT(windowPath, "/dom", windowSizes.mDOM,
+         "Memory used by a window and the DOM within it.");
+  aWindowTotalSizes->mDOM += windowSizes.mDOM;
 
-  if (windowSizes.mStyleSheets > 0) {
-    nsCAutoString styleSheetsPath(windowPath);
-    styleSheetsPath += "/style-sheets";
-    NS_NAMED_LITERAL_CSTRING(kStyleSheetsDesc,
-                             "Memory used by style sheets within a window.");
-    aCb->Callback(EmptyCString(), styleSheetsPath,
-                  nsIMemoryReporter::KIND_HEAP,
-                  nsIMemoryReporter::UNITS_BYTES, windowSizes.mStyleSheets,
-                  kStyleSheetsDesc, aClosure);
-    aWindowTotals->mStyleSheets += windowSizes.mStyleSheets;
-  }
+  REPORT(windowPath, "/style-sheets", windowSizes.mStyleSheets,
+         "Memory used by style sheets within a window.");
+  aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
+
+  REPORT(windowPath, "/layout/arenas", windowSizes.mLayoutArenas,
+         "Memory used by layout PresShell, PresContext, and other related "
+         "areas within a window.");
+  aWindowTotalSizes->mLayoutArenas += windowSizes.mLayoutArenas;
+
+  REPORT(windowPath, "/layout/style-sets", windowSizes.mLayoutStyleSets,
+         "Memory used by style sets within a window.");
+  aWindowTotalSizes->mLayoutStyleSets += windowSizes.mLayoutStyleSets;
+
+  REPORT(windowPath, "/layout/text-runs", windowSizes.mLayoutTextRuns,
+         "Memory used for text-runs (glyph layout) in the PresShell's frame "
+         "tree, within a window.");
+  aWindowTotalSizes->mLayoutTextRuns += windowSizes.mLayoutTextRuns;
+
+#undef REPORT
 }
 
 typedef nsTArray< nsRefPtr<nsGlobalWindow> > WindowArray;
 
 static
 PLDHashOperator
 GetWindows(const PRUint64& aId, nsGlobalWindow*& aWindow, void* aClosure)
 {
   ((WindowArray *)aClosure)->AppendElement(aWindow);
 
   return PL_DHASH_NEXT;
 }
 
 NS_IMETHODIMP
 nsDOMMemoryMultiReporter::GetName(nsACString &aName)
 {
-  aName.AssignLiteral("dom+style");
+  aName.AssignLiteral("window-objects");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
                                          nsISupports* aClosure)
 {
   nsGlobalWindow::WindowByIdTable* windowsById =
@@ -252,37 +257,52 @@ nsDOMMemoryMultiReporter::CollectReports
   // Hold on to every window in memory so that window objects can't be
   // destroyed while we're calling the memory reporter callback.
   WindowArray windows;
   windowsById->Enumerate(GetWindows, &windows);
 
   // Collect window memory usage.
   nsRefPtr<nsGlobalWindow> *w = windows.Elements();
   nsRefPtr<nsGlobalWindow> *end = w + windows.Length();
-  WindowTotals windowTotals;
+  nsWindowSizes windowTotalSizes(NULL);
   for (; w != end; ++w) {
-    CollectWindowReports(*w, &windowTotals, aCb, aClosure);
+    CollectWindowReports(*w, &windowTotalSizes, aCb, aClosure);
   }
 
-  NS_NAMED_LITERAL_CSTRING(kDomTotalWindowsDesc,
-    "Memory used for the DOM within windows.  This is the sum of all windows' "
-    "'dom' numbers.");
-  aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("dom-total-window"),
-                nsIMemoryReporter::KIND_OTHER,
-                nsIMemoryReporter::UNITS_BYTES, windowTotals.mDom,
-                kDomTotalWindowsDesc, aClosure);
+#define REPORT(_path, _amount, _desc)                                         \
+  do {                                                                        \
+    aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path),                  \
+                  nsIMemoryReporter::KIND_OTHER,                              \
+                  nsIMemoryReporter::UNITS_BYTES, _amount,                    \
+                  NS_LITERAL_CSTRING(_desc), aClosure);                       \
+  } while (0)
 
-  NS_NAMED_LITERAL_CSTRING(kLayoutTotalWindowStyleSheetsDesc,
-    "Memory used for style sheets within windows.  This is the sum of all windows' "
-    "'style-sheets' numbers.");
-  aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("style-sheets-total-window"),
-                nsIMemoryReporter::KIND_OTHER,
-                nsIMemoryReporter::UNITS_BYTES, windowTotals.mStyleSheets,
-                kLayoutTotalWindowStyleSheetsDesc, aClosure);
+  REPORT("window-objects-dom", windowTotalSizes.mDOM, 
+         "Memory used for the DOM within windows. "
+         "This is the sum of all windows' 'dom' numbers.");
+    
+  REPORT("window-objects-style-sheets", windowTotalSizes.mStyleSheets, 
+         "Memory used for style sheets within windows. "
+         "This is the sum of all windows' 'style-sheets' numbers.");
+    
+  REPORT("window-objects-layout-arenas", windowTotalSizes.mLayoutArenas, 
+         "Memory used by layout PresShell, PresContext, and other related "
+         "areas within windows. This is the sum of all windows' "
+         "'layout/arenas' numbers.");
+    
+  REPORT("window-objects-layout-style-sets", windowTotalSizes.mLayoutStyleSets, 
+         "Memory used for style sets within windows. "
+         "This is the sum of all windows' 'layout/style-sets' numbers.");
+    
+  REPORT("window-objects-layout-text-runs", windowTotalSizes.mLayoutTextRuns, 
+         "Memory used for text runs within windows. "
+         "This is the sum of all windows' 'layout/text-runs' numbers.");
 
+#undef REPORT
+    
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMMemoryMultiReporter::GetExplicitNonHeap(PRInt64* aAmount)
 {
   // This reporter only measures heap memory.
   *aAmount = 0;
--- a/dom/base/nsDOMMemoryReporter.h
+++ b/dom/base/nsDOMMemoryReporter.h
@@ -44,24 +44,26 @@
 // that it needs to measure;  any sub-class that doesn't use it will inherit
 // SizeOfExcludingThis from its super-class.  SizeOfIncludingThis() need not be
 // defined, it is inherited from nsINode.
 #define NS_DECL_SIZEOF_EXCLUDING_THIS \
   virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
 class nsWindowSizes {
 public:
-    nsWindowSizes(nsMallocSizeOfFun aMallocSizeOf)
-    : mMallocSizeOf(aMallocSizeOf),
-      mDOM(0),
-      mStyleSheets(0)
-    {}
+    nsWindowSizes(nsMallocSizeOfFun aMallocSizeOf) {
+      memset(this, 0, sizeof(nsWindowSizes));
+      mMallocSizeOf = aMallocSizeOf;
+    }
     nsMallocSizeOfFun mMallocSizeOf;
     size_t mDOM;
     size_t mStyleSheets;
+    size_t mLayoutArenas;
+    size_t mLayoutStyleSets;
+    size_t mLayoutTextRuns;
 };
 
 class nsDOMMemoryMultiReporter: public nsIMemoryMultiReporter
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIMEMORYMULTIREPORTER
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -139,18 +139,18 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mRetargetToElement;
   bool mPreventDrag;
   nsIContent* mContent;
 } CapturingContentInfo;
 
 #define NS_IPRESSHELL_IID    \
-        { 0x87719fd6, 0xe50c, 0x4d72, \
-          { 0xbd, 0x55, 0x05, 0xf9, 0x5f, 0x33, 0x9e, 0xf2 } }
+        { 0x4dc4db09, 0x03d4, 0x4427, \
+          { 0xbe, 0xfb, 0xc9, 0x29, 0xac, 0x5c, 0x62, 0xab } }
 
 // Constants for ScrollContentIntoView() function
 #define NS_PRESSHELL_SCROLL_TOP      0
 #define NS_PRESSHELL_SCROLL_BOTTOM   100
 #define NS_PRESSHELL_SCROLL_LEFT     0
 #define NS_PRESSHELL_SCROLL_RIGHT    100
 #define NS_PRESSHELL_SCROLL_CENTER   50
 #define NS_PRESSHELL_SCROLL_ANYWHERE -1
@@ -1171,16 +1171,21 @@ public:
    * root pres shell.
    */
   virtual void DidPaint() = 0;
   virtual void ScheduleViewManagerFlush() = 0;
   virtual void ClearMouseCaptureOnView(nsIView* aView) = 0;
   virtual bool IsVisible() = 0;
   virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;
 
+  virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
+                                   size_t *aArenasSize,
+                                   size_t *aStyleSetsSize,
+                                   size_t *aTextRunsSize) const = 0;
+
   /**
    * Refresh observer management.
    */
 protected:
   virtual bool AddRefreshObserverExternal(nsARefreshObserver* aObserver,
                                             mozFlushType aFlushType);
   bool AddRefreshObserverInternal(nsARefreshObserver* aObserver,
                                     mozFlushType aFlushType);
@@ -1278,20 +1283,16 @@ protected:
   // re-use old pixels.
   PRUint32                  mRenderFlags;
 
   // Used to force allocation and rendering of proportionally more or
   // less pixels in the given dimension.
   float                     mXResolution;
   float                     mYResolution;
 
-  // Live pres shells, for memory and other tracking
-  typedef nsPtrHashKey<nsIPresShell> PresShellPtrKey;
-  static nsTHashtable<PresShellPtrKey> *sLiveShells;
-
   static nsIContent* gKeyDownTarget;
 };
 
 /**
  * Create a new empty presentation shell. Upon success, call Init
  * before attempting to use the shell.
  */
 nsresult
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -196,19 +196,16 @@
 #include "nsPlaceholderFrame.h"
 #include "nsCanvasFrame.h"
 
 // Content viewer interfaces
 #include "nsIContentViewer.h"
 #include "imgIEncoder.h"
 #include "gfxPlatform.h"
 
-/* for NS_MEMORY_REPORTER_IMPLEMENT */
-#include "nsIMemoryReporter.h"
-
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "sampler.h"
 
 #include "Layers.h"
 #include "nsAsyncDOMEvent.h"
 
@@ -603,123 +600,16 @@ struct nsCallbackEventRequest
 };
 
 // ----------------------------------------------------------------------------
 #define ASSERT_REFLOW_SCHEDULED_STATE()                                       \
   NS_ASSERTION(mReflowScheduled ==                                            \
                  GetPresContext()->RefreshDriver()->                          \
                    IsLayoutFlushObserver(this), "Unexpected state")
 
-NS_IMPL_ISUPPORTS1(PresShell::MemoryReporter, nsIMemoryMultiReporter)
-
-namespace {
-
-struct MemoryReporterData
-{
-  nsIMemoryMultiReporterCallback* callback;
-  nsISupports* closure;
-};
-
-} // anonymous namespace
-
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutMallocSizeOf, "layout")
-
-/* 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.");
-  NS_NAMED_LITERAL_CSTRING(kTextRunsDesc, "Memory used for text-runs (glyph layout) in the PresShell's frame tree.");
-
-  nsCAutoString arenaPath = str + NS_LITERAL_CSTRING("/arenas");
-  nsCAutoString stylePath = str + NS_LITERAL_CSTRING("/styledata");
-  nsCAutoString textRunsPath = str + NS_LITERAL_CSTRING("/textruns");
-
-  PRInt64 arenasSize =
-    aShell->SizeOfIncludingThis(LayoutMallocSizeOf) +
-    aShell->mPresContext->SizeOfIncludingThis(LayoutMallocSizeOf);
-
-  PRInt64 styleSize =
-    aShell->StyleSet()->SizeOfIncludingThis(LayoutMallocSizeOf);
-
-  PRInt64 textRunsSize = aShell->SizeOfTextRuns(LayoutMallocSizeOf);
-
-  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);
-
-  if (textRunsSize) {
-    data->callback->
-      Callback(EmptyCString(), textRunsPath, nsIMemoryReporter::KIND_HEAP,
-               nsIMemoryReporter::UNITS_BYTES, textRunsSize, kTextRunsDesc,
-               data->closure);
-  }
-
-  return PL_DHASH_NEXT;
-}
-
-NS_IMETHODIMP
-PresShell::MemoryReporter::GetName(nsACString &aName)
-{
-  aName.AssignLiteral("layout");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PresShell::MemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
-                                          nsISupports* aClosure)
-{
-  MemoryReporterData data;
-  data.callback = aCb;
-  data.closure = aClosure;
-
-  sLiveShells->EnumerateEntries(SizeEnumerator, &data);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PresShell::MemoryReporter::GetExplicitNonHeap(PRInt64 *aAmount) {
-  // This reporter doesn't do any KIND_NONHEAP measurements.
-  *aAmount = 0;
-  return NS_OK;
-}
-
 class nsAutoCauseReflowNotifier
 {
 public:
   nsAutoCauseReflowNotifier(PresShell* aShell)
     : mShell(aShell)
   {
     mShell->WillCauseReflow();
   }
@@ -910,17 +800,16 @@ NS_NewPresShell(nsIPresShell** aInstance
     return NS_ERROR_NULL_POINTER;
 
   *aInstancePtrResult = new PresShell();
 
   NS_ADDREF(*aInstancePtrResult);
   return NS_OK;
 }
 
-nsTHashtable<PresShell::PresShellPtrKey> *nsIPresShell::sLiveShells = 0;
 static bool sSynthMouseMove = true;
 
 PresShell::PresShell()
   : mMouseLocation(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)
 {
   mSelection = nsnull;
 #ifdef MOZ_REFLOW_PERF
   mReflowCountMgr = new ReflowCountMgr();
@@ -938,36 +827,31 @@ PresShell::PresShell()
 #ifdef DEBUG
   mPresArenaAllocCount = 0;
 #endif
   mRenderFlags = 0;
   mXResolution = 1.0;
   mYResolution = 1.0;
   mViewportOverridden = false;
 
-  static bool registeredReporter = false;
-  if (!registeredReporter) {
-    NS_RegisterMemoryMultiReporter(new MemoryReporter);
+  static bool addedSynthMouseMove = false;
+  if (!addedSynthMouseMove) {
     Preferences::AddBoolVarCache(&sSynthMouseMove,
                                  "layout.reflow.synthMouseMove", true);
-    registeredReporter = true;
-  }
-
-  sLiveShells->PutEntry(this);
+    addedSynthMouseMove = true;
+  }
 }
 
 NS_IMPL_ISUPPORTS7(PresShell, nsIPresShell, nsIDocumentObserver,
                    nsISelectionController,
                    nsISelectionDisplay, nsIObserver, nsISupportsWeakReference,
                    nsIMutationObserver)
 
 PresShell::~PresShell()
 {
-  sLiveShells->RemoveEntry(this);
-
   if (!mHaveShutDown) {
     NS_NOTREACHED("Someone did not call nsIPresShell::destroy");
     Destroy();
   }
 
   NS_ASSERTION(mCurrentEventContentStack.Count() == 0,
                "Huh, event content left on the stack in pres shell dtor!");
   NS_ASSERTION(mFirstCallbackEventRequest == nsnull &&
@@ -9080,29 +8964,28 @@ nsIPresShell::IsAccessibilityActive()
 
 nsAccessibilityService*
 nsIPresShell::AccService()
 {
   return GetAccService();
 }
 #endif
 
+static bool inited = false;
+
 void nsIPresShell::InitializeStatics()
 {
-  NS_ASSERTION(sLiveShells == nsnull, "InitializeStatics called multiple times!");
-  sLiveShells = new nsTHashtable<PresShellPtrKey>();
-  sLiveShells->Init();
+  NS_ASSERTION(!inited, "InitializeStatics called multiple times!");
   gCaptureTouchList.Init();
+  inited = true;
 }
 
 void nsIPresShell::ReleaseStatics()
 {
-  NS_ASSERTION(sLiveShells, "ReleaseStatics called without Initialize!");
-  delete sLiveShells;
-  sLiveShells = nsnull;
+  NS_ASSERTION(inited, "ReleaseStatics called without Initialize!");
 }
 
 // Asks our docshell whether we're active.
 void PresShell::QueryIsActive()
 {
   nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
   if (mDocument) {
     nsIDocument* displayDoc = mDocument->GetDisplayDocument();
@@ -9198,18 +9081,33 @@ PresShell::GetRootPresShell()
     nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
     if (rootPresContext) {
       return static_cast<PresShell*>(rootPresContext->PresShell());
     }
   }
   return nsnull;
 }
 
+void
+PresShell::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
+                               size_t *aArenasSize,
+                               size_t *aStyleSetsSize,
+                               size_t *aTextRunsSize) const
+{
+  *aArenasSize = aMallocSizeOf(this);
+  *aArenasSize += mStackArena.SizeOfExcludingThis(aMallocSizeOf);
+  *aArenasSize += mFrameArena.SizeOfExcludingThis(aMallocSizeOf);
+
+  *aStyleSetsSize = StyleSet()->SizeOfIncludingThis(aMallocSizeOf);
+
+  *aTextRunsSize = SizeOfTextRuns(aMallocSizeOf);
+}
+
 size_t
-PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf)
+PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const
 {
   nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
   if (!rootFrame) {
     return 0;
   }
 
   // clear the TEXT_RUN_MEMORY_ACCOUNTED flags
   nsLayoutUtils::SizeOfTextRunsForFrames(rootFrame, nsnull,
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -896,36 +896,21 @@ private:
 private:
 #ifdef DEBUG
   // Ensure that every allocation from the PresArena is eventually freed.
   PRUint32 mPresArenaAllocCount;
 #endif
 
 public:
 
-  size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
-    size_t n = 0;
-
-    n += aMallocSizeOf(this);
-    n += mStackArena.SizeOfExcludingThis(aMallocSizeOf);
-    n += mFrameArena.SizeOfExcludingThis(aMallocSizeOf);
-
-    return n;
-  }
-
-  size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf);
-
-  class MemoryReporter : public nsIMemoryMultiReporter
-  {
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIMEMORYMULTIREPORTER
-  protected:
-    static PLDHashOperator SizeEnumerator(PresShellPtrKey *aEntry, void *userArg);
-  };
+  void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
+                           size_t *aArenasSize,
+                           size_t *aStyleSetsSize,
+                           size_t *aTextRunsSize) const;
+  size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
 
 protected:
   void QueryIsActive();
   nsresult UpdateImageLockingState();
 
 private:
   nscolor GetDefaultBackgroundColorToDraw();
 };
--- a/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
+++ b/toolkit/components/aboutmemory/tests/test_memoryReporters.xul
@@ -39,18 +39,17 @@
   let vsizeAmounts = [];
   let residentAmounts = [];
   let jsGcHeapAmounts = [];
   let heapAllocatedAmounts = [];
   let storageSqliteAmounts = [];
 
   let areJsCompartmentsPresent = false;
   let isSandboxLocationShown = false;
-  let areLayoutShellsPresent = false;
-  let areDomInnerWindowsPresent = false;
+  let areInnerWindowsPresent = false;
   let isPlacesPresent = false;
   let isImagesPresent = false;
   let isXptiWorkingSetPresent = false;
   let isAtomTablePresent = false;
 
   let mySandbox = Components.utils.Sandbox(document.nodePrincipal,
                     { sandboxName: "this-is-a-sandbox-name" });
 
@@ -68,20 +67,18 @@
     } else if (aPath === "heap-allocated") {
       heapAllocatedAmounts.push(aAmount);
     } else if (aPath === "storage-sqlite") {
       storageSqliteAmounts.push(aAmount);
 
     // Check the presence of some other notable reporters.
     } else if (aPath.search(/^explicit\/js\/compartment\(/) >= 0) {
       areJsCompartmentsPresent = true;
-    } else if (aPath.search(/^explicit\/layout\/shell\(/) >= 0) {
-      areLayoutShellsPresent = true;
-    } else if (aPath.search(/^explicit\/dom\+style\/window-objects\/.*inner-window\(/) >= 0) {
-      areDomInnerWindowsPresent = true;
+    } else if (aPath.search(/^explicit\/window-objects\/.*inner-window\(/) >= 0) {
+      areInnerWindowsPresent = true;
     } else if (aPath.search(/^explicit\/storage\/sqlite\/places.sqlite/) >= 0) {
       isPlacesPresent = true;
     } else if (aPath.search(/^explicit\/images/) >= 0) {
       isImagesPresent = true;
     } else if (aPath.search(/^explicit\/xpti-working-set$/) >= 0) {
       isXptiWorkingSetPresent = true;
     } else if (aPath.search(/^explicit\/atom-table$/) >= 0) {
       isAtomTablePresent = true;
@@ -129,18 +126,17 @@
   checkSpecialReport("vsize",          vsizeAmounts);
   checkSpecialReport("resident",       residentAmounts);
   checkSpecialReport("js-gc-heap",     jsGcHeapAmounts);
   checkSpecialReport("heap-allocated", heapAllocatedAmounts);
   checkSpecialReport("storage-sqlite", storageSqliteAmounts);
 
   ok(areJsCompartmentsPresent,  "js compartments are present");
   ok(isSandboxLocationShown,    "sandbox locations are present");
-  ok(areLayoutShellsPresent,    "layout shells are present");
-  ok(areDomInnerWindowsPresent, "dom inner-windows are present");
+  ok(areInnerWindowsPresent,    "inner-windows are present");
   ok(isPlacesPresent,           "places is present");
   ok(isImagesPresent,           "images is present");
   ok(isXptiWorkingSetPresent,   "xpti-working-set is present");
   ok(isAtomTablePresent,        "atom-table is present");
 
   ]]>
   </script>
 </window>