Bug 799796. Do memory reporting for stylesheets that only the CSS loader might know about. r=dbaron,njn
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 17 Oct 2012 17:01:56 -0400
changeset 110728 557cfb0bdc396835d11d6d1f62316fbd92df96cf
parent 110727 fd12a2c69e93b58cb79f6c3d0482d3df6943397d
child 110729 3f603fdf63564ea2b9eb1b5ed1ebf98263b990fb
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersdbaron, njn
bugs799796
milestone19.0a1
Bug 799796. Do memory reporting for stylesheets that only the CSS loader might know about. r=dbaron,njn
content/base/src/nsDocument.cpp
layout/style/Loader.cpp
layout/style/Loader.h
layout/style/nsCSSStyleSheet.h
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -10060,16 +10060,33 @@ nsDocument::DocSizeOfExcludingThis(nsWin
     }
 
     *p += nodeSize;
   }
 
   aWindowSizes->mStyleSheets +=
     mStyleSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
                                      aWindowSizes->mMallocSizeOf);
+  aWindowSizes->mStyleSheets +=
+    mCatalogSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
+                                       aWindowSizes->mMallocSizeOf);
+  aWindowSizes->mStyleSheets +=
+    mAdditionalSheets[eAgentSheet].
+      SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
+                          aWindowSizes->mMallocSizeOf);
+  aWindowSizes->mStyleSheets +=
+    mAdditionalSheets[eUserSheet].
+      SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
+                          aWindowSizes->mMallocSizeOf);
+  // Lumping in the loader with the style-sheets size is not ideal,
+  // but most of the things in there are in fact stylesheets, so it
+  // doesn't seem worthwhile to separate it out.
+  aWindowSizes->mStyleSheets +=
+    CSSLoader()->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf);
+
   aWindowSizes->mDOMOther +=
     mAttrStyleSheet ?
     mAttrStyleSheet->DOMSizeOfIncludingThis(aWindowSizes->mMallocSizeOf) :
     0;
 
   aWindowSizes->mDOMOther +=
     mStyledLinks.SizeOfExcludingThis(NULL, aWindowSizes->mMallocSizeOf);
 
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -2414,10 +2414,54 @@ Loader::TraverseCachedSheets(nsCycleColl
 void
 Loader::UnlinkCachedSheets()
 {
   if (mCompleteSheets.IsInitialized()) {
     mCompleteSheets.Clear();
   }
 }
 
+struct SheetMemoryCounter {
+  size_t size;
+  nsMallocSizeOfFun mallocSizeOf;
+};
+
+static size_t
+CountSheetMemory(URIPrincipalAndCORSModeHashKey* /* unused */,
+                 const nsRefPtr<nsCSSStyleSheet>& aSheet,
+                 nsMallocSizeOfFun aMallocSizeOf,
+                 void* /* unused */)
+{
+  // If aSheet has a parent, then its parent will report it so we don't
+  // have to worry about it here.
+  // Likewise, if aSheet has an owning node, then the document that
+  // node is in will report it.
+  if (aSheet->GetOwningNode() || aSheet->GetParentSheet()) {
+    return 0;
+  }
+  return aSheet->SizeOfIncludingThis(aMallocSizeOf);
+}
+
+size_t
+Loader::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+  size_t s = aMallocSizeOf(this);
+
+  s += mCompleteSheets.SizeOfExcludingThis(CountSheetMemory, aMallocSizeOf);
+
+  s += mObservers.SizeOfExcludingThis(aMallocSizeOf);
+
+  // Measurement of the following members may be added later if DMD finds it is
+  // worthwhile:
+  // - mLoadingDatas: transient, and should be small
+  // - mPendingDatas: transient, and should be small
+  // - mParsingDatas: transient, and should be small
+  // - mPostedEvents: transient, and should be small
+  //
+  // The following members aren't measured:
+  // - mDocument, because it's a weak backpointer
+  // - mPreferredSheet, because it can be a shared string
+
+  return s;
+}
+
 } // namespace css
 } // namespace mozilla
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -355,16 +355,19 @@ public:
   // Traverse the cached stylesheets we're holding on to.  This should
   // only be called from the document that owns this loader.
   void TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb);
 
   // Unlink the cached stylesheets we're holding on to.  Again, this
   // should only be called from the document that owns this loader.
   void UnlinkCachedSheets();
 
+  // Measure our size.
+  size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
+
 private:
   friend class SheetLoadData;
 
   // Note: null aSourcePrincipal indicates that the content policy and
   // CheckLoadURI checks should be skipped.
   nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
                             nsIURI* aTargetURI,
                             nsISupports* aContext);
--- a/layout/style/nsCSSStyleSheet.h
+++ b/layout/style/nsCSSStyleSheet.h
@@ -172,16 +172,17 @@ public:
   nsIPrincipal* Principal() const { return mInner->mPrincipal; }
 
   // The document this style sheet is associated with.  May be null
   nsIDocument* GetDocument() const { return mDocument; }
 
   void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
   void SetMedia(nsMediaList* aMedia);
   void SetOwningNode(nsIDOMNode* aOwningNode) { mOwningNode = aOwningNode; /* Not ref counted */ }
+  nsIDOMNode* GetOwningNode() const { return mOwningNode; }
 
   void SetOwnerRule(mozilla::css::ImportRule* aOwnerRule) { mOwnerRule = aOwnerRule; /* Not ref counted */ }
   mozilla::css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
 
   nsXMLNameSpaceMap* GetNameSpaceMap() const { return mInner->mNameSpaceMap; }
 
   already_AddRefed<nsCSSStyleSheet> Clone(nsCSSStyleSheet* aCloneParent,
                                           mozilla::css::ImportRule* aCloneOwnerRule,