Bug 676048: Report RuleCascadeData and substructures to about:memory. r=bz
authorKyle Huey <khuey@kylehuey.com>
Tue, 02 Aug 2011 16:21:52 -0400
changeset 73691 f185f48d35dc966aff08536b6c599319731271a9
parent 73688 aca5afbed1883d081218aeb1d99c6f6ef5cfa2ba
child 73692 7813728d68ff9c96278d6612c62268b9f0179671
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersbz
bugs676048
milestone8.0a1
Bug 676048: Report RuleCascadeData and substructures to about:memory. r=bz
layout/style/nsCSSRuleProcessor.cpp
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -386,16 +386,18 @@ class RuleHash {
 public:
   RuleHash(PRBool aQuirksMode);
   ~RuleHash();
   void AppendRule(const RuleSelectorPair &aRuleInfo);
   void EnumerateAllRules(Element* aElement, RuleProcessorData* aData,
                          NodeMatchContext& aNodeMatchContext);
   PLArenaPool& Arena() { return mArena; }
 
+  PRInt64 SizeOf() const;
+
 protected:
   typedef nsTArray<RuleValue> RuleValueList;
   void AppendRuleToTable(PLDHashTable* aTable, const void* aKey,
                          const RuleSelectorPair& aRuleInfo);
   void AppendUniversalRule(const RuleSelectorPair& aRuleInfo);
 
   PRInt32     mRuleCount;
   PLDHashTable mIdTable;
@@ -691,16 +693,55 @@ void RuleHash::EnumerateAllRules(Element
     for (const RuleValue *value = mEnumList[0].mCurValue,
                          *end = mEnumList[0].mEnd;
          value != end; ++value) {
       ContentEnumFunc(value->mRule, value->mSelector, aData, aNodeContext);
     }
   }
 }
 
+static PLDHashOperator
+RuleHashTableSizeOfEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
+                              PRUint32 i, void* aClosure)
+{
+  PRInt64* n = static_cast<PRInt64*>(aClosure);
+  RuleHashTableEntry* entry = static_cast<RuleHashTableEntry*>(aHdr);
+
+  *n += entry->mRules.SizeOf();
+  // The size of the RuleHashTableEntry itself is accounted for already
+
+  return PL_DHASH_NEXT;
+}
+
+PRInt64
+RuleHash::SizeOf() const
+{
+  PRInt64 n = sizeof(*this);
+
+  n += PL_DHASH_TABLE_SIZE(&mIdTable) * sizeof(RuleHashTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mIdTable),
+                         RuleHashTableSizeOfEnumerator, &n);
+
+  n += PL_DHASH_TABLE_SIZE(&mClassTable) * sizeof(RuleHashTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mClassTable),
+                         RuleHashTableSizeOfEnumerator, &n);
+
+  n += PL_DHASH_TABLE_SIZE(&mTagTable) * sizeof(RuleHashTagTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mTagTable),
+                         RuleHashTableSizeOfEnumerator, &n);
+
+  n += PL_DHASH_TABLE_SIZE(&mNameSpaceTable) * sizeof(RuleHashTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mNameSpaceTable),
+                         RuleHashTableSizeOfEnumerator, &n);
+
+  n += mUniversalRules.SizeOf();
+
+  return n;
+}
+
 //--------------------------------
 
 // Attribute selectors hash table.
 struct AttributeSelectorEntry : public PLDHashEntryHdr {
   nsIAtom *mAttribute;
   nsTArray<nsCSSSelector*> *mSelectors;
 };
 
@@ -823,16 +864,19 @@ struct RuleCascadeData {
     PL_DHashTableFinish(&mClassSelectors);
 #ifdef MOZ_XUL
     PL_DHashTableFinish(&mXULTreeRules);
 #endif
     for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
       delete mPseudoElementRuleHashes[i];
     }
   }
+
+  PRInt64 SizeOf() const;
+
   RuleHash                 mRuleHash;
   RuleHash*
     mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount];
   nsTArray<nsCSSSelector*> mStateSelectors;
   nsEventStates            mSelectorDocumentStates;
   PLDHashTable             mClassSelectors;
   PLDHashTable             mIdSelectors;
   nsTArray<nsCSSSelector*> mPossiblyNegatedClassSelectors;
@@ -851,16 +895,84 @@ struct RuleCascadeData {
   nsTArray<nsCSSSelector*>* AttributeListFor(nsIAtom* aAttribute);
 
   nsMediaQueryResultCacheKey mCacheKey;
   RuleCascadeData*  mNext; // for a different medium
 
   const PRBool mQuirksMode;
 };
 
+static PLDHashOperator
+SelectorsSizeOfEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
+                          PRUint32 i, void* aClosure)
+{
+  PRInt64* n = (PRInt64*) aClosure;
+  AtomSelectorEntry* entry = (AtomSelectorEntry*)aHdr;
+
+  *n += entry->mSelectors.SizeOf();
+
+  return PL_DHASH_NEXT;
+}
+
+static PLDHashOperator
+AttrSelectorsSizeOfEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aHdr,
+                              PRUint32 i, void* aClosure)
+{
+  PRInt64* n = (PRInt64*) aClosure;
+  AttributeSelectorEntry* entry = (AttributeSelectorEntry*)aHdr;
+
+  if (entry->mSelectors)
+    *n += entry->mSelectors->SizeOf() + sizeof(*entry->mSelectors);
+
+  return PL_DHASH_NEXT;
+}
+
+PRInt64
+RuleCascadeData::SizeOf() const
+{
+  PRInt64 n = sizeof(*this);
+
+  n += mRuleHash.SizeOf();
+  for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) {
+    if (mPseudoElementRuleHashes[i])
+      n += mPseudoElementRuleHashes[i]->SizeOf();
+  }
+
+  n += mStateSelectors.SizeOf();
+
+  n += PL_DHASH_TABLE_SIZE(&mIdSelectors) * sizeof(AtomSelectorEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mIdSelectors),
+                         SelectorsSizeOfEnumerator, &n);
+  n += PL_DHASH_TABLE_SIZE(&mClassSelectors) * sizeof(AtomSelectorEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mClassSelectors),
+                         SelectorsSizeOfEnumerator, &n);
+
+  n += mPossiblyNegatedClassSelectors.SizeOf();
+  n += mPossiblyNegatedIDSelectors.SizeOf();
+
+  n += PL_DHASH_TABLE_SIZE(&mAttributeSelectors) * sizeof(AttributeSelectorEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mAttributeSelectors),
+                         AttrSelectorsSizeOfEnumerator, &n);
+
+  n += PL_DHASH_TABLE_SIZE(&mAnonBoxRules) * sizeof(RuleHashTagTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mAnonBoxRules),
+                         RuleHashTableSizeOfEnumerator, &n);
+
+#ifdef MOZ_XUL
+  n += PL_DHASH_TABLE_SIZE(&mXULTreeRules) * sizeof(RuleHashTagTableEntry);
+  PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&mAnonBoxRules),
+                         RuleHashTableSizeOfEnumerator, &n);
+#endif
+
+  n += mFontFaceRules.SizeOf();
+  n += mKeyframesRules.SizeOf();
+
+  return n;
+}
+
 nsTArray<nsCSSSelector*>*
 RuleCascadeData::AttributeListFor(nsIAtom* aAttribute)
 {
   AttributeSelectorEntry *entry = static_cast<AttributeSelectorEntry*>
                                              (PL_DHashTableOperate(&mAttributeSelectors, aAttribute, PL_DHASH_ADD));
   if (!entry)
     return nsnull;
   if (!entry->mSelectors) {
@@ -2452,17 +2564,23 @@ nsCSSRuleProcessor::MediumFeaturesChange
     RefreshRuleCascade(aPresContext);
   }
   return (old != mRuleCascades);
 }
 
 /* virtual */ PRInt64
 nsCSSRuleProcessor::SizeOf() const
 {
-  size_t n = sizeof(*this);
+  PRInt64 n = sizeof(*this);
+
+  n += mSheets.SizeOf();
+  for (RuleCascadeData* cascade = mRuleCascades; cascade;
+       cascade = cascade->mNext) {
+    n += cascade->SizeOf();
+  }
 
   return n;
 }
 
 // Append all the currently-active font face rules to aArray.  Return
 // true for success and false for failure.
 PRBool
 nsCSSRuleProcessor::AppendFontFaceRules(