From 9657bf7bed7853e09e83f7592c36439a0bea3091 Mon Sep 17 00:00:00 2001 From: "attinasi%netscape.com" Date: Fri, 31 Mar 2000 07:08:36 +0000 Subject: [PATCH] Implemented Style Size Dump. r=rickg b=26565 git-svn-id: svn://10.0.0.236/trunk@64709 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/public/nsIStyleRule.h | 5 + .../base/public/nsIStyleRuleProcessor.h | 4 + mozilla/content/base/public/nsIStyleSheet.h | 5 + mozilla/content/base/src/nsStyleContext.cpp | 152 +++++++- mozilla/content/base/src/nsStyleSet.cpp | 246 +++++++++++- .../html/content/src/nsGenericHTMLElement.cpp | 2 +- .../html/content/src/nsHTMLBodyElement.cpp | 87 +++++ .../html/style/src/nsCSSDeclaration.cpp | 109 +++++- mozilla/content/html/style/src/nsCSSProps.h | 4 + mozilla/content/html/style/src/nsCSSRules.cpp | 196 ++++++++++ .../content/html/style/src/nsCSSStruct.cpp | 109 +++++- .../content/html/style/src/nsCSSStyleRule.cpp | 303 ++++++++++++++- .../html/style/src/nsCSSStyleSheet.cpp | 367 +++++++++++++++++- .../html/style/src/nsHTMLAttributes.cpp | 73 ++-- .../html/style/src/nsHTMLCSSStyleSheet.cpp | 96 +++++ .../html/style/src/nsHTMLStyleSheet.cpp | 268 +++++++++++++ .../html/style/src/nsICSSDeclaration.h | 3 + .../content/html/style/src/nsICSSStyleRule.h | 8 +- .../html/style/src/nsIHTMLAttributes.h | 5 +- mozilla/content/shared/public/nsCSSProps.h | 4 + mozilla/content/shared/src/nsCSSProps.cpp | 35 +- .../content/xul/content/src/nsXULElement.cpp | 9 + .../content/xul/content/src/nsXULElement.h | 4 + mozilla/layout/base/public/nsIStyleContext.h | 4 + mozilla/layout/base/public/nsIStyleRule.h | 5 + .../base/public/nsIStyleRuleProcessor.h | 4 + mozilla/layout/base/public/nsIStyleSet.h | 73 ++++ mozilla/layout/base/public/nsIStyleSheet.h | 5 + mozilla/layout/base/src/nsStyleContext.cpp | 152 +++++++- mozilla/layout/base/src/nsStyleSet.cpp | 246 +++++++++++- .../html/content/src/nsGenericHTMLElement.cpp | 2 +- .../html/content/src/nsHTMLBodyElement.cpp | 87 +++++ .../html/style/src/nsCSSDeclaration.cpp | 109 +++++- mozilla/layout/html/style/src/nsCSSProps.cpp | 35 +- mozilla/layout/html/style/src/nsCSSProps.h | 4 + mozilla/layout/html/style/src/nsCSSRules.cpp | 196 ++++++++++ .../layout/html/style/src/nsCSSStyleRule.cpp | 303 ++++++++++++++- .../layout/html/style/src/nsCSSStyleSheet.cpp | 367 +++++++++++++++++- .../html/style/src/nsHTMLAttributes.cpp | 73 ++-- .../html/style/src/nsHTMLCSSStyleSheet.cpp | 96 +++++ .../html/style/src/nsHTMLStyleSheet.cpp | 268 +++++++++++++ .../layout/html/style/src/nsICSSDeclaration.h | 3 + .../layout/html/style/src/nsICSSStyleRule.h | 8 +- .../layout/html/style/src/nsIHTMLAttributes.h | 5 +- mozilla/layout/style/nsCSSDeclaration.cpp | 109 +++++- mozilla/layout/style/nsCSSProps.cpp | 35 +- mozilla/layout/style/nsCSSProps.h | 4 + mozilla/layout/style/nsCSSRules.cpp | 196 ++++++++++ mozilla/layout/style/nsCSSStruct.cpp | 109 +++++- mozilla/layout/style/nsCSSStyleRule.cpp | 303 ++++++++++++++- mozilla/layout/style/nsCSSStyleSheet.cpp | 367 +++++++++++++++++- mozilla/layout/style/nsHTMLCSSStyleSheet.cpp | 96 +++++ mozilla/layout/style/nsHTMLStyleSheet.cpp | 268 +++++++++++++ mozilla/layout/style/nsICSSStyleRule.h | 8 +- mozilla/layout/style/nsIStyleRule.h | 5 + mozilla/layout/style/nsIStyleRuleProcessor.h | 4 + mozilla/layout/style/nsIStyleSheet.h | 5 + mozilla/layout/style/nsStyleContext.cpp | 152 +++++++- mozilla/layout/style/nsStyleSet.cpp | 246 +++++++++++- mozilla/rdf/content/src/nsXULElement.cpp | 9 + mozilla/rdf/content/src/nsXULElement.h | 4 + .../webshell/tests/viewer/nsBrowserWindow.cpp | 45 ++- .../webshell/tests/viewer/nsBrowserWindow.h | 2 +- 63 files changed, 5967 insertions(+), 139 deletions(-) diff --git a/mozilla/content/base/public/nsIStyleRule.h b/mozilla/content/base/public/nsIStyleRule.h index e5107e4d019..4de54696d92 100644 --- a/mozilla/content/base/public/nsIStyleRule.h +++ b/mozilla/content/base/public/nsIStyleRule.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIMutableStyleContext; class nsIPresContext; @@ -51,6 +53,9 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) = 0; NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; }; + #endif /* nsIStyleRule_h___ */ diff --git a/mozilla/content/base/public/nsIStyleRuleProcessor.h b/mozilla/content/base/public/nsIStyleRuleProcessor.h index cedb70bc0d7..b4dafa92e12 100644 --- a/mozilla/content/base/public/nsIStyleRuleProcessor.h +++ b/mozilla/content/base/public/nsIStyleRuleProcessor.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIStyleContext; class nsIPresContext; @@ -67,6 +69,8 @@ public: NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent) = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleRuleProcessor_h___ */ diff --git a/mozilla/content/base/public/nsIStyleSheet.h b/mozilla/content/base/public/nsIStyleSheet.h index 03b4d6bbd5a..023ae19454f 100644 --- a/mozilla/content/base/public/nsIStyleSheet.h +++ b/mozilla/content/base/public/nsIStyleSheet.h @@ -24,6 +24,9 @@ #include #include "nsISupports.h" + +class nsISizeOfHandler; + class nsIAtom; class nsString; class nsIURI; @@ -66,6 +69,8 @@ public: // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleSheet_h___ */ diff --git a/mozilla/content/base/src/nsStyleContext.cpp b/mozilla/content/base/src/nsStyleContext.cpp index a4e66ad78d1..3c6dbc276f2 100644 --- a/mozilla/content/base/src/nsStyleContext.cpp +++ b/mozilla/content/base/src/nsStyleContext.cpp @@ -45,10 +45,18 @@ #include "nsIFrame.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" +#include "nsIPresShell.h" + static NS_DEFINE_IID(kIStyleContextIID, NS_ISTYLECONTEXT_IID); #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; } +//#ifdef DEBUG_SC_SHARING + + // -------------------- // nsStyleFont // @@ -1673,6 +1681,8 @@ public: virtual void List(FILE* out, PRInt32 aIndent); + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: void AppendChild(StyleContextImpl* aChild); void RemoveChild(StyleContextImpl* aChild); @@ -1701,6 +1711,8 @@ protected: StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; + + nsCOMPtr mStyleSet; }; static PRInt32 gLastDataCode; @@ -1748,6 +1760,21 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, if (nsnull != mRules) { mRules->EnumerateForwards(HashStyleRule, &mRuleHash); } + +#ifdef DEBUG_SC_SHARING + // add this instance to the style set + nsIPresShell* shell = nsnull; + aPresContext->GetShell(&shell); + if (shell) { + shell->GetStyleSet( getter_AddRefs(mStyleSet) ); + if (mStyleSet) { + // add it to the set: the set does NOT addref or release + // NOTE: QI here is not a good idea - this is the constructor so we are not whole yet... + mStyleSet->AddStyleContext((nsIStyleContext *)this); + } + NS_RELEASE( shell ); + } +#endif // DEBUG_SC_SHARING } StyleContextImpl::~StyleContextImpl() @@ -1760,8 +1787,14 @@ StyleContextImpl::~StyleContextImpl() } NS_IF_RELEASE(mPseudoTag); - NS_IF_RELEASE(mRules); + +#ifdef DEBUG_SC_SHARING + // remove this instance from the style set (remember, the set does not AddRef or Release us) + if (mStyleSet) { + mStyleSet->RemoveStyleContext((nsIStyleContext *)this); + } +#endif // DEBUG_SC_SHARING } NS_IMPL_ADDREF(StyleContextImpl) @@ -2446,6 +2479,123 @@ void StyleContextImpl::List(FILE* out, PRInt32 aIndent) } } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleContextImpl's size): +* 1) sizeof(*this) which gets all of the data members +* 2) adds in the size of the PseudoTag, if there is one +* +* Contained / Aggregated data (not reported as StyleContextImpl's size): +* 1) the Style Rules in mRules are not counted as part of sizeof(*this) +* (though the size of the nsISupportsArray ptr. is) so we need to +* count the rules seperately. For each rule in the mRules collection +* we call the SizeOf method and let it report itself. +* +* Children / siblings / parents: +* 1) We recurse over the mChild and mEmptyChild instances if they exist. +* These instances will then be accumulated seperately (not part of +* the containing instance's size) +* 2) We recurse over the siblings of the Child and Empty Child instances +* and count then seperately as well. +* 3) We recurse over our direct siblings (if any). +* +******************************************************************************/ +void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + static PRBool bDetailDumpDone = PR_FALSE; + if (!bDetailDumpDone) { + bDetailDumpDone = PR_TRUE; + PRUint32 totalSize=0; + + printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" ); + printf( "*************************************\n"); + printf( " - StyleFontImpl: %ld\n", (long)sizeof(mFont) ); + totalSize += (long)sizeof(mFont); + printf( " - StyleColorImpl: %ld\n", (long)sizeof(mColor) ); + totalSize += (long)sizeof(mColor); + printf( " - StyleSpacingImpl: %ld\n", (long)sizeof(mSpacing) ); + totalSize += (long)sizeof(mSpacing); + printf( " - StyleListImpl: %ld\n", (long)sizeof(mList) ); + totalSize += (long)sizeof(mList); + printf( " - StylePositionImpl: %ld\n", (long)sizeof(mPosition) ); + totalSize += (long)sizeof(mPosition); + printf( " - StyleTextImpl: %ld\n", (long)sizeof(mText) ); + totalSize += (long)sizeof(mText); + printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(mDisplay) ); + totalSize += (long)sizeof(mDisplay); + printf( " - StyleTableImpl: %ld\n", (long)sizeof(mTable) ); + totalSize += (long)sizeof(mTable); + printf( " - StyleContentImpl: %ld\n", (long)sizeof(mContent) ); + totalSize += (long)sizeof(mContent); + printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(mUserInterface) ); + totalSize += (long)sizeof(mUserInterface); + printf( " - StylePrintImpl: %ld\n", (long)sizeof(mPrint)); + totalSize += (long)sizeof(mPrint); + printf( " - Total: %ld\n", (long)totalSize); + printf( "*************************************\n"); + } + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + PRUint32 localSize=0; + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleContextImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add in the size of the member mPseudoTag + if(mPseudoTag){ + mPseudoTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // size up the rules (if not already done) + // XXX - overhead of the collection??? + if(mRules && uniqueItems->AddItem(mRules)){ + PRUint32 curRule, ruleCount; + mRules->Count(&ruleCount); + if (ruleCount > 0) { + for (curRule = 0; curRule < ruleCount; curRule++) { + nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(curRule); + NS_ASSERTION(rule, "null entry in Rules list is bad news"); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } + } + // now follow up with the child (and empty child) recursion + if (nsnull != mChild) { + StyleContextImpl* child = mChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mChild != child); + } + if (nsnull != mEmptyChild) { + StyleContextImpl* child = mEmptyChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mEmptyChild != child); + } + // and finally our direct siblings (if any) + if (nsnull != mNextSibling) { + mNextSibling->SizeOf(aSizeOfHandler, localSize); + } +} + NS_LAYOUT nsresult NS_NewStyleContext(nsIStyleContext** aInstancePtrResult, nsIStyleContext* aParentContext, diff --git a/mozilla/content/base/src/nsStyleSet.cpp b/mozilla/content/base/src/nsStyleSet.cpp index 7472ff0ddb1..3346da6cbd0 100644 --- a/mozilla/content/base/src/nsStyleSet.cpp +++ b/mozilla/content/base/src/nsStyleSet.cpp @@ -46,9 +46,12 @@ #define STYLESET_STOP_TIMER(a) ((void)0) #endif +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID); static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID); +// #ifdef DEBUG_SC_SHARING class StyleSetImpl : public nsIStyleSet #ifdef MOZ_PERF_METRICS @@ -175,6 +178,15 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + virtual void ResetUniqueStyleItems(void); + +#ifdef DEBUG_SC_SHARING + // add and remove from the cache of all contexts + NS_IMETHOD AddStyleContext(nsIStyleContext *aNewStyleContext); + NS_IMETHOD RemoveStyleContext(nsIStyleContext *aNewStyleContext); +#endif + #ifdef MOZ_PERF_METRICS NS_DECL_NSITIMERECORDER #endif @@ -207,6 +219,11 @@ protected: nsIStyleFrameConstruction* mFrameConstructor; +#ifdef DEBUG_SC_SHARING + nsVoidArray mStyleContextCache; // a cache of all style contexts for faster searching + // when we want to find style contexts in GetContext +#endif + MOZ_TIMER_DECLARE(mStyleResolutionWatch) #ifdef MOZ_PERF_METRICS @@ -222,6 +239,9 @@ StyleSetImpl::StyleSetImpl() mRuleProcessors(nsnull), mRecycler(nsnull), mFrameConstructor(nsnull) +#ifdef DEBUG_SC_SHARING + ,mStyleContextCache(0) +#endif #ifdef MOZ_PERF_METRICS ,mTimerEnabled(PR_FALSE) #endif @@ -237,6 +257,9 @@ StyleSetImpl::~StyleSetImpl() NS_IF_RELEASE(mRuleProcessors); NS_IF_RELEASE(mFrameConstructor); NS_IF_RELEASE(mRecycler); +#ifdef DEBUG_SC_SHARING + NS_ASSERTION( mStyleContextCache.Count() == 0, "StyleContextCache is not empty: leaking style context?"); +#endif } #ifndef MOZ_PERF_METRICS @@ -565,6 +588,10 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData) return PR_TRUE; } +#ifdef DEBUG_SC_SHARING + static int gNewCount=0; + static int gSharedCount=0; +#endif nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, nsIStyleContext* aParentContext, nsIAtom* aPseudoTag, @@ -572,11 +599,41 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, PRBool aForceUnique, PRBool& aUsedRules) { nsIStyleContext* result = nsnull; - aUsedRules = PR_FALSE; + +#ifdef DEBUG_SC_SHARING + static PRBool bCheckCache = PR_FALSE; // DEBUGGING: set to true or false in debugger... + + if ((PR_FALSE == aForceUnique) && (aParentContext != nsnull)) { + aParentContext->FindChildWithRules(aPseudoTag, aRules, result); + } + if (result == nsnull && bCheckCache) { + // check the context cache for another context to search... + if (PR_FALSE == aForceUnique) { + PRInt32 count = mStyleContextCache.Count(); + PRInt32 i; + for (i=0; iAddRef(); + pContext->FindChildWithRules(aPseudoTag, aRules, result); + pContext->Release(); + if (result != nsnull) { + printf( "StyleContext with matching rules found: %d of %d\n", (int)i, (int)count); + break; + } + } + } + } + } +#else if ((PR_FALSE == aForceUnique) && (nsnull != aParentContext)) { aParentContext->FindChildWithRules(aPseudoTag, aRules, result); } +#endif + if (nsnull == result) { if (NS_OK == NS_NewStyleContext(&result, aParentContext, aPseudoTag, aRules, aPresContext)) { if (PR_TRUE == aForceUnique) { @@ -584,11 +641,16 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, } aUsedRules = PRBool(nsnull != aRules); } -//fprintf(stdout, "+"); +#ifdef DEBUG_SC_SHARING + fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount); +#endif } +#ifdef DEBUG_SC_SHARING else { -//fprintf(stdout, "-"); + fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount); } +#endif + return result; } @@ -842,8 +904,8 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext, nsIStyleContext** aNewStyleContext) { NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); + NS_ASSERTION(aStyleContext, "must have style context"); + NS_ASSERTION(aNewStyleContext, "must have new style context"); nsresult result = NS_ERROR_NULL_POINTER; @@ -1241,3 +1303,177 @@ StyleSetImpl::PrintTimer(PRUint32 aTimerID) #endif +//----------------------------------------------------------------------------- + +#ifdef DEBUG_SC_SHARING +NS_IMETHODIMP +StyleSetImpl::AddStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in AddStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) == -1), "StyleContext added in AddStyleContext is already in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.AppendElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} + +NS_IMETHODIMP +StyleSetImpl::RemoveStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in RemoveStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) != -1), "StyleContext removed in AddStyleContext is not in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.RemoveElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} +#endif // DEBUG_SC_SHARING + +//----------------------------------------------------------------------------- + +// static +nsUniqueStyleItems *nsUniqueStyleItems ::mInstance = nsnull; + +void StyleSetImpl::ResetUniqueStyleItems(void) +{ + UNIQUE_STYLE_ITEMS(uniqueItems); + uniqueItems->Clear(); +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleSetImpl's size): +* 1) sizeof(*this) + sizeof (overhead only) each collection that exists +* and the FrameConstructor overhead +* +* Contained / Aggregated data (not reported as StyleSetImpl's size): +* 1) Override Sheets, DocSheets, BackstopSheets, RuleProcessors, Recycler +* are all delegated to. +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + NS_ASSERTION(0, "StyleSet has already been conted in SizeOf operation"); + // styleset has already been accounted for + return; + } + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleSet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(StyleSetImpl); + + // Next get the size of the OVERHEAD of objects we will delegate to: + if (mOverrideSheets && uniqueItems->AddItem(mOverrideSheets)){ + aSize += sizeof(*mOverrideSheets); + } + if (mDocSheets && uniqueItems->AddItem(mDocSheets)){ + aSize += sizeof(*mDocSheets); + } + if (mBackstopSheets && uniqueItems->AddItem(mBackstopSheets)){ + aSize += sizeof(*mBackstopSheets); + } + if (mRuleProcessors && uniqueItems->AddItem(mRuleProcessors)){ + aSize += sizeof(*mRuleProcessors); + } + if (mRecycler && uniqueItems->AddItem(mRecycler)){ + aSize += sizeof(*mRecycler); + } + /////////////////////////////////////////////// + // now the FrameConstructor + if(mFrameConstructor && uniqueItems->AddItem((void*)mFrameConstructor)){ + aSize += sizeof(mFrameConstructor); + } + aSizeOfHandler->AddSize(tag,aSize); + + /////////////////////////////////////////////// + // Now travers the collections and delegate + PRInt32 numSheets, curSheet; + PRUint32 localSize=0; + numSheets = GetNumberOfOverrideStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetOverrideStyleSheetAt(curSheet); //addref + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfDocStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetDocStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfBackstopStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetBackstopStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + /////////////////////////////////////////////// + // rule processors + PRUint32 numRuleProcessors,curRuleProcessor; + if(mRuleProcessors){ + mRuleProcessors->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRuleProcessors->ElementAt(curRuleProcessor); + if(processor){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + /////////////////////////////////////////////// + // and the recycled ones too + if(mRecycler){ + mRecycler->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRecycler->ElementAt(curRuleProcessor); + if(processor && uniqueItems->AddItem((void*)processor)){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + // now delegate the sizeof to the larger or more complex aggregated objects + // - none +} diff --git a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp index 34983b9a50b..c77e8db6e5a 100644 --- a/mozilla/content/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/content/html/content/src/nsGenericHTMLElement.cpp @@ -1550,7 +1550,7 @@ nsGenericHTMLElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult, sum += (PRUint32) aInstanceSize; if (mAttributes) { PRUint32 attrs = 0; - mAttributes->SizeOf(aSizer, &attrs); + mAttributes->SizeOf(aSizer, attrs); sum += attrs; } #endif diff --git a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp index ae83f23cbf2..e3e0a719867 100644 --- a/mozilla/content/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLBodyElement.cpp @@ -47,6 +47,10 @@ #include "nsIFrame.h" #include "nsIDocShell.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); @@ -78,6 +82,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -104,6 +110,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content nsIHTMLCSSStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -380,6 +388,45 @@ BodyRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as BodyRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as BodyRule's size): +* 1) delegate to mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void BodyRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("BodyRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag, aSize); + + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } + + return; +} + //---------------------------------------------------------------------- @@ -538,6 +585,45 @@ BodyFixupRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as BodyFixupRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as BodyFixupRule's size): +* 1) Delegates to the mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void BodyFixupRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("BodyFixupRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag, aSize); + + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } + + return; +} + //---------------------------------------------------------------------- nsresult @@ -863,5 +949,6 @@ nsHTMLBodyElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, NS_IMETHODIMP nsHTMLBodyElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { + // XXX - self? Unique? (Content Size Dump) return mInner.SizeOf(aSizer, aResult, sizeof(*this)); } diff --git a/mozilla/content/html/style/src/nsCSSDeclaration.cpp b/mozilla/content/html/style/src/nsCSSDeclaration.cpp index 9025de4e49d..fa1f365a977 100644 --- a/mozilla/content/html/style/src/nsCSSDeclaration.cpp +++ b/mozilla/content/html/style/src/nsCSSDeclaration.cpp @@ -28,7 +28,11 @@ #include "nsStyleConsts.h" -//#define DEBUG_REFS +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); @@ -950,6 +954,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const; void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); NS_IMETHOD Count(PRUint32* aCount); NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsString& aReturn); @@ -993,7 +999,7 @@ CSSDeclarationImpl::CSSDeclarationImpl(void) NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; - fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (ctor): %ld\n", (long)gInstanceCount); #endif } @@ -1017,6 +1023,11 @@ CSSDeclarationImpl::CSSDeclarationImpl(const CSSDeclarationImpl& aCopy) DECL_IF_COPY(UserInterface); DECL_IF_COPY(Aural); +#ifdef DEBUG_REFS + ++gInstanceCount; + fprintf(stdout, "CSSDeclaration Instances (cp-ctor): %ld\n", (long)gInstanceCount); +#endif + if (aCopy.mImportant) { mImportant = new CSSDeclarationImpl(*(aCopy.mImportant)); NS_IF_ADDREF(mImportant); @@ -1060,7 +1071,7 @@ CSSDeclarationImpl::~CSSDeclarationImpl(void) #ifdef DEBUG_REFS --gInstanceCount; - fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (dtor): %ld\n", (long)gInstanceCount); #endif } @@ -3179,7 +3190,23 @@ PRBool CSSDeclarationImpl::AppendValueToString(nsCSSProperty aProperty, const ns aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { - aResult.Append(aValue.GetIntValue(), 10); + switch (aProperty) { + case eCSSProperty_color: + case eCSSProperty_background_color: { + // we can lookup the property in the ColorTable and then + // get a string mapping the name + nsCString str; + if (nsCSSProps::GetColorName(aValue.GetIntValue(), str)){ + aResult.Append(str); + } else { + aResult.Append(aValue.GetIntValue(), 10); + } + } + break; + + default: + aResult.Append(aValue.GetIntValue(), 10); + } } else if (eCSSUnit_Enumerated == unit) { if (eCSSProperty_text_decoration == aProperty) { @@ -3737,6 +3764,80 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSDeclarationImpl's size): +* 1) sizeof(*this) + the sizeof each non-null attribute +* +* Contained / Aggregated data (not reported as CSSDeclarationImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSDeclarationImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSDeclarationImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now add in all of the contained objects, checking for duplicates on all of them + if(mFont && uniqueItems->AddItem(mFont)){ + aSize += sizeof(*mFont); + } + if(mColor && uniqueItems->AddItem(mColor)){ + aSize += sizeof(*mColor); + } + if(mText && uniqueItems->AddItem(mText)){ + aSize += sizeof(*mText); + } + if(mMargin && uniqueItems->AddItem(mMargin)){ + aSize += sizeof(*mMargin); + } + if(mPosition && uniqueItems->AddItem(mPosition)){ + aSize += sizeof(*mPosition); + } + if(mList && uniqueItems->AddItem(mList)){ + aSize += sizeof(*mList); + } + if(mDisplay && uniqueItems->AddItem(mDisplay)){ + aSize += sizeof(*mDisplay); + } + if(mTable && uniqueItems->AddItem(mTable)){ + aSize += sizeof(*mTable); + } + if(mBreaks && uniqueItems->AddItem(mBreaks)){ + aSize += sizeof(*mBreaks); + } + if(mPage && uniqueItems->AddItem(mPage)){ + aSize += sizeof(*mPage); + } + if(mContent && uniqueItems->AddItem(mContent)){ + aSize += sizeof(*mContent); + } + if(mUserInterface && uniqueItems->AddItem(mUserInterface)){ + aSize += sizeof(*mUserInterface); + } + if(mAural && uniqueItems->AddItem(mAural)){ + aSize += sizeof(*mAural); + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSDeclarationImpl::Count(PRUint32* aCount) { diff --git a/mozilla/content/html/style/src/nsCSSProps.h b/mozilla/content/html/style/src/nsCSSProps.h index 8180f359371..81778dd3ff8 100644 --- a/mozilla/content/html/style/src/nsCSSProps.h +++ b/mozilla/content/html/style/src/nsCSSProps.h @@ -60,6 +60,10 @@ public: // value. Return back nullstr if no value is found static const nsCString& LookupPropertyValue(nsCSSProperty aProperty, PRInt32 aValue); + // Get a color name for a predefined color value like buttonhighlight or activeborder + // Sets the aStr param to the name of the propertyID + static PRBool GetColorName(PRInt32 aPropID, nsCString &aStr); + static const PRInt32 kHintTable[]; // Keyword/Enum value tables diff --git a/mozilla/content/html/style/src/nsCSSRules.cpp b/mozilla/content/html/style/src/nsCSSRules.cpp index e4e9cba802f..32e544aa3e7 100644 --- a/mozilla/content/html/style/src/nsCSSRules.cpp +++ b/mozilla/content/html/style/src/nsCSSRules.cpp @@ -33,6 +33,9 @@ #include "nsLayoutAtoms.h" #include "nsICSSStyleSheet.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -82,6 +85,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -167,6 +172,43 @@ CSSCharsetRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSCharSetRuleImpl's size): +* 1) sizeof(*this) + the size of the mEncoding string +* +* Contained / Aggregated data (not reported as CSSCharsetRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSCharsetRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSCharsetRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add the string for encoding value + mEncoding.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mEncoding); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); +} + NS_IMETHODIMP CSSCharsetRuleImpl::GetType(PRInt32& aType) const { @@ -229,6 +271,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -317,6 +361,49 @@ CSSImportRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the size of the mMedia string +* +* Contained / Aggregated data (not reported as CSSImportRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add the strings for the URLSpec and the Media + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + mMedia.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mMedia); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); + +} + NS_IMETHODIMP CSSImportRuleImpl::GetType(PRInt32& aType) const { @@ -401,6 +488,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -563,6 +652,67 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSMediaRuleImpl's size): +* 1) sizeof(*this) + the size of each unique atom in the mMedia collection +* +* Contained / Aggregated data (not reported as CSSMediaRuleImpl's size): +* 1) Delegate to the rules in the mRules collection to report theri own size +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSMediaRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + if (mMedia) { + // get the sizes of the media atoms (if unique) + PRUint32 index = 0; + PRUint32 count; + mMedia->Count(&count); + while (index < count) { + nsIAtom* medium = (nsIAtom*)mMedia->ElementAt(index++); + if(medium && uniqueItems->AddItem(medium)){ + medium->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + NS_IF_RELEASE(medium); + } + } + // we are done with the size we report for ourself + aSizeOfHandler->AddSize(tag,aSize); + + if (mRules) { + // delegate to the rules themselves (do not sum into our size) + PRUint32 index = 0; + PRUint32 count; + mRules->Count(&count); + while (index < count) { + nsICSSRule* rule = (nsICSSRule*)mRules->ElementAt(index++); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } +} + NS_IMETHODIMP CSSMediaRuleImpl::GetType(PRInt32& aType) const { @@ -693,6 +843,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -788,6 +940,50 @@ CSSNameSpaceRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSNamespaceRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the sizeof the mPrefix atom (if it ieists) +* +* Contained / Aggregated data (not reported as CSSNamespaceRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSNameSpaceRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSNameSpaceRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // get the member data as part of this dump + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + + if(mPrefix && uniqueItems->AddItem(mPrefix)){ + mPrefix->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSNameSpaceRuleImpl::GetType(PRInt32& aType) const { diff --git a/mozilla/content/html/style/src/nsCSSStruct.cpp b/mozilla/content/html/style/src/nsCSSStruct.cpp index 9025de4e49d..fa1f365a977 100644 --- a/mozilla/content/html/style/src/nsCSSStruct.cpp +++ b/mozilla/content/html/style/src/nsCSSStruct.cpp @@ -28,7 +28,11 @@ #include "nsStyleConsts.h" -//#define DEBUG_REFS +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); @@ -950,6 +954,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const; void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); NS_IMETHOD Count(PRUint32* aCount); NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsString& aReturn); @@ -993,7 +999,7 @@ CSSDeclarationImpl::CSSDeclarationImpl(void) NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; - fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (ctor): %ld\n", (long)gInstanceCount); #endif } @@ -1017,6 +1023,11 @@ CSSDeclarationImpl::CSSDeclarationImpl(const CSSDeclarationImpl& aCopy) DECL_IF_COPY(UserInterface); DECL_IF_COPY(Aural); +#ifdef DEBUG_REFS + ++gInstanceCount; + fprintf(stdout, "CSSDeclaration Instances (cp-ctor): %ld\n", (long)gInstanceCount); +#endif + if (aCopy.mImportant) { mImportant = new CSSDeclarationImpl(*(aCopy.mImportant)); NS_IF_ADDREF(mImportant); @@ -1060,7 +1071,7 @@ CSSDeclarationImpl::~CSSDeclarationImpl(void) #ifdef DEBUG_REFS --gInstanceCount; - fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (dtor): %ld\n", (long)gInstanceCount); #endif } @@ -3179,7 +3190,23 @@ PRBool CSSDeclarationImpl::AppendValueToString(nsCSSProperty aProperty, const ns aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { - aResult.Append(aValue.GetIntValue(), 10); + switch (aProperty) { + case eCSSProperty_color: + case eCSSProperty_background_color: { + // we can lookup the property in the ColorTable and then + // get a string mapping the name + nsCString str; + if (nsCSSProps::GetColorName(aValue.GetIntValue(), str)){ + aResult.Append(str); + } else { + aResult.Append(aValue.GetIntValue(), 10); + } + } + break; + + default: + aResult.Append(aValue.GetIntValue(), 10); + } } else if (eCSSUnit_Enumerated == unit) { if (eCSSProperty_text_decoration == aProperty) { @@ -3737,6 +3764,80 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSDeclarationImpl's size): +* 1) sizeof(*this) + the sizeof each non-null attribute +* +* Contained / Aggregated data (not reported as CSSDeclarationImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSDeclarationImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSDeclarationImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now add in all of the contained objects, checking for duplicates on all of them + if(mFont && uniqueItems->AddItem(mFont)){ + aSize += sizeof(*mFont); + } + if(mColor && uniqueItems->AddItem(mColor)){ + aSize += sizeof(*mColor); + } + if(mText && uniqueItems->AddItem(mText)){ + aSize += sizeof(*mText); + } + if(mMargin && uniqueItems->AddItem(mMargin)){ + aSize += sizeof(*mMargin); + } + if(mPosition && uniqueItems->AddItem(mPosition)){ + aSize += sizeof(*mPosition); + } + if(mList && uniqueItems->AddItem(mList)){ + aSize += sizeof(*mList); + } + if(mDisplay && uniqueItems->AddItem(mDisplay)){ + aSize += sizeof(*mDisplay); + } + if(mTable && uniqueItems->AddItem(mTable)){ + aSize += sizeof(*mTable); + } + if(mBreaks && uniqueItems->AddItem(mBreaks)){ + aSize += sizeof(*mBreaks); + } + if(mPage && uniqueItems->AddItem(mPage)){ + aSize += sizeof(*mPage); + } + if(mContent && uniqueItems->AddItem(mContent)){ + aSize += sizeof(*mContent); + } + if(mUserInterface && uniqueItems->AddItem(mUserInterface)){ + aSize += sizeof(*mUserInterface); + } + if(mAural && uniqueItems->AddItem(mAural)){ + aSize += sizeof(*mAural); + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSDeclarationImpl::Count(PRUint32* aCount) { diff --git a/mozilla/content/html/style/src/nsCSSStyleRule.cpp b/mozilla/content/html/style/src/nsCSSStyleRule.cpp index a11c6c59461..e6557253425 100644 --- a/mozilla/content/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleRule.cpp @@ -52,6 +52,11 @@ #include "nsINameSpaceManager.h" #include "nsILookAndFeel.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS + static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); @@ -138,6 +143,10 @@ PRBool nsAtomList::Equals(const nsAtomList* aOther) const MOZ_DECL_CTOR_COUNTER(nsAttrSelector); +#ifdef DEBUG_REFS +PRUint32 gAttrSelectorCount=0; +#endif + nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) : mNameSpace(aNameSpace), mAttr(nsnull), @@ -147,6 +156,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -160,6 +175,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr, PRUint mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -172,6 +193,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (cp-ctor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_ADDREF(mAttr); NS_IF_COPY(mNext, aCopy.mNext, nsAttrSelector); } @@ -179,6 +206,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) nsAttrSelector::~nsAttrSelector(void) { MOZ_COUNT_DTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount--; + printf( "nsAttrSelector Instances (dtor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_RELEASE(mAttr); NS_IF_DELETE(mNext); } @@ -203,8 +236,56 @@ PRBool nsAttrSelector::Equals(const nsAttrSelector* aOther) const return PR_FALSE; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsAttrSelector's size): +* 1) sizeof(*this) + the size of mAttr atom (if it exists and is unique) +* +* Contained / Aggregated data (not reported as nsAttrSelector's size): +* none +* +* Children / siblings / parents: +* 1) Recurses to the mMext instance which is reported as a seperate instance +* +******************************************************************************/ +void nsAttrSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsAttrSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add in the mAttr atom + if (mAttr && uniqueItems->AddItem(mAttr)){ + mAttr->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // recurse to the next one... + if(mNext){ + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + MOZ_DECL_CTOR_COUNTER(nsCSSSelector); +#ifdef DEBUG_REFS +PRUint32 gSelectorCount=0; +#endif + nsCSSSelector::nsCSSSelector(void) : mNameSpace(kNameSpaceID_Unknown), mTag(nsnull), mID(nsnull), @@ -215,6 +296,11 @@ nsCSSSelector::nsCSSSelector(void) mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) @@ -232,12 +318,22 @@ nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) NS_IF_COPY(mClassList, aCopy.mClassList, nsAtomList); NS_IF_COPY(mPseudoClassList, aCopy.mPseudoClassList, nsAtomList); NS_IF_COPY(mAttrList, aCopy.mAttrList, nsAttrSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (cp-ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::~nsCSSSelector(void) { MOZ_COUNT_DTOR(nsCSSSelector); Reset(); + +#ifdef DEBUG_REFS + gSelectorCount--; + printf( "nsCSSSelector Instances (dtor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector& nsCSSSelector::operator=(const nsCSSSelector& aCopy) @@ -429,6 +525,90 @@ PRInt32 nsCSSSelector::CalcWeight(void) const return weight; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsCSSSelector's size): +* 1) sizeof(*this) + the size of the mTag and mID atoms (if unique) +* + the size of the mClassList and mPseudoClassList unique items +* +* Contained / Aggregated data (not reported as nsCSSSelector's size): +* 1) AttributeList is called out to seperately if it exists +* +* Children / siblings / parents: +* 1) Recurses to mNext which is counted as it's own instance +* +******************************************************************************/ +void nsCSSSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsCSSSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now get the member-atoms and add them in + if(mTag && uniqueItems->AddItem(mTag)){ + localSize = 0; + mTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + if(mID && uniqueItems->AddItem(mID)){ + localSize = 0; + mID->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + // a couple of simple atom lists + if(mClassList && uniqueItems->AddItem(mClassList)){ + aSize += sizeof(*mClassList); + nsAtomList *pNext = nsnull; + pNext = mClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + if(mPseudoClassList && uniqueItems->AddItem(mPseudoClassList)){ + nsAtomList *pNext = nsnull; + pNext = mPseudoClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + // done with undelegated sizes + aSizeOfHandler->AddSize(tag, aSize); + + // the AttributeList gets its own delegation-call + if(mAttrList){ + localSize = 0; + mAttrList->SizeOf(aSizeOfHandler, localSize); + } + // finally chain to the next... + if(mNext){ + localSize = 0; + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + // -- CSSImportantRule ------------------------------- static nscoord CalcLength(const nsCSSValue& aValue, const nsFont& aFont, @@ -467,6 +647,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: virtual ~CSSImportantRule(void); @@ -555,6 +737,48 @@ CSSImportantRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportantRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSImportantRule's size): +* 1) mDeclaration is sized seperately +* 2) mSheet is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportantRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportantRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSImportantRule); + aSizeOfHandler->AddSize(tag,aSize); + + // now dump the mDeclaration and mSheet + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // -- nsDOMStyleRuleDeclaration ------------------------------- class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration @@ -729,6 +953,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsIDOMCSSRule interface NS_IMETHOD GetType(PRUint16* aType); NS_IMETHOD GetCssText(nsString& aCssText); @@ -762,6 +988,10 @@ protected: void* mScriptObject; }; +#ifdef DEBUG_REFS +PRUint32 gStyleRuleCount=0; +#endif + CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) : nsCSSRule(), mSelector(aSelector), mSelectorText(), mDeclaration(nsnull), @@ -769,6 +999,10 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (ctor): %ld\n", (long)gStyleRuleCount); +#endif } CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) @@ -781,6 +1015,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (cp-ctor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* copySel = aCopy.mSelector.mNext; nsCSSSelector* ourSel = &mSelector; @@ -799,6 +1038,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) CSSStyleRuleImpl::~CSSStyleRuleImpl(void) { +#ifdef DEBUG_REFS + gStyleRuleCount--; + printf( "CSSStyleRuleImpl Instances (dtor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* next = mSelector.mNext; while (nsnull != next) { @@ -2856,6 +3100,64 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleRuleImpl's size): +* 1) sizeof(*this) + size of the mSelectorText +* + sizeof the DOMDeclaration if it exists and is unique +* +* Contained / Aggregated data (not reported as CSSStyleRuleImpl's size): +* 1) mDeclaration if it exists +* 2) mImportantRule if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // remove the sizeof the mSelector's class since we count it seperately below + aSize -= sizeof(mSelector); + + // add in the length of the selectorText + mSelectorText.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mSelectorText); // counted in sizeof(*this) and nsString.SizeOf() + + // and add the size of the DOMDeclaration + // XXX - investigate the size and quantity of these + if(mDOMDeclaration && uniqueItems->AddItem(mDOMDeclaration)){ + aSize += sizeof(DOMCSSDeclarationImpl); + } + aSizeOfHandler->AddSize(tag,aSize); + + // now delegate to the Selector, Declaration, and ImportantRule + mSelector.SizeOf(aSizeOfHandler, localSize); + + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mImportantRule){ + mImportantRule->SizeOf(aSizeOfHandler, localSize); + } +} + NS_IMETHODIMP CSSStyleRuleImpl::GetType(PRUint16* aType) { @@ -2970,6 +3272,5 @@ NS_HTML nsresult if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(kICSSStyleRuleIID, (void **) aInstancePtrResult); } diff --git a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp index 5c1d752a598..4ebea9b15b1 100644 --- a/mozilla/content/html/style/src/nsCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsCSSStyleSheet.cpp @@ -62,7 +62,12 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsITextContent.h" #include "prlog.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + //#define DEBUG_RULES +//#define EVENT_DEBUG static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -407,6 +412,8 @@ public: nsIAtom* aMedium, nsIContent* aContent); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + protected: RuleCascadeData* GetRuleCascade(nsIAtom* aMedium); @@ -433,6 +440,8 @@ public: virtual void RebuildNameSpaces(void); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsVoidArray mSheets; nsIURI* mURL; @@ -521,6 +530,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + // nsIDOMStyleSheet interface NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); @@ -1048,6 +1059,80 @@ CSSStyleSheetInner::RebuildNameSpaces(void) } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetInner's size): +* 1) sizeof(*this) + sizeof mSheets array (not contents though) +* + size of the mOrderedRules array (not the contents though) +* +* Contained / Aggregated data (not reported as CSSStyleSheetInner's size): +* 1) mSheets: each style sheet is sized seperately +* 2) mOrderedRules: each fule is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleSheetInner::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + PRBool rulesCounted=PR_FALSE; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheetInner")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetInner); + + // add in the size of the mSheets array itself + mSheets.SizeOf(aSizeOfHandler,&localSize); + aSize += localSize; + + // and the mOrderedRules array (if there is one) + if(mOrderedRules && uniqueItems->AddItem(mOrderedRules)){ + rulesCounted=PR_TRUE; + // no SizeOf method so we just get the basic object size + aSize += sizeof(*mOrderedRules); + } + aSizeOfHandler->AddSize(tag,aSize); + + + // delegate to the contained containers + // mSheets : nsVoidArray + { + PRUint32 sheetCount, sheetCur; + sheetCount = mSheets.Count(); + for(sheetCur=0; sheetCur < sheetCount; sheetCur++){ + nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)mSheets.ElementAt(sheetCur); + if(sheet){ + sheet->SizeOf(aSizeOfHandler, localSize); + } + } + } + // mOrderedRules : nsISupportsArray* + if(mOrderedRules && rulesCounted){ + PRUint32 ruleCount, ruleCur; + mOrderedRules->Count(&ruleCount); + for(ruleCur=0; ruleCur < ruleCount; ruleCur++){ + nsICSSRule* rule = (nsICSSRule*)mOrderedRules->ElementAt(ruleCur); + if(rule){ + rule->SizeOf(aSizeOfHandler, localSize); + NS_IF_RELEASE(rule); + } + } + } +} + // ------------------------------- // CSS Style Sheet @@ -1837,6 +1922,59 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const ListRules(mInner->mOrderedRules, out, aIndent); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetImpl's size): +* 1) sizeof(*this) + sizeof the mImportsCollection + sizeof mCuleCollection) +* +* Contained / Aggregated data (not reported as CSSStyleSheetImpl's size): +* 1) mInner is delegated to be counted seperately +* +* Children / siblings / parents: +* 1) Recurse to mFirstChild +* +******************************************************************************/ +void CSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is already accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetImpl); + + // add up the contained objects we won't delegate to: + // NOTE that we just add the sizeof the objects + // since the style data they contain is accounted for elsewhere + // - mImportsCollection + // - mRuleCollection + aSize += sizeof(mImportsCollection); + aSize += sizeof(mRuleCollection); + aSizeOfHandler->AddSize(tag,aSize); + + // size the inner + if(mInner){ + mInner->SizeOf(aSizeOfHandler, localSize); + } + + // now travers the children (recursively, I'm sorry to say) + if(mFirstChild){ + PRUint32 childSize=0; + mFirstChild->SizeOf(aSizeOfHandler, childSize); + } +} + static PRBool EnumClearRuleCascades(void* aProcessor, void* aData) { @@ -2308,6 +2446,29 @@ static PRBool IsLinkPseudo(nsIAtom* aAtom) (nsCSSAtoms::visitedPseudo == aAtom)); } +static PRBool IsEventSensitive(nsIAtom *aPseudo, nsIAtom *aContentTag, PRBool aSelectorIsGlobal) +{ + // if the selector is global, meaning it is not tied to a tag, then + // we restrict the application of the event pseudo to the following tags + if (aSelectorIsGlobal) { + return PRBool ((nsHTMLAtoms::a == aContentTag) || + (nsHTMLAtoms::button == aContentTag) || + (nsHTMLAtoms::img == aContentTag) || + (nsHTMLAtoms::input == aContentTag) || + (nsHTMLAtoms::li == aContentTag) || + (nsHTMLAtoms::label == aContentTag) || + (nsHTMLAtoms::select == aContentTag) || + (nsHTMLAtoms::textarea == aContentTag) || + (nsHTMLAtoms::textPseudo == aContentTag) || + // We require a Layout Atom too + (nsLayoutAtoms::textTagName == aContentTag) + ); + } else { + // selector is not global, so apply the event pseudo to everything except HTML and BODY + return PRBool ((nsHTMLAtoms::html != aContentTag) && + (nsHTMLAtoms::body != aContentTag)); + } +} static PRBool SelectorMatches(nsIPresContext* aPresContext, nsCSSSelector* aSelector, nsIContent* aContent, PRBool aTestState) @@ -2488,12 +2649,49 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, result = PR_FALSE; } else if (IsEventPseudo(pseudoClass->mAtom)) { - if (aTestState) { + // check if the element is event-sensitive + if (!contentTag) { + if (aContent) { + aContent->GetTag(contentTag); + } + } + +#ifdef EVENT_DEBUG + nsAutoString strTag; + // easier to watch the string value than the ATOM + if (contentTag) { + contentTag->ToString(strTag); + } +#endif + // Quirk Mode: check to see if the element is event-sensitive + // - see if the selector applies to event pseudo classes + // NOTE: we distinguish between global and subjected selectors so + // pass that information on to the determining routine + nsCompatibility quirkMode = eCompatibility_Standard; + aPresContext->GetCompatibilityMode(&quirkMode); + PRBool isSelectorGlobal = aSelector->mTag==nsnull ? PR_TRUE : PR_FALSE; + if ((eCompatibility_NavQuirks == quirkMode) && + (!IsEventSensitive(pseudoClass->mAtom, contentTag, isSelectorGlobal))){ + result = PR_FALSE; + } else if (aTestState) { if (! eventStateManager) { aPresContext->GetEventStateManager(&eventStateManager); - if (eventStateManager) { - eventStateManager->GetContentState(aContent, eventState); + } + if (eventStateManager) { + eventStateManager->GetContentState(aContent, eventState); + +#ifdef EVENT_DEBUG + nsAutoString strPseudo, strTag; + pseudoClass->mAtom->ToString(strPseudo); + if (!contentTag) { + if (aContent) aContent->GetTag(contentTag); } + if (contentTag) { + contentTag->ToString(strTag); + } + printf("Tag: %s PseudoClass: %s EventState: %d\n", + strTag.ToNewCString(), strPseudo.ToNewCString(), (int)eventState); +#endif } if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE)); @@ -2507,14 +2705,14 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, else if (nsCSSAtoms::dragOverPseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_DRAGOVER)); } - } + } } else if (IsLinkPseudo(pseudoClass->mAtom)) { // XXX xml link too - if(!tagset) { - tagset=PR_TRUE; - aContent->GetTag(contentTag); - } + if(!tagset) { + tagset=PR_TRUE; + aContent->GetTag(contentTag); + } if (nsHTMLAtoms::a == contentTag) { // make sure this anchor has a link even if we are not testing state // if there is no link, then this anchor is not really a linkpseudo. @@ -2888,6 +3086,159 @@ CSSRuleProcessor::HasStateDependentStyle(nsIPresContext* aPresContext, return ((isStateful) ? NS_OK : NS_COMFALSE); } + +struct CascadeSizeEnumData { + + CascadeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem, + nsIAtom *aTag) + { + handler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + tag = aTag; + } + // weak references all 'round + + nsISizeOfHandler *handler; + nsUniqueStyleItems *uniqueItems; + nsIAtom *tag; +}; + +static +PRBool StateSelectorsSizeEnumFunc( void *aSelector, void *aData ) +{ + nsCSSSelector* selector = (nsCSSSelector*)aSelector; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(selector && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)selector)){ + return PR_TRUE; + } + + // pass the call to the selector + PRUint32 localSize = 0; + selector->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool WeightedRulesSizeEnumFunc( nsISupports *aRule, void *aData ) +{ + nsICSSStyleRule* rule = (nsICSSStyleRule*)aRule; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(rule && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)rule)){ + return PR_TRUE; + } + + PRUint32 localSize=0; + + // pass the call to the rule + rule->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool CascadeSizeEnumFunc(nsHashKey* aKey, void *aCascade, void *aData) +{ + RuleCascadeData* cascade = (RuleCascadeData *) aCascade; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(cascade && pData, "null arguments not supported"); + + // see if the cascade has already been counted + if(!(pData->uniqueItems->AddItem(cascade))){ + return PR_TRUE; + } + // record the size of the cascade data itself + PRUint32 localSize = sizeof(RuleCascadeData); + pData->handler->AddSize(pData->tag, localSize); + + // next add up the selectors and the weighted rules for the cascade + nsCOMPtr stateSelectorSizeTag; + stateSelectorSizeTag = getter_AddRefs(NS_NewAtom("CascadeStateSelectors")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,stateSelectorSizeTag); + cascade->mStateSelectors.EnumerateForwards(StateSelectorsSizeEnumFunc, &stateData); + + if(cascade->mWeightedRules){ + nsCOMPtr weightedRulesSizeTag; + weightedRulesSizeTag = getter_AddRefs(NS_NewAtom("CascadeWeightedRules")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,weightedRulesSizeTag); + cascade->mWeightedRules->EnumerateForwards(WeightedRulesSizeEnumFunc, &stateData); + } + return PR_TRUE; +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSRuleProcessor's size): +* 1) sizeof(*this) + mMediumCascadeTable hashtable overhead +* +* Contained / Aggregated data (not reported as CSSRuleProcessor's size): +* 1) Delegate to the StyleSheets in the mSheets collection +* 2) Delegate to the Rules in the CascadeTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSRuleProcessor::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSRuleProcessor")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSRuleProcessor); + + // collect sizes for the data + // - mSheets + // - mMediumCascadeTable + + // sheets first + if(mSheets && uniqueItems->AddItem(mSheets)){ + PRUint32 sheetCount, curSheet, localSize; + mSheets->Count(&sheetCount); + for(curSheet=0; curSheet < sheetCount; curSheet++){ + nsICSSStyleSheet *pSheet = (nsICSSStyleSheet *)mSheets->ElementAt(curSheet); + if(pSheet && uniqueItems->AddItem((void*)pSheet)){ + pSheet->SizeOf(aSizeOfHandler, localSize); + // XXX aSize += localSize; + } + } + } + + // and for the medium cascade table we account for the hash table overhead, + // and then compute the sizeof each rule-cascade in the table + if(mMediumCascadeTable){ + PRUint32 count; + count = mMediumCascadeTable->Count(); + localSize = sizeof(PLHashTable); + if(count > 0){ + aSize += sizeof(PLHashEntry) * count; + // now go ghrough each RuleCascade in the table + nsCOMPtr tag = getter_AddRefs(NS_NewAtom("RuleCascade")); + CascadeSizeEnumData data(aSizeOfHandler, uniqueItems, tag); + mMediumCascadeTable->Enumerate(CascadeSizeEnumFunc, &data); + } + } + + // now add the size of the RuleProcessor + aSizeOfHandler->AddSize(tag,aSize); +} + static PRBool DeleteRuleCascade(nsHashKey* aKey, void* aValue, void* closure) { delete ((RuleCascadeData*)aValue); diff --git a/mozilla/content/html/style/src/nsHTMLAttributes.cpp b/mozilla/content/html/style/src/nsHTMLAttributes.cpp index b075ad6de63..fa2321da0ae 100644 --- a/mozilla/content/html/style/src/nsHTMLAttributes.cpp +++ b/mozilla/content/html/style/src/nsHTMLAttributes.cpp @@ -33,6 +33,9 @@ #include "nsIHTMLContent.h" #include "nsVoidArray.h" #include "nsISizeOfHandler.h" +#include "nsCOMPtr.h" + +#include "nsIStyleSet.h" static NS_DEFINE_IID(kIHTMLAttributesIID, NS_IHTML_ATTRIBUTES_IID); @@ -215,7 +218,6 @@ struct HTMLAttribute { return PR_FALSE; } -#ifdef DEBUG nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { if (!aResult) { return NS_ERROR_NULL_POINTER; @@ -223,7 +225,6 @@ struct HTMLAttribute { *aResult = sizeof(*this); return NS_OK; } -#endif nsIAtom* mAttribute; nsHTMLValue mValue; @@ -320,15 +321,7 @@ public: NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; -#ifdef DEBUG - nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } - *aResult = sizeof(*this); - return NS_OK; - } -#endif + void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult); nsIHTMLStyleSheet* mSheet; PRInt32 mUseCount; @@ -780,6 +773,33 @@ nsHTMLMappedAttributes::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsHTMLMappedAttributes's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as nsHTMLMappedAttributes's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void nsHTMLMappedAttributes::SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) +{ + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this is already accounted for + return; + } + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLMappedAttributes")); + aResult = sizeof(*this); + aSizer->AddSize(tag, aResult); +} + //-------------------- const PRInt32 kNameBufferSize = 4; @@ -842,7 +862,7 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; + void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult); protected: virtual nsresult SetAttributeName(nsIAtom* aAttrName, PRBool& aFound); @@ -1503,14 +1523,18 @@ HTMLAttributesImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } -NS_IMETHODIMP -HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const +void HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) { - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } PRUint32 sum = 0; -#ifdef DEBUG + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this is already accounted for + return; + } + + // XXX step through this again sum = sizeof(*this); if (mAttrNames != mNameBuffer) { sum += sizeof(*mAttrNames) * mAttrSize; @@ -1519,7 +1543,7 @@ HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const HTMLAttribute* ha = mFirstUnmapped; while (ha) { PRUint32 asum = 0; - ha->SizeOf(aSizer, &asum); + ha->SizeOf(aSizer, &asum); // XXX Unique??? sum += asum; ha = ha->mNext; } @@ -1529,13 +1553,16 @@ HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const aSizer->RecordObject((void*)mMapped, &recorded); if (!recorded) { PRUint32 asum = 0; - mMapped->SizeOf(aSizer, &asum); + mMapped->SizeOf(aSizer, asum); // XXX Unique??? sum += asum; } } -#endif - *aResult = sum; - return NS_OK; + + aResult = sum; + + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLAttributesImpl")); + aSizer->AddSize(tag, aResult); } extern NS_HTML nsresult diff --git a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp index cfa778db981..c635932d139 100644 --- a/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -38,6 +38,10 @@ #include "nsIMutableStyleContext.h" #include "nsIPresContext.h" #include "nsIDocument.h" +#include "nsCOMPtr.h" + +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -61,6 +65,8 @@ public: nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLCSSStyleSheet* mSheet; }; @@ -188,6 +194,44 @@ CSSFirstLineRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSFirstLineRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSFirstLineRule's size): +* 1) Delegate to mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSFirstLineRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSFirstLine-LetterRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // ----------------------------------------------------------- class CSSFirstLetterRule : public CSSFirstLineRule { @@ -321,6 +365,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy); @@ -666,6 +712,56 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const fputs("\n", out); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLCSSStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLCSSStyleSheetImpl's size): +* 1) We don't really delegate but count seperately the FirstLineRule and +* the FirstLetterRule if the exist and are unique instances +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLCSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLCSSStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // Now the associated rules (if they exist) + // - mFirstLineRule + // - mFirstLetterRule + if(mFirstLineRule && uniqueItems->AddItem((void*)mFirstLineRule)){ + localSize = sizeof(*mFirstLineRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLineRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mFirstLetterRule && uniqueItems->AddItem((void*)mFirstLetterRule)){ + localSize = sizeof(*mFirstLetterRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLetterRule")); + aSizeOfHandler->AddSize(tag,localSize); + } +} // XXX For backwards compatibility and convenience NS_HTML nsresult diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index 506af22d0f5..3487fcc832d 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -54,6 +54,9 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsINameSpaceManager.h" #include "nsLayoutAtoms.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -77,6 +80,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nscolor mColor; nsIHTMLStyleSheet* mSheet; }; @@ -88,6 +93,8 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nscolor mBackgroundColor; PRBool mForegroundSet; PRBool mBackgroundSet; @@ -158,6 +165,44 @@ HTMLColorRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLColorRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as HTMLColorRule's size): +* 1) delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + HTMLDocumentColorRule::HTMLDocumentColorRule(nsIHTMLStyleSheet* aSheet) : HTMLColorRule(aSheet) { @@ -186,6 +231,44 @@ HTMLDocumentColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresCon return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLDocumentColorRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLDocumentColorRule's size): +* 1) Delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLDocumentColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLDocumentColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + class GenericTableRule: public nsIStyleRule { public: GenericTableRule(nsIHTMLStyleSheet* aSheet); @@ -207,6 +290,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -269,6 +354,46 @@ GenericTableRule::List(FILE* out, PRInt32 aIndent) const { return NS_OK; } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as GenericTableRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as GenericTableRule's size): +* 1) Delegate to the mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void GenericTableRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("GenericTableRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + + // ----------------------------------------------------------- // this rule only applies in NavQuirks mode // ----------------------------------------------------------- @@ -307,10 +432,13 @@ TableBackgroundRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresConte styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } +// NOTE: Nav does not inherit the background image: this was over-zealous and mistaken +#if 0 if (!(parentStyleColor->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE)) { styleColor->mBackgroundImage = parentStyleColor->mBackgroundImage; styleColor->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE; } +#endif NS_RELEASE(parentContext); } @@ -520,6 +648,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy); @@ -541,6 +671,9 @@ protected: HTMLDocumentColorRule* mDocumentColorRule; TableBackgroundRule* mTableBackgroundRule; TableTHRule* mTableTHRule; + // NOTE: if adding more rules, be sure to update + // the SizeOf method to include them + nsHashtable mMappedAttrTable; }; @@ -1244,6 +1377,141 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } +struct MappedAttributeSizeEnumData { + MappedAttributeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem) + + { + aHandler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + } + // weak references all 'round + + nsISizeOfHandler *aHandler; + nsUniqueStyleItems *uniqueItems; +}; + +static +PRBool MappedSizeAttributes(nsHashKey *aKey, void *aData, void* closure) +{ + MappedAttributeSizeEnumData *pData = (MappedAttributeSizeEnumData *)closure; + NS_ASSERTION(pData,"null closure is not supported"); + nsIHTMLMappedAttributes* mapped = (nsIHTMLMappedAttributes*)aData; + NS_ASSERTION(mapped, "null item in enumeration fcn is not supported"); + // if there is an attribute and it has not been counted, the get its size + if(mapped){ + PRUint32 size=0; + mapped->SizeOf(pData->aHandler, size); + } + return PR_TRUE; +} + + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLStyleSheetImpl's size): +* 1) Not really delegated, but counted seperately: +* - mLinkRule +* - mVisitedRule +* - mActiveRule +* - mDocumentColorRule +* - mTableBackgroundRule +* - mTableTHRule +* - mMappedAttrTable +* 2) Delegates (really) to the MappedAttributes in the mMappedAttrTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // now gather up the sizes of the data members + // - mLinkRule : sizeof object + // - mVisitedRule : sizeof object + // - mActiveRule : sizeof object + // - mDocumentColorRule : sizeof object + // - mTableBackgroundRule : sizeof object + // - mTableTHRule : sizeof object + // - mMappedAttrTable + + if(mLinkRule && uniqueItems->AddItem((void*)mLinkRule)){ + localSize = sizeof(*mLinkRule); + tag = getter_AddRefs(NS_NewAtom("LinkRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mVisitedRule && uniqueItems->AddItem((void*)mVisitedRule)){ + localSize = sizeof(*mVisitedRule); + tag = getter_AddRefs(NS_NewAtom("VisitedRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mActiveRule && uniqueItems->AddItem((void*)mActiveRule)){ + localSize = sizeof(*mActiveRule); + tag = getter_AddRefs(NS_NewAtom("ActiveRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mDocumentColorRule && uniqueItems->AddItem((void*)mDocumentColorRule)){ + localSize = sizeof(*mDocumentColorRule); + tag = getter_AddRefs(NS_NewAtom("DocumentColorRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableBackgroundRule && uniqueItems->AddItem((void*)mTableBackgroundRule)){ + localSize = sizeof(*mTableBackgroundRule); + tag = getter_AddRefs(NS_NewAtom("TableBackgroundRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableTHRule && uniqueItems->AddItem((void*)mTableTHRule)){ + localSize = sizeof(*mTableTHRule); + tag = getter_AddRefs(NS_NewAtom("TableTHRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + + // for the AttrTable it is kindof sleezy: + // We want the hash table overhead as well as the entries it contains + // + // we get the overall size of the hashtable, and if there are entries, + // we calculate a rough overhead estimate as: + // number of entries X sizeof each hash-entry + // + the size of a hash table (see plhash.h and nsHashTable.h) + // then we add up the size of each unique attribute + localSize = sizeof(mMappedAttrTable); + if(mMappedAttrTable.Count() >0){ + localSize += sizeof(PLHashTable); + localSize += mMappedAttrTable.Count() * sizeof(PLHashEntry); + } + tag = getter_AddRefs(NS_NewAtom("MappedAttrTable")); + aSizeOfHandler->AddSize(tag,localSize); + + // now get each unique attribute + MappedAttributeSizeEnumData sizeEnumData(aSizeOfHandler, uniqueItems); + mMappedAttrTable.Enumerate(MappedSizeAttributes, &sizeEnumData); + + // that's it +} + + // XXX For convenience and backwards compatibility NS_HTML nsresult NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURI* aURL, diff --git a/mozilla/content/html/style/src/nsICSSDeclaration.h b/mozilla/content/html/style/src/nsICSSDeclaration.h index 40b92e276aa..f5386155198 100644 --- a/mozilla/content/html/style/src/nsICSSDeclaration.h +++ b/mozilla/content/html/style/src/nsICSSDeclaration.h @@ -31,6 +31,7 @@ #include "nsCSSValue.h" #include "nsCSSProps.h" +class nsISizeOfHandler; struct nsCSSStruct { virtual const nsID& GetID(void) = 0; @@ -412,6 +413,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const = 0; virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; }; extern NS_HTML nsresult diff --git a/mozilla/content/html/style/src/nsICSSStyleRule.h b/mozilla/content/html/style/src/nsICSSStyleRule.h index d3dac04f1cf..b77ec5ed8b6 100644 --- a/mozilla/content/html/style/src/nsICSSStyleRule.h +++ b/mozilla/content/html/style/src/nsICSSStyleRule.h @@ -27,6 +27,8 @@ #include "nsICSSRule.h" #include "nsString.h" +class nsISizeOfHandler; + class nsIAtom; class nsIArena; class nsICSSDeclaration; @@ -58,6 +60,8 @@ public: ~nsAttrSelector(void); PRBool Equals(const nsAttrSelector* aOther) const; + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + PRInt32 mNameSpace; nsIAtom* mAttr; PRUint8 mFunction; @@ -88,7 +92,9 @@ public: void SetOperator(PRUnichar aOperator); PRInt32 CalcWeight(void) const; - + + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + public: PRInt32 mNameSpace; nsIAtom* mTag; diff --git a/mozilla/content/html/style/src/nsIHTMLAttributes.h b/mozilla/content/html/style/src/nsIHTMLAttributes.h index 015ceb6db25..e270e77b7ea 100644 --- a/mozilla/content/html/style/src/nsIHTMLAttributes.h +++ b/mozilla/content/html/style/src/nsIHTMLAttributes.h @@ -30,7 +30,6 @@ class nsIAtom; class nsISupportsArray; class nsIHTMLStyleSheet; - // IID for the nsIHTMLAttributes interface {a18f85f0-c058-11d1-8031-006008159b5a} #define NS_IHTML_ATTRIBUTES_IID \ {0xa18f85f0, 0xc058, 0x11d1, \ @@ -94,7 +93,7 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; - NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const = 0; + virtual void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) = 0; }; class nsIHTMLMappedAttributes : public nsISupports { @@ -112,6 +111,8 @@ public: NS_IMETHOD SetUniqued(PRBool aUniqued) = 0; NS_IMETHOD GetUniqued(PRBool& aUniqued) = 0; NS_IMETHOD DropStyleSheetReference(void) = 0; + + virtual void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) = 0; }; extern NS_HTML nsresult diff --git a/mozilla/content/shared/public/nsCSSProps.h b/mozilla/content/shared/public/nsCSSProps.h index 8180f359371..81778dd3ff8 100644 --- a/mozilla/content/shared/public/nsCSSProps.h +++ b/mozilla/content/shared/public/nsCSSProps.h @@ -60,6 +60,10 @@ public: // value. Return back nullstr if no value is found static const nsCString& LookupPropertyValue(nsCSSProperty aProperty, PRInt32 aValue); + // Get a color name for a predefined color value like buttonhighlight or activeborder + // Sets the aStr param to the name of the propertyID + static PRBool GetColorName(PRInt32 aPropID, nsCString &aStr); + static const PRInt32 kHintTable[]; // Keyword/Enum value tables diff --git a/mozilla/content/shared/src/nsCSSProps.cpp b/mozilla/content/shared/src/nsCSSProps.cpp index 709f2b9c749..4dc106dcd20 100644 --- a/mozilla/content/shared/src/nsCSSProps.cpp +++ b/mozilla/content/shared/src/nsCSSProps.cpp @@ -670,8 +670,7 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = { -1,-1 }; -static const nsCString& -SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +static PRInt32 SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[]) { PRInt32 i = 1; for (;;) { @@ -679,14 +678,23 @@ SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) break; } if (aValue == aTable[i]) { - return nsCSSKeywords::GetStringValue(nsCSSKeyword(aTable[i-1])); + return PRInt32(aTable[i-1]); } i += 2; } - return *kNullStr; + return -1; } - +static const nsCString& +SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +{ + PRInt32 i = SearchKeywordTableInt(aValue, aTable); + if (i < 0) { + return *kNullStr; + } else { + return nsCSSKeywords::GetStringValue(nsCSSKeyword(i)); + } +} const nsCString& nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, PRInt32 aValue) @@ -1042,6 +1050,23 @@ static const PRInt32 kBackgroundYPositionKTable[] = { return *kNullStr; } +PRBool nsCSSProps::GetColorName(PRInt32 aPropValue, nsCString &aStr) +{ + PRBool rv = PR_FALSE; + PRInt32 keyword = -1; + + // first get the keyword corresponding to the property Value from the color table + keyword = SearchKeywordTableInt(aPropValue, kColorKTable); + + // next get the name as a string from the keywords table + if (keyword >= 0) { + nsCSSKeywords::AddRefTable(); + aStr = nsCSSKeywords::GetStringValue((nsCSSKeyword)keyword); + nsCSSKeywords::ReleaseTable(); + rv = PR_TRUE; + } + return rv; +} // define array of all CSS property hints #define CSS_PROP(_prop, _hint) NS_STYLE_HINT_##_hint, diff --git a/mozilla/content/xul/content/src/nsXULElement.cpp b/mozilla/content/xul/content/src/nsXULElement.cpp index 460cdb4dc9f..0064572fea1 100644 --- a/mozilla/content/xul/content/src/nsXULElement.cpp +++ b/mozilla/content/xul/content/src/nsXULElement.cpp @@ -113,6 +113,8 @@ // The XUL doc interface #include "nsIDOMXULDocument.h" +#include "nsISizeOfHandler.h" + // XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp #define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI; @@ -4221,6 +4223,13 @@ nsXULElement::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPr return NS_OK; } +void nsXULElement::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + // XXX - implement this if you want the sizes of XUL style rules + // dumped during StyleSize dump + return; +} + PRBool nsXULElement::ParseNumericValue(const nsString& aString, PRInt32& aIntValue, diff --git a/mozilla/content/xul/content/src/nsXULElement.h b/mozilla/content/xul/content/src/nsXULElement.h index a18ea1ae9aa..6980eb40b18 100644 --- a/mozilla/content/xul/content/src/nsXULElement.h +++ b/mozilla/content/xul/content/src/nsXULElement.h @@ -59,6 +59,8 @@ #include "nsXULAttributes.h" #include "nsIChromeEventHandler.h" +class nsISizeOfHandler; + class nsIDocument; class nsIRDFService; class nsISupportsArray; @@ -503,6 +505,8 @@ public: NS_IMETHOD GetStrength(PRInt32& aStrength) const; NS_IMETHOD MapFontStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); // nsIChromeEventHandler NS_DECL_NSICHROMEEVENTHANDLER diff --git a/mozilla/layout/base/public/nsIStyleContext.h b/mozilla/layout/base/public/nsIStyleContext.h index 7114c037350..5511672f3f3 100644 --- a/mozilla/layout/base/public/nsIStyleContext.h +++ b/mozilla/layout/base/public/nsIStyleContext.h @@ -33,6 +33,8 @@ #include "nsStyleStruct.h" #include "nsStyleConsts.h" +class nsISizeOfHandler; + class nsIFrame; class nsIPresContext; class nsISupportsArray; @@ -404,6 +406,8 @@ public: // debugging virtual void List(FILE* out, PRInt32 aIndent) = 0; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; + // ------------------------------------------------------------- // DEPRECATED METHODS - these are all going away, stop using them // get a style data struct by ID, may return null diff --git a/mozilla/layout/base/public/nsIStyleRule.h b/mozilla/layout/base/public/nsIStyleRule.h index e5107e4d019..4de54696d92 100644 --- a/mozilla/layout/base/public/nsIStyleRule.h +++ b/mozilla/layout/base/public/nsIStyleRule.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIMutableStyleContext; class nsIPresContext; @@ -51,6 +53,9 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) = 0; NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; }; + #endif /* nsIStyleRule_h___ */ diff --git a/mozilla/layout/base/public/nsIStyleRuleProcessor.h b/mozilla/layout/base/public/nsIStyleRuleProcessor.h index cedb70bc0d7..b4dafa92e12 100644 --- a/mozilla/layout/base/public/nsIStyleRuleProcessor.h +++ b/mozilla/layout/base/public/nsIStyleRuleProcessor.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIStyleContext; class nsIPresContext; @@ -67,6 +69,8 @@ public: NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent) = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleRuleProcessor_h___ */ diff --git a/mozilla/layout/base/public/nsIStyleSet.h b/mozilla/layout/base/public/nsIStyleSet.h index 2490787de41..7b9d5333a25 100644 --- a/mozilla/layout/base/public/nsIStyleSet.h +++ b/mozilla/layout/base/public/nsIStyleSet.h @@ -36,6 +36,8 @@ class nsIFrame; class nsIDocument; class nsIFrameManager; +#include "nsVoidArray.h" +class nsISizeOfHandler; // IID for the nsIStyleSet interface {e59396b0-b244-11d1-8031-006008159b5a} #define NS_ISTYLE_SET_IID \ @@ -180,9 +182,80 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) = 0; virtual void ListContexts(nsIStyleContext* aRootContext, FILE* out = stdout, PRInt32 aIndent = 0) = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; + virtual void ResetUniqueStyleItems(void) = 0; + +#ifdef DEBUG_SC_SHARING + // add and remove from the cache of all contexts + NS_IMETHOD AddStyleContext(nsIStyleContext *aNewStyleContext) = 0; + NS_IMETHOD RemoveStyleContext(nsIStyleContext *aNewStyleContext) = 0; +#endif }; extern NS_LAYOUT nsresult NS_NewStyleSet(nsIStyleSet** aInstancePtrResult); + +#define kUniqueItemsStartSize 128 + +class nsUniqueStyleItems : private nsVoidArray +{ +public : + // return a singleton instance of the nsUniqueStyleItems object + static nsUniqueStyleItems *GetUniqueStyleItems( void ){ + if(mInstance == nsnull){ + nsUniqueStyleItems *pInstance = new nsUniqueStyleItems; + NS_ASSERTION(pInstance == mInstance, "Singleton?"); + } + return mInstance; + } + + void *GetItem(void *aPtr){ + PRInt32 index = nsVoidArray::IndexOf(aPtr); + if( index != -1){ + return nsVoidArray::ElementAt(index); + } else { + return nsnull; + } + } + + PRBool AddItem(void *aPtr){ + if(nsVoidArray::IndexOf(aPtr) == -1){ + return nsVoidArray::AppendElement(aPtr); + } else { + return PR_FALSE; + } + } + + PRBool RemoveItem(void *aPtr){ + return nsVoidArray::RemoveElement(aPtr); + } + + PRInt32 Count(void){ + return nsVoidArray::Count(); + } + + void Clear(void){ + nsVoidArray::Clear(); + } +protected: + // disallow these: + nsUniqueStyleItems( const nsUniqueStyleItems& src); + nsUniqueStyleItems& operator =(const nsUniqueStyleItems& src); + + // make this accessable to factory only + nsUniqueStyleItems(void) : nsVoidArray(kUniqueItemsStartSize){ + NS_ASSERTION(mInstance == nsnull, "singleton?"); + mInstance=this; + } + + static nsUniqueStyleItems *mInstance; +}; + +#define UNIQUE_STYLE_ITEMS(_name) \ + nsUniqueStyleItems* ##_name = nsUniqueStyleItems::GetUniqueStyleItems(); \ + NS_ASSERTION(##_name != nsnull, "UniqueItems cannot be null: error in nsUniqueStyleImtes factory"); + + #endif /* nsIStyleSet_h___ */ diff --git a/mozilla/layout/base/public/nsIStyleSheet.h b/mozilla/layout/base/public/nsIStyleSheet.h index 03b4d6bbd5a..023ae19454f 100644 --- a/mozilla/layout/base/public/nsIStyleSheet.h +++ b/mozilla/layout/base/public/nsIStyleSheet.h @@ -24,6 +24,9 @@ #include #include "nsISupports.h" + +class nsISizeOfHandler; + class nsIAtom; class nsString; class nsIURI; @@ -66,6 +69,8 @@ public: // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleSheet_h___ */ diff --git a/mozilla/layout/base/src/nsStyleContext.cpp b/mozilla/layout/base/src/nsStyleContext.cpp index a4e66ad78d1..3c6dbc276f2 100644 --- a/mozilla/layout/base/src/nsStyleContext.cpp +++ b/mozilla/layout/base/src/nsStyleContext.cpp @@ -45,10 +45,18 @@ #include "nsIFrame.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" +#include "nsIPresShell.h" + static NS_DEFINE_IID(kIStyleContextIID, NS_ISTYLECONTEXT_IID); #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; } +//#ifdef DEBUG_SC_SHARING + + // -------------------- // nsStyleFont // @@ -1673,6 +1681,8 @@ public: virtual void List(FILE* out, PRInt32 aIndent); + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: void AppendChild(StyleContextImpl* aChild); void RemoveChild(StyleContextImpl* aChild); @@ -1701,6 +1711,8 @@ protected: StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; + + nsCOMPtr mStyleSet; }; static PRInt32 gLastDataCode; @@ -1748,6 +1760,21 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, if (nsnull != mRules) { mRules->EnumerateForwards(HashStyleRule, &mRuleHash); } + +#ifdef DEBUG_SC_SHARING + // add this instance to the style set + nsIPresShell* shell = nsnull; + aPresContext->GetShell(&shell); + if (shell) { + shell->GetStyleSet( getter_AddRefs(mStyleSet) ); + if (mStyleSet) { + // add it to the set: the set does NOT addref or release + // NOTE: QI here is not a good idea - this is the constructor so we are not whole yet... + mStyleSet->AddStyleContext((nsIStyleContext *)this); + } + NS_RELEASE( shell ); + } +#endif // DEBUG_SC_SHARING } StyleContextImpl::~StyleContextImpl() @@ -1760,8 +1787,14 @@ StyleContextImpl::~StyleContextImpl() } NS_IF_RELEASE(mPseudoTag); - NS_IF_RELEASE(mRules); + +#ifdef DEBUG_SC_SHARING + // remove this instance from the style set (remember, the set does not AddRef or Release us) + if (mStyleSet) { + mStyleSet->RemoveStyleContext((nsIStyleContext *)this); + } +#endif // DEBUG_SC_SHARING } NS_IMPL_ADDREF(StyleContextImpl) @@ -2446,6 +2479,123 @@ void StyleContextImpl::List(FILE* out, PRInt32 aIndent) } } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleContextImpl's size): +* 1) sizeof(*this) which gets all of the data members +* 2) adds in the size of the PseudoTag, if there is one +* +* Contained / Aggregated data (not reported as StyleContextImpl's size): +* 1) the Style Rules in mRules are not counted as part of sizeof(*this) +* (though the size of the nsISupportsArray ptr. is) so we need to +* count the rules seperately. For each rule in the mRules collection +* we call the SizeOf method and let it report itself. +* +* Children / siblings / parents: +* 1) We recurse over the mChild and mEmptyChild instances if they exist. +* These instances will then be accumulated seperately (not part of +* the containing instance's size) +* 2) We recurse over the siblings of the Child and Empty Child instances +* and count then seperately as well. +* 3) We recurse over our direct siblings (if any). +* +******************************************************************************/ +void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + static PRBool bDetailDumpDone = PR_FALSE; + if (!bDetailDumpDone) { + bDetailDumpDone = PR_TRUE; + PRUint32 totalSize=0; + + printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" ); + printf( "*************************************\n"); + printf( " - StyleFontImpl: %ld\n", (long)sizeof(mFont) ); + totalSize += (long)sizeof(mFont); + printf( " - StyleColorImpl: %ld\n", (long)sizeof(mColor) ); + totalSize += (long)sizeof(mColor); + printf( " - StyleSpacingImpl: %ld\n", (long)sizeof(mSpacing) ); + totalSize += (long)sizeof(mSpacing); + printf( " - StyleListImpl: %ld\n", (long)sizeof(mList) ); + totalSize += (long)sizeof(mList); + printf( " - StylePositionImpl: %ld\n", (long)sizeof(mPosition) ); + totalSize += (long)sizeof(mPosition); + printf( " - StyleTextImpl: %ld\n", (long)sizeof(mText) ); + totalSize += (long)sizeof(mText); + printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(mDisplay) ); + totalSize += (long)sizeof(mDisplay); + printf( " - StyleTableImpl: %ld\n", (long)sizeof(mTable) ); + totalSize += (long)sizeof(mTable); + printf( " - StyleContentImpl: %ld\n", (long)sizeof(mContent) ); + totalSize += (long)sizeof(mContent); + printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(mUserInterface) ); + totalSize += (long)sizeof(mUserInterface); + printf( " - StylePrintImpl: %ld\n", (long)sizeof(mPrint)); + totalSize += (long)sizeof(mPrint); + printf( " - Total: %ld\n", (long)totalSize); + printf( "*************************************\n"); + } + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + PRUint32 localSize=0; + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleContextImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add in the size of the member mPseudoTag + if(mPseudoTag){ + mPseudoTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // size up the rules (if not already done) + // XXX - overhead of the collection??? + if(mRules && uniqueItems->AddItem(mRules)){ + PRUint32 curRule, ruleCount; + mRules->Count(&ruleCount); + if (ruleCount > 0) { + for (curRule = 0; curRule < ruleCount; curRule++) { + nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(curRule); + NS_ASSERTION(rule, "null entry in Rules list is bad news"); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } + } + // now follow up with the child (and empty child) recursion + if (nsnull != mChild) { + StyleContextImpl* child = mChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mChild != child); + } + if (nsnull != mEmptyChild) { + StyleContextImpl* child = mEmptyChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mEmptyChild != child); + } + // and finally our direct siblings (if any) + if (nsnull != mNextSibling) { + mNextSibling->SizeOf(aSizeOfHandler, localSize); + } +} + NS_LAYOUT nsresult NS_NewStyleContext(nsIStyleContext** aInstancePtrResult, nsIStyleContext* aParentContext, diff --git a/mozilla/layout/base/src/nsStyleSet.cpp b/mozilla/layout/base/src/nsStyleSet.cpp index 7472ff0ddb1..3346da6cbd0 100644 --- a/mozilla/layout/base/src/nsStyleSet.cpp +++ b/mozilla/layout/base/src/nsStyleSet.cpp @@ -46,9 +46,12 @@ #define STYLESET_STOP_TIMER(a) ((void)0) #endif +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID); static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID); +// #ifdef DEBUG_SC_SHARING class StyleSetImpl : public nsIStyleSet #ifdef MOZ_PERF_METRICS @@ -175,6 +178,15 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + virtual void ResetUniqueStyleItems(void); + +#ifdef DEBUG_SC_SHARING + // add and remove from the cache of all contexts + NS_IMETHOD AddStyleContext(nsIStyleContext *aNewStyleContext); + NS_IMETHOD RemoveStyleContext(nsIStyleContext *aNewStyleContext); +#endif + #ifdef MOZ_PERF_METRICS NS_DECL_NSITIMERECORDER #endif @@ -207,6 +219,11 @@ protected: nsIStyleFrameConstruction* mFrameConstructor; +#ifdef DEBUG_SC_SHARING + nsVoidArray mStyleContextCache; // a cache of all style contexts for faster searching + // when we want to find style contexts in GetContext +#endif + MOZ_TIMER_DECLARE(mStyleResolutionWatch) #ifdef MOZ_PERF_METRICS @@ -222,6 +239,9 @@ StyleSetImpl::StyleSetImpl() mRuleProcessors(nsnull), mRecycler(nsnull), mFrameConstructor(nsnull) +#ifdef DEBUG_SC_SHARING + ,mStyleContextCache(0) +#endif #ifdef MOZ_PERF_METRICS ,mTimerEnabled(PR_FALSE) #endif @@ -237,6 +257,9 @@ StyleSetImpl::~StyleSetImpl() NS_IF_RELEASE(mRuleProcessors); NS_IF_RELEASE(mFrameConstructor); NS_IF_RELEASE(mRecycler); +#ifdef DEBUG_SC_SHARING + NS_ASSERTION( mStyleContextCache.Count() == 0, "StyleContextCache is not empty: leaking style context?"); +#endif } #ifndef MOZ_PERF_METRICS @@ -565,6 +588,10 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData) return PR_TRUE; } +#ifdef DEBUG_SC_SHARING + static int gNewCount=0; + static int gSharedCount=0; +#endif nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, nsIStyleContext* aParentContext, nsIAtom* aPseudoTag, @@ -572,11 +599,41 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, PRBool aForceUnique, PRBool& aUsedRules) { nsIStyleContext* result = nsnull; - aUsedRules = PR_FALSE; + +#ifdef DEBUG_SC_SHARING + static PRBool bCheckCache = PR_FALSE; // DEBUGGING: set to true or false in debugger... + + if ((PR_FALSE == aForceUnique) && (aParentContext != nsnull)) { + aParentContext->FindChildWithRules(aPseudoTag, aRules, result); + } + if (result == nsnull && bCheckCache) { + // check the context cache for another context to search... + if (PR_FALSE == aForceUnique) { + PRInt32 count = mStyleContextCache.Count(); + PRInt32 i; + for (i=0; iAddRef(); + pContext->FindChildWithRules(aPseudoTag, aRules, result); + pContext->Release(); + if (result != nsnull) { + printf( "StyleContext with matching rules found: %d of %d\n", (int)i, (int)count); + break; + } + } + } + } + } +#else if ((PR_FALSE == aForceUnique) && (nsnull != aParentContext)) { aParentContext->FindChildWithRules(aPseudoTag, aRules, result); } +#endif + if (nsnull == result) { if (NS_OK == NS_NewStyleContext(&result, aParentContext, aPseudoTag, aRules, aPresContext)) { if (PR_TRUE == aForceUnique) { @@ -584,11 +641,16 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, } aUsedRules = PRBool(nsnull != aRules); } -//fprintf(stdout, "+"); +#ifdef DEBUG_SC_SHARING + fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount); +#endif } +#ifdef DEBUG_SC_SHARING else { -//fprintf(stdout, "-"); + fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount); } +#endif + return result; } @@ -842,8 +904,8 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext, nsIStyleContext** aNewStyleContext) { NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); + NS_ASSERTION(aStyleContext, "must have style context"); + NS_ASSERTION(aNewStyleContext, "must have new style context"); nsresult result = NS_ERROR_NULL_POINTER; @@ -1241,3 +1303,177 @@ StyleSetImpl::PrintTimer(PRUint32 aTimerID) #endif +//----------------------------------------------------------------------------- + +#ifdef DEBUG_SC_SHARING +NS_IMETHODIMP +StyleSetImpl::AddStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in AddStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) == -1), "StyleContext added in AddStyleContext is already in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.AppendElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} + +NS_IMETHODIMP +StyleSetImpl::RemoveStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in RemoveStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) != -1), "StyleContext removed in AddStyleContext is not in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.RemoveElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} +#endif // DEBUG_SC_SHARING + +//----------------------------------------------------------------------------- + +// static +nsUniqueStyleItems *nsUniqueStyleItems ::mInstance = nsnull; + +void StyleSetImpl::ResetUniqueStyleItems(void) +{ + UNIQUE_STYLE_ITEMS(uniqueItems); + uniqueItems->Clear(); +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleSetImpl's size): +* 1) sizeof(*this) + sizeof (overhead only) each collection that exists +* and the FrameConstructor overhead +* +* Contained / Aggregated data (not reported as StyleSetImpl's size): +* 1) Override Sheets, DocSheets, BackstopSheets, RuleProcessors, Recycler +* are all delegated to. +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + NS_ASSERTION(0, "StyleSet has already been conted in SizeOf operation"); + // styleset has already been accounted for + return; + } + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleSet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(StyleSetImpl); + + // Next get the size of the OVERHEAD of objects we will delegate to: + if (mOverrideSheets && uniqueItems->AddItem(mOverrideSheets)){ + aSize += sizeof(*mOverrideSheets); + } + if (mDocSheets && uniqueItems->AddItem(mDocSheets)){ + aSize += sizeof(*mDocSheets); + } + if (mBackstopSheets && uniqueItems->AddItem(mBackstopSheets)){ + aSize += sizeof(*mBackstopSheets); + } + if (mRuleProcessors && uniqueItems->AddItem(mRuleProcessors)){ + aSize += sizeof(*mRuleProcessors); + } + if (mRecycler && uniqueItems->AddItem(mRecycler)){ + aSize += sizeof(*mRecycler); + } + /////////////////////////////////////////////// + // now the FrameConstructor + if(mFrameConstructor && uniqueItems->AddItem((void*)mFrameConstructor)){ + aSize += sizeof(mFrameConstructor); + } + aSizeOfHandler->AddSize(tag,aSize); + + /////////////////////////////////////////////// + // Now travers the collections and delegate + PRInt32 numSheets, curSheet; + PRUint32 localSize=0; + numSheets = GetNumberOfOverrideStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetOverrideStyleSheetAt(curSheet); //addref + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfDocStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetDocStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfBackstopStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetBackstopStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + /////////////////////////////////////////////// + // rule processors + PRUint32 numRuleProcessors,curRuleProcessor; + if(mRuleProcessors){ + mRuleProcessors->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRuleProcessors->ElementAt(curRuleProcessor); + if(processor){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + /////////////////////////////////////////////// + // and the recycled ones too + if(mRecycler){ + mRecycler->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRecycler->ElementAt(curRuleProcessor); + if(processor && uniqueItems->AddItem((void*)processor)){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + // now delegate the sizeof to the larger or more complex aggregated objects + // - none +} diff --git a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp index 34983b9a50b..c77e8db6e5a 100644 --- a/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp +++ b/mozilla/layout/html/content/src/nsGenericHTMLElement.cpp @@ -1550,7 +1550,7 @@ nsGenericHTMLElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult, sum += (PRUint32) aInstanceSize; if (mAttributes) { PRUint32 attrs = 0; - mAttributes->SizeOf(aSizer, &attrs); + mAttributes->SizeOf(aSizer, attrs); sum += attrs; } #endif diff --git a/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp b/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp index ae83f23cbf2..e3e0a719867 100644 --- a/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLBodyElement.cpp @@ -47,6 +47,10 @@ #include "nsIFrame.h" #include "nsIDocShell.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSStyleRuleIID, NS_ICSS_STYLE_RULE_IID); @@ -78,6 +82,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -104,6 +110,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nsHTMLBodyElement* mPart; // not ref-counted, cleared by content nsIHTMLCSSStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -380,6 +388,45 @@ BodyRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as BodyRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as BodyRule's size): +* 1) delegate to mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void BodyRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("BodyRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag, aSize); + + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } + + return; +} + //---------------------------------------------------------------------- @@ -538,6 +585,45 @@ BodyFixupRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as BodyFixupRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as BodyFixupRule's size): +* 1) Delegates to the mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void BodyFixupRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("BodyFixupRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag, aSize); + + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } + + return; +} + //---------------------------------------------------------------------- nsresult @@ -863,5 +949,6 @@ nsHTMLBodyElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, NS_IMETHODIMP nsHTMLBodyElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { + // XXX - self? Unique? (Content Size Dump) return mInner.SizeOf(aSizer, aResult, sizeof(*this)); } diff --git a/mozilla/layout/html/style/src/nsCSSDeclaration.cpp b/mozilla/layout/html/style/src/nsCSSDeclaration.cpp index 9025de4e49d..fa1f365a977 100644 --- a/mozilla/layout/html/style/src/nsCSSDeclaration.cpp +++ b/mozilla/layout/html/style/src/nsCSSDeclaration.cpp @@ -28,7 +28,11 @@ #include "nsStyleConsts.h" -//#define DEBUG_REFS +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); @@ -950,6 +954,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const; void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); NS_IMETHOD Count(PRUint32* aCount); NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsString& aReturn); @@ -993,7 +999,7 @@ CSSDeclarationImpl::CSSDeclarationImpl(void) NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; - fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (ctor): %ld\n", (long)gInstanceCount); #endif } @@ -1017,6 +1023,11 @@ CSSDeclarationImpl::CSSDeclarationImpl(const CSSDeclarationImpl& aCopy) DECL_IF_COPY(UserInterface); DECL_IF_COPY(Aural); +#ifdef DEBUG_REFS + ++gInstanceCount; + fprintf(stdout, "CSSDeclaration Instances (cp-ctor): %ld\n", (long)gInstanceCount); +#endif + if (aCopy.mImportant) { mImportant = new CSSDeclarationImpl(*(aCopy.mImportant)); NS_IF_ADDREF(mImportant); @@ -1060,7 +1071,7 @@ CSSDeclarationImpl::~CSSDeclarationImpl(void) #ifdef DEBUG_REFS --gInstanceCount; - fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (dtor): %ld\n", (long)gInstanceCount); #endif } @@ -3179,7 +3190,23 @@ PRBool CSSDeclarationImpl::AppendValueToString(nsCSSProperty aProperty, const ns aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { - aResult.Append(aValue.GetIntValue(), 10); + switch (aProperty) { + case eCSSProperty_color: + case eCSSProperty_background_color: { + // we can lookup the property in the ColorTable and then + // get a string mapping the name + nsCString str; + if (nsCSSProps::GetColorName(aValue.GetIntValue(), str)){ + aResult.Append(str); + } else { + aResult.Append(aValue.GetIntValue(), 10); + } + } + break; + + default: + aResult.Append(aValue.GetIntValue(), 10); + } } else if (eCSSUnit_Enumerated == unit) { if (eCSSProperty_text_decoration == aProperty) { @@ -3737,6 +3764,80 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSDeclarationImpl's size): +* 1) sizeof(*this) + the sizeof each non-null attribute +* +* Contained / Aggregated data (not reported as CSSDeclarationImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSDeclarationImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSDeclarationImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now add in all of the contained objects, checking for duplicates on all of them + if(mFont && uniqueItems->AddItem(mFont)){ + aSize += sizeof(*mFont); + } + if(mColor && uniqueItems->AddItem(mColor)){ + aSize += sizeof(*mColor); + } + if(mText && uniqueItems->AddItem(mText)){ + aSize += sizeof(*mText); + } + if(mMargin && uniqueItems->AddItem(mMargin)){ + aSize += sizeof(*mMargin); + } + if(mPosition && uniqueItems->AddItem(mPosition)){ + aSize += sizeof(*mPosition); + } + if(mList && uniqueItems->AddItem(mList)){ + aSize += sizeof(*mList); + } + if(mDisplay && uniqueItems->AddItem(mDisplay)){ + aSize += sizeof(*mDisplay); + } + if(mTable && uniqueItems->AddItem(mTable)){ + aSize += sizeof(*mTable); + } + if(mBreaks && uniqueItems->AddItem(mBreaks)){ + aSize += sizeof(*mBreaks); + } + if(mPage && uniqueItems->AddItem(mPage)){ + aSize += sizeof(*mPage); + } + if(mContent && uniqueItems->AddItem(mContent)){ + aSize += sizeof(*mContent); + } + if(mUserInterface && uniqueItems->AddItem(mUserInterface)){ + aSize += sizeof(*mUserInterface); + } + if(mAural && uniqueItems->AddItem(mAural)){ + aSize += sizeof(*mAural); + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSDeclarationImpl::Count(PRUint32* aCount) { diff --git a/mozilla/layout/html/style/src/nsCSSProps.cpp b/mozilla/layout/html/style/src/nsCSSProps.cpp index 709f2b9c749..4dc106dcd20 100644 --- a/mozilla/layout/html/style/src/nsCSSProps.cpp +++ b/mozilla/layout/html/style/src/nsCSSProps.cpp @@ -670,8 +670,7 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = { -1,-1 }; -static const nsCString& -SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +static PRInt32 SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[]) { PRInt32 i = 1; for (;;) { @@ -679,14 +678,23 @@ SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) break; } if (aValue == aTable[i]) { - return nsCSSKeywords::GetStringValue(nsCSSKeyword(aTable[i-1])); + return PRInt32(aTable[i-1]); } i += 2; } - return *kNullStr; + return -1; } - +static const nsCString& +SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +{ + PRInt32 i = SearchKeywordTableInt(aValue, aTable); + if (i < 0) { + return *kNullStr; + } else { + return nsCSSKeywords::GetStringValue(nsCSSKeyword(i)); + } +} const nsCString& nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, PRInt32 aValue) @@ -1042,6 +1050,23 @@ static const PRInt32 kBackgroundYPositionKTable[] = { return *kNullStr; } +PRBool nsCSSProps::GetColorName(PRInt32 aPropValue, nsCString &aStr) +{ + PRBool rv = PR_FALSE; + PRInt32 keyword = -1; + + // first get the keyword corresponding to the property Value from the color table + keyword = SearchKeywordTableInt(aPropValue, kColorKTable); + + // next get the name as a string from the keywords table + if (keyword >= 0) { + nsCSSKeywords::AddRefTable(); + aStr = nsCSSKeywords::GetStringValue((nsCSSKeyword)keyword); + nsCSSKeywords::ReleaseTable(); + rv = PR_TRUE; + } + return rv; +} // define array of all CSS property hints #define CSS_PROP(_prop, _hint) NS_STYLE_HINT_##_hint, diff --git a/mozilla/layout/html/style/src/nsCSSProps.h b/mozilla/layout/html/style/src/nsCSSProps.h index 8180f359371..81778dd3ff8 100644 --- a/mozilla/layout/html/style/src/nsCSSProps.h +++ b/mozilla/layout/html/style/src/nsCSSProps.h @@ -60,6 +60,10 @@ public: // value. Return back nullstr if no value is found static const nsCString& LookupPropertyValue(nsCSSProperty aProperty, PRInt32 aValue); + // Get a color name for a predefined color value like buttonhighlight or activeborder + // Sets the aStr param to the name of the propertyID + static PRBool GetColorName(PRInt32 aPropID, nsCString &aStr); + static const PRInt32 kHintTable[]; // Keyword/Enum value tables diff --git a/mozilla/layout/html/style/src/nsCSSRules.cpp b/mozilla/layout/html/style/src/nsCSSRules.cpp index e4e9cba802f..32e544aa3e7 100644 --- a/mozilla/layout/html/style/src/nsCSSRules.cpp +++ b/mozilla/layout/html/style/src/nsCSSRules.cpp @@ -33,6 +33,9 @@ #include "nsLayoutAtoms.h" #include "nsICSSStyleSheet.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -82,6 +85,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -167,6 +172,43 @@ CSSCharsetRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSCharSetRuleImpl's size): +* 1) sizeof(*this) + the size of the mEncoding string +* +* Contained / Aggregated data (not reported as CSSCharsetRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSCharsetRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSCharsetRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add the string for encoding value + mEncoding.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mEncoding); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); +} + NS_IMETHODIMP CSSCharsetRuleImpl::GetType(PRInt32& aType) const { @@ -229,6 +271,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -317,6 +361,49 @@ CSSImportRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the size of the mMedia string +* +* Contained / Aggregated data (not reported as CSSImportRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add the strings for the URLSpec and the Media + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + mMedia.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mMedia); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); + +} + NS_IMETHODIMP CSSImportRuleImpl::GetType(PRInt32& aType) const { @@ -401,6 +488,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -563,6 +652,67 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSMediaRuleImpl's size): +* 1) sizeof(*this) + the size of each unique atom in the mMedia collection +* +* Contained / Aggregated data (not reported as CSSMediaRuleImpl's size): +* 1) Delegate to the rules in the mRules collection to report theri own size +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSMediaRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + if (mMedia) { + // get the sizes of the media atoms (if unique) + PRUint32 index = 0; + PRUint32 count; + mMedia->Count(&count); + while (index < count) { + nsIAtom* medium = (nsIAtom*)mMedia->ElementAt(index++); + if(medium && uniqueItems->AddItem(medium)){ + medium->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + NS_IF_RELEASE(medium); + } + } + // we are done with the size we report for ourself + aSizeOfHandler->AddSize(tag,aSize); + + if (mRules) { + // delegate to the rules themselves (do not sum into our size) + PRUint32 index = 0; + PRUint32 count; + mRules->Count(&count); + while (index < count) { + nsICSSRule* rule = (nsICSSRule*)mRules->ElementAt(index++); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } +} + NS_IMETHODIMP CSSMediaRuleImpl::GetType(PRInt32& aType) const { @@ -693,6 +843,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -788,6 +940,50 @@ CSSNameSpaceRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSNamespaceRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the sizeof the mPrefix atom (if it ieists) +* +* Contained / Aggregated data (not reported as CSSNamespaceRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSNameSpaceRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSNameSpaceRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // get the member data as part of this dump + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + + if(mPrefix && uniqueItems->AddItem(mPrefix)){ + mPrefix->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSNameSpaceRuleImpl::GetType(PRInt32& aType) const { diff --git a/mozilla/layout/html/style/src/nsCSSStyleRule.cpp b/mozilla/layout/html/style/src/nsCSSStyleRule.cpp index a11c6c59461..e6557253425 100644 --- a/mozilla/layout/html/style/src/nsCSSStyleRule.cpp +++ b/mozilla/layout/html/style/src/nsCSSStyleRule.cpp @@ -52,6 +52,11 @@ #include "nsINameSpaceManager.h" #include "nsILookAndFeel.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS + static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); @@ -138,6 +143,10 @@ PRBool nsAtomList::Equals(const nsAtomList* aOther) const MOZ_DECL_CTOR_COUNTER(nsAttrSelector); +#ifdef DEBUG_REFS +PRUint32 gAttrSelectorCount=0; +#endif + nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) : mNameSpace(aNameSpace), mAttr(nsnull), @@ -147,6 +156,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -160,6 +175,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr, PRUint mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -172,6 +193,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (cp-ctor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_ADDREF(mAttr); NS_IF_COPY(mNext, aCopy.mNext, nsAttrSelector); } @@ -179,6 +206,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) nsAttrSelector::~nsAttrSelector(void) { MOZ_COUNT_DTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount--; + printf( "nsAttrSelector Instances (dtor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_RELEASE(mAttr); NS_IF_DELETE(mNext); } @@ -203,8 +236,56 @@ PRBool nsAttrSelector::Equals(const nsAttrSelector* aOther) const return PR_FALSE; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsAttrSelector's size): +* 1) sizeof(*this) + the size of mAttr atom (if it exists and is unique) +* +* Contained / Aggregated data (not reported as nsAttrSelector's size): +* none +* +* Children / siblings / parents: +* 1) Recurses to the mMext instance which is reported as a seperate instance +* +******************************************************************************/ +void nsAttrSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsAttrSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add in the mAttr atom + if (mAttr && uniqueItems->AddItem(mAttr)){ + mAttr->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // recurse to the next one... + if(mNext){ + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + MOZ_DECL_CTOR_COUNTER(nsCSSSelector); +#ifdef DEBUG_REFS +PRUint32 gSelectorCount=0; +#endif + nsCSSSelector::nsCSSSelector(void) : mNameSpace(kNameSpaceID_Unknown), mTag(nsnull), mID(nsnull), @@ -215,6 +296,11 @@ nsCSSSelector::nsCSSSelector(void) mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) @@ -232,12 +318,22 @@ nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) NS_IF_COPY(mClassList, aCopy.mClassList, nsAtomList); NS_IF_COPY(mPseudoClassList, aCopy.mPseudoClassList, nsAtomList); NS_IF_COPY(mAttrList, aCopy.mAttrList, nsAttrSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (cp-ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::~nsCSSSelector(void) { MOZ_COUNT_DTOR(nsCSSSelector); Reset(); + +#ifdef DEBUG_REFS + gSelectorCount--; + printf( "nsCSSSelector Instances (dtor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector& nsCSSSelector::operator=(const nsCSSSelector& aCopy) @@ -429,6 +525,90 @@ PRInt32 nsCSSSelector::CalcWeight(void) const return weight; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsCSSSelector's size): +* 1) sizeof(*this) + the size of the mTag and mID atoms (if unique) +* + the size of the mClassList and mPseudoClassList unique items +* +* Contained / Aggregated data (not reported as nsCSSSelector's size): +* 1) AttributeList is called out to seperately if it exists +* +* Children / siblings / parents: +* 1) Recurses to mNext which is counted as it's own instance +* +******************************************************************************/ +void nsCSSSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsCSSSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now get the member-atoms and add them in + if(mTag && uniqueItems->AddItem(mTag)){ + localSize = 0; + mTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + if(mID && uniqueItems->AddItem(mID)){ + localSize = 0; + mID->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + // a couple of simple atom lists + if(mClassList && uniqueItems->AddItem(mClassList)){ + aSize += sizeof(*mClassList); + nsAtomList *pNext = nsnull; + pNext = mClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + if(mPseudoClassList && uniqueItems->AddItem(mPseudoClassList)){ + nsAtomList *pNext = nsnull; + pNext = mPseudoClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + // done with undelegated sizes + aSizeOfHandler->AddSize(tag, aSize); + + // the AttributeList gets its own delegation-call + if(mAttrList){ + localSize = 0; + mAttrList->SizeOf(aSizeOfHandler, localSize); + } + // finally chain to the next... + if(mNext){ + localSize = 0; + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + // -- CSSImportantRule ------------------------------- static nscoord CalcLength(const nsCSSValue& aValue, const nsFont& aFont, @@ -467,6 +647,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: virtual ~CSSImportantRule(void); @@ -555,6 +737,48 @@ CSSImportantRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportantRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSImportantRule's size): +* 1) mDeclaration is sized seperately +* 2) mSheet is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportantRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportantRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSImportantRule); + aSizeOfHandler->AddSize(tag,aSize); + + // now dump the mDeclaration and mSheet + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // -- nsDOMStyleRuleDeclaration ------------------------------- class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration @@ -729,6 +953,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsIDOMCSSRule interface NS_IMETHOD GetType(PRUint16* aType); NS_IMETHOD GetCssText(nsString& aCssText); @@ -762,6 +988,10 @@ protected: void* mScriptObject; }; +#ifdef DEBUG_REFS +PRUint32 gStyleRuleCount=0; +#endif + CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) : nsCSSRule(), mSelector(aSelector), mSelectorText(), mDeclaration(nsnull), @@ -769,6 +999,10 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (ctor): %ld\n", (long)gStyleRuleCount); +#endif } CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) @@ -781,6 +1015,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (cp-ctor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* copySel = aCopy.mSelector.mNext; nsCSSSelector* ourSel = &mSelector; @@ -799,6 +1038,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) CSSStyleRuleImpl::~CSSStyleRuleImpl(void) { +#ifdef DEBUG_REFS + gStyleRuleCount--; + printf( "CSSStyleRuleImpl Instances (dtor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* next = mSelector.mNext; while (nsnull != next) { @@ -2856,6 +3100,64 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleRuleImpl's size): +* 1) sizeof(*this) + size of the mSelectorText +* + sizeof the DOMDeclaration if it exists and is unique +* +* Contained / Aggregated data (not reported as CSSStyleRuleImpl's size): +* 1) mDeclaration if it exists +* 2) mImportantRule if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // remove the sizeof the mSelector's class since we count it seperately below + aSize -= sizeof(mSelector); + + // add in the length of the selectorText + mSelectorText.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mSelectorText); // counted in sizeof(*this) and nsString.SizeOf() + + // and add the size of the DOMDeclaration + // XXX - investigate the size and quantity of these + if(mDOMDeclaration && uniqueItems->AddItem(mDOMDeclaration)){ + aSize += sizeof(DOMCSSDeclarationImpl); + } + aSizeOfHandler->AddSize(tag,aSize); + + // now delegate to the Selector, Declaration, and ImportantRule + mSelector.SizeOf(aSizeOfHandler, localSize); + + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mImportantRule){ + mImportantRule->SizeOf(aSizeOfHandler, localSize); + } +} + NS_IMETHODIMP CSSStyleRuleImpl::GetType(PRUint16* aType) { @@ -2970,6 +3272,5 @@ NS_HTML nsresult if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(kICSSStyleRuleIID, (void **) aInstancePtrResult); } diff --git a/mozilla/layout/html/style/src/nsCSSStyleSheet.cpp b/mozilla/layout/html/style/src/nsCSSStyleSheet.cpp index 5c1d752a598..4ebea9b15b1 100644 --- a/mozilla/layout/html/style/src/nsCSSStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsCSSStyleSheet.cpp @@ -62,7 +62,12 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsITextContent.h" #include "prlog.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + //#define DEBUG_RULES +//#define EVENT_DEBUG static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -407,6 +412,8 @@ public: nsIAtom* aMedium, nsIContent* aContent); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + protected: RuleCascadeData* GetRuleCascade(nsIAtom* aMedium); @@ -433,6 +440,8 @@ public: virtual void RebuildNameSpaces(void); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsVoidArray mSheets; nsIURI* mURL; @@ -521,6 +530,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + // nsIDOMStyleSheet interface NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); @@ -1048,6 +1059,80 @@ CSSStyleSheetInner::RebuildNameSpaces(void) } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetInner's size): +* 1) sizeof(*this) + sizeof mSheets array (not contents though) +* + size of the mOrderedRules array (not the contents though) +* +* Contained / Aggregated data (not reported as CSSStyleSheetInner's size): +* 1) mSheets: each style sheet is sized seperately +* 2) mOrderedRules: each fule is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleSheetInner::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + PRBool rulesCounted=PR_FALSE; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheetInner")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetInner); + + // add in the size of the mSheets array itself + mSheets.SizeOf(aSizeOfHandler,&localSize); + aSize += localSize; + + // and the mOrderedRules array (if there is one) + if(mOrderedRules && uniqueItems->AddItem(mOrderedRules)){ + rulesCounted=PR_TRUE; + // no SizeOf method so we just get the basic object size + aSize += sizeof(*mOrderedRules); + } + aSizeOfHandler->AddSize(tag,aSize); + + + // delegate to the contained containers + // mSheets : nsVoidArray + { + PRUint32 sheetCount, sheetCur; + sheetCount = mSheets.Count(); + for(sheetCur=0; sheetCur < sheetCount; sheetCur++){ + nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)mSheets.ElementAt(sheetCur); + if(sheet){ + sheet->SizeOf(aSizeOfHandler, localSize); + } + } + } + // mOrderedRules : nsISupportsArray* + if(mOrderedRules && rulesCounted){ + PRUint32 ruleCount, ruleCur; + mOrderedRules->Count(&ruleCount); + for(ruleCur=0; ruleCur < ruleCount; ruleCur++){ + nsICSSRule* rule = (nsICSSRule*)mOrderedRules->ElementAt(ruleCur); + if(rule){ + rule->SizeOf(aSizeOfHandler, localSize); + NS_IF_RELEASE(rule); + } + } + } +} + // ------------------------------- // CSS Style Sheet @@ -1837,6 +1922,59 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const ListRules(mInner->mOrderedRules, out, aIndent); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetImpl's size): +* 1) sizeof(*this) + sizeof the mImportsCollection + sizeof mCuleCollection) +* +* Contained / Aggregated data (not reported as CSSStyleSheetImpl's size): +* 1) mInner is delegated to be counted seperately +* +* Children / siblings / parents: +* 1) Recurse to mFirstChild +* +******************************************************************************/ +void CSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is already accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetImpl); + + // add up the contained objects we won't delegate to: + // NOTE that we just add the sizeof the objects + // since the style data they contain is accounted for elsewhere + // - mImportsCollection + // - mRuleCollection + aSize += sizeof(mImportsCollection); + aSize += sizeof(mRuleCollection); + aSizeOfHandler->AddSize(tag,aSize); + + // size the inner + if(mInner){ + mInner->SizeOf(aSizeOfHandler, localSize); + } + + // now travers the children (recursively, I'm sorry to say) + if(mFirstChild){ + PRUint32 childSize=0; + mFirstChild->SizeOf(aSizeOfHandler, childSize); + } +} + static PRBool EnumClearRuleCascades(void* aProcessor, void* aData) { @@ -2308,6 +2446,29 @@ static PRBool IsLinkPseudo(nsIAtom* aAtom) (nsCSSAtoms::visitedPseudo == aAtom)); } +static PRBool IsEventSensitive(nsIAtom *aPseudo, nsIAtom *aContentTag, PRBool aSelectorIsGlobal) +{ + // if the selector is global, meaning it is not tied to a tag, then + // we restrict the application of the event pseudo to the following tags + if (aSelectorIsGlobal) { + return PRBool ((nsHTMLAtoms::a == aContentTag) || + (nsHTMLAtoms::button == aContentTag) || + (nsHTMLAtoms::img == aContentTag) || + (nsHTMLAtoms::input == aContentTag) || + (nsHTMLAtoms::li == aContentTag) || + (nsHTMLAtoms::label == aContentTag) || + (nsHTMLAtoms::select == aContentTag) || + (nsHTMLAtoms::textarea == aContentTag) || + (nsHTMLAtoms::textPseudo == aContentTag) || + // We require a Layout Atom too + (nsLayoutAtoms::textTagName == aContentTag) + ); + } else { + // selector is not global, so apply the event pseudo to everything except HTML and BODY + return PRBool ((nsHTMLAtoms::html != aContentTag) && + (nsHTMLAtoms::body != aContentTag)); + } +} static PRBool SelectorMatches(nsIPresContext* aPresContext, nsCSSSelector* aSelector, nsIContent* aContent, PRBool aTestState) @@ -2488,12 +2649,49 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, result = PR_FALSE; } else if (IsEventPseudo(pseudoClass->mAtom)) { - if (aTestState) { + // check if the element is event-sensitive + if (!contentTag) { + if (aContent) { + aContent->GetTag(contentTag); + } + } + +#ifdef EVENT_DEBUG + nsAutoString strTag; + // easier to watch the string value than the ATOM + if (contentTag) { + contentTag->ToString(strTag); + } +#endif + // Quirk Mode: check to see if the element is event-sensitive + // - see if the selector applies to event pseudo classes + // NOTE: we distinguish between global and subjected selectors so + // pass that information on to the determining routine + nsCompatibility quirkMode = eCompatibility_Standard; + aPresContext->GetCompatibilityMode(&quirkMode); + PRBool isSelectorGlobal = aSelector->mTag==nsnull ? PR_TRUE : PR_FALSE; + if ((eCompatibility_NavQuirks == quirkMode) && + (!IsEventSensitive(pseudoClass->mAtom, contentTag, isSelectorGlobal))){ + result = PR_FALSE; + } else if (aTestState) { if (! eventStateManager) { aPresContext->GetEventStateManager(&eventStateManager); - if (eventStateManager) { - eventStateManager->GetContentState(aContent, eventState); + } + if (eventStateManager) { + eventStateManager->GetContentState(aContent, eventState); + +#ifdef EVENT_DEBUG + nsAutoString strPseudo, strTag; + pseudoClass->mAtom->ToString(strPseudo); + if (!contentTag) { + if (aContent) aContent->GetTag(contentTag); } + if (contentTag) { + contentTag->ToString(strTag); + } + printf("Tag: %s PseudoClass: %s EventState: %d\n", + strTag.ToNewCString(), strPseudo.ToNewCString(), (int)eventState); +#endif } if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE)); @@ -2507,14 +2705,14 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, else if (nsCSSAtoms::dragOverPseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_DRAGOVER)); } - } + } } else if (IsLinkPseudo(pseudoClass->mAtom)) { // XXX xml link too - if(!tagset) { - tagset=PR_TRUE; - aContent->GetTag(contentTag); - } + if(!tagset) { + tagset=PR_TRUE; + aContent->GetTag(contentTag); + } if (nsHTMLAtoms::a == contentTag) { // make sure this anchor has a link even if we are not testing state // if there is no link, then this anchor is not really a linkpseudo. @@ -2888,6 +3086,159 @@ CSSRuleProcessor::HasStateDependentStyle(nsIPresContext* aPresContext, return ((isStateful) ? NS_OK : NS_COMFALSE); } + +struct CascadeSizeEnumData { + + CascadeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem, + nsIAtom *aTag) + { + handler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + tag = aTag; + } + // weak references all 'round + + nsISizeOfHandler *handler; + nsUniqueStyleItems *uniqueItems; + nsIAtom *tag; +}; + +static +PRBool StateSelectorsSizeEnumFunc( void *aSelector, void *aData ) +{ + nsCSSSelector* selector = (nsCSSSelector*)aSelector; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(selector && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)selector)){ + return PR_TRUE; + } + + // pass the call to the selector + PRUint32 localSize = 0; + selector->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool WeightedRulesSizeEnumFunc( nsISupports *aRule, void *aData ) +{ + nsICSSStyleRule* rule = (nsICSSStyleRule*)aRule; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(rule && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)rule)){ + return PR_TRUE; + } + + PRUint32 localSize=0; + + // pass the call to the rule + rule->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool CascadeSizeEnumFunc(nsHashKey* aKey, void *aCascade, void *aData) +{ + RuleCascadeData* cascade = (RuleCascadeData *) aCascade; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(cascade && pData, "null arguments not supported"); + + // see if the cascade has already been counted + if(!(pData->uniqueItems->AddItem(cascade))){ + return PR_TRUE; + } + // record the size of the cascade data itself + PRUint32 localSize = sizeof(RuleCascadeData); + pData->handler->AddSize(pData->tag, localSize); + + // next add up the selectors and the weighted rules for the cascade + nsCOMPtr stateSelectorSizeTag; + stateSelectorSizeTag = getter_AddRefs(NS_NewAtom("CascadeStateSelectors")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,stateSelectorSizeTag); + cascade->mStateSelectors.EnumerateForwards(StateSelectorsSizeEnumFunc, &stateData); + + if(cascade->mWeightedRules){ + nsCOMPtr weightedRulesSizeTag; + weightedRulesSizeTag = getter_AddRefs(NS_NewAtom("CascadeWeightedRules")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,weightedRulesSizeTag); + cascade->mWeightedRules->EnumerateForwards(WeightedRulesSizeEnumFunc, &stateData); + } + return PR_TRUE; +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSRuleProcessor's size): +* 1) sizeof(*this) + mMediumCascadeTable hashtable overhead +* +* Contained / Aggregated data (not reported as CSSRuleProcessor's size): +* 1) Delegate to the StyleSheets in the mSheets collection +* 2) Delegate to the Rules in the CascadeTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSRuleProcessor::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSRuleProcessor")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSRuleProcessor); + + // collect sizes for the data + // - mSheets + // - mMediumCascadeTable + + // sheets first + if(mSheets && uniqueItems->AddItem(mSheets)){ + PRUint32 sheetCount, curSheet, localSize; + mSheets->Count(&sheetCount); + for(curSheet=0; curSheet < sheetCount; curSheet++){ + nsICSSStyleSheet *pSheet = (nsICSSStyleSheet *)mSheets->ElementAt(curSheet); + if(pSheet && uniqueItems->AddItem((void*)pSheet)){ + pSheet->SizeOf(aSizeOfHandler, localSize); + // XXX aSize += localSize; + } + } + } + + // and for the medium cascade table we account for the hash table overhead, + // and then compute the sizeof each rule-cascade in the table + if(mMediumCascadeTable){ + PRUint32 count; + count = mMediumCascadeTable->Count(); + localSize = sizeof(PLHashTable); + if(count > 0){ + aSize += sizeof(PLHashEntry) * count; + // now go ghrough each RuleCascade in the table + nsCOMPtr tag = getter_AddRefs(NS_NewAtom("RuleCascade")); + CascadeSizeEnumData data(aSizeOfHandler, uniqueItems, tag); + mMediumCascadeTable->Enumerate(CascadeSizeEnumFunc, &data); + } + } + + // now add the size of the RuleProcessor + aSizeOfHandler->AddSize(tag,aSize); +} + static PRBool DeleteRuleCascade(nsHashKey* aKey, void* aValue, void* closure) { delete ((RuleCascadeData*)aValue); diff --git a/mozilla/layout/html/style/src/nsHTMLAttributes.cpp b/mozilla/layout/html/style/src/nsHTMLAttributes.cpp index b075ad6de63..fa2321da0ae 100644 --- a/mozilla/layout/html/style/src/nsHTMLAttributes.cpp +++ b/mozilla/layout/html/style/src/nsHTMLAttributes.cpp @@ -33,6 +33,9 @@ #include "nsIHTMLContent.h" #include "nsVoidArray.h" #include "nsISizeOfHandler.h" +#include "nsCOMPtr.h" + +#include "nsIStyleSet.h" static NS_DEFINE_IID(kIHTMLAttributesIID, NS_IHTML_ATTRIBUTES_IID); @@ -215,7 +218,6 @@ struct HTMLAttribute { return PR_FALSE; } -#ifdef DEBUG nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { if (!aResult) { return NS_ERROR_NULL_POINTER; @@ -223,7 +225,6 @@ struct HTMLAttribute { *aResult = sizeof(*this); return NS_OK; } -#endif nsIAtom* mAttribute; nsHTMLValue mValue; @@ -320,15 +321,7 @@ public: NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; -#ifdef DEBUG - nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const { - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } - *aResult = sizeof(*this); - return NS_OK; - } -#endif + void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult); nsIHTMLStyleSheet* mSheet; PRInt32 mUseCount; @@ -780,6 +773,33 @@ nsHTMLMappedAttributes::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsHTMLMappedAttributes's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as nsHTMLMappedAttributes's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void nsHTMLMappedAttributes::SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) +{ + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this is already accounted for + return; + } + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLMappedAttributes")); + aResult = sizeof(*this); + aSizer->AddSize(tag, aResult); +} + //-------------------- const PRInt32 kNameBufferSize = 4; @@ -842,7 +862,7 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; - NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; + void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult); protected: virtual nsresult SetAttributeName(nsIAtom* aAttrName, PRBool& aFound); @@ -1503,14 +1523,18 @@ HTMLAttributesImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } -NS_IMETHODIMP -HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const +void HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) { - if (!aResult) { - return NS_ERROR_NULL_POINTER; - } PRUint32 sum = 0; -#ifdef DEBUG + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this is already accounted for + return; + } + + // XXX step through this again sum = sizeof(*this); if (mAttrNames != mNameBuffer) { sum += sizeof(*mAttrNames) * mAttrSize; @@ -1519,7 +1543,7 @@ HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const HTMLAttribute* ha = mFirstUnmapped; while (ha) { PRUint32 asum = 0; - ha->SizeOf(aSizer, &asum); + ha->SizeOf(aSizer, &asum); // XXX Unique??? sum += asum; ha = ha->mNext; } @@ -1529,13 +1553,16 @@ HTMLAttributesImpl::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const aSizer->RecordObject((void*)mMapped, &recorded); if (!recorded) { PRUint32 asum = 0; - mMapped->SizeOf(aSizer, &asum); + mMapped->SizeOf(aSizer, asum); // XXX Unique??? sum += asum; } } -#endif - *aResult = sum; - return NS_OK; + + aResult = sum; + + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLAttributesImpl")); + aSizer->AddSize(tag, aResult); } extern NS_HTML nsresult diff --git a/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp index cfa778db981..c635932d139 100644 --- a/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLCSSStyleSheet.cpp @@ -38,6 +38,10 @@ #include "nsIMutableStyleContext.h" #include "nsIPresContext.h" #include "nsIDocument.h" +#include "nsCOMPtr.h" + +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -61,6 +65,8 @@ public: nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLCSSStyleSheet* mSheet; }; @@ -188,6 +194,44 @@ CSSFirstLineRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSFirstLineRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSFirstLineRule's size): +* 1) Delegate to mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSFirstLineRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSFirstLine-LetterRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // ----------------------------------------------------------- class CSSFirstLetterRule : public CSSFirstLineRule { @@ -321,6 +365,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy); @@ -666,6 +712,56 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const fputs("\n", out); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLCSSStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLCSSStyleSheetImpl's size): +* 1) We don't really delegate but count seperately the FirstLineRule and +* the FirstLetterRule if the exist and are unique instances +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLCSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLCSSStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // Now the associated rules (if they exist) + // - mFirstLineRule + // - mFirstLetterRule + if(mFirstLineRule && uniqueItems->AddItem((void*)mFirstLineRule)){ + localSize = sizeof(*mFirstLineRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLineRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mFirstLetterRule && uniqueItems->AddItem((void*)mFirstLetterRule)){ + localSize = sizeof(*mFirstLetterRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLetterRule")); + aSizeOfHandler->AddSize(tag,localSize); + } +} // XXX For backwards compatibility and convenience NS_HTML nsresult diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index 506af22d0f5..3487fcc832d 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -54,6 +54,9 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsINameSpaceManager.h" #include "nsLayoutAtoms.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -77,6 +80,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nscolor mColor; nsIHTMLStyleSheet* mSheet; }; @@ -88,6 +93,8 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nscolor mBackgroundColor; PRBool mForegroundSet; PRBool mBackgroundSet; @@ -158,6 +165,44 @@ HTMLColorRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLColorRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as HTMLColorRule's size): +* 1) delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + HTMLDocumentColorRule::HTMLDocumentColorRule(nsIHTMLStyleSheet* aSheet) : HTMLColorRule(aSheet) { @@ -186,6 +231,44 @@ HTMLDocumentColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresCon return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLDocumentColorRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLDocumentColorRule's size): +* 1) Delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLDocumentColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLDocumentColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + class GenericTableRule: public nsIStyleRule { public: GenericTableRule(nsIHTMLStyleSheet* aSheet); @@ -207,6 +290,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -269,6 +354,46 @@ GenericTableRule::List(FILE* out, PRInt32 aIndent) const { return NS_OK; } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as GenericTableRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as GenericTableRule's size): +* 1) Delegate to the mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void GenericTableRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("GenericTableRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + + // ----------------------------------------------------------- // this rule only applies in NavQuirks mode // ----------------------------------------------------------- @@ -307,10 +432,13 @@ TableBackgroundRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresConte styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } +// NOTE: Nav does not inherit the background image: this was over-zealous and mistaken +#if 0 if (!(parentStyleColor->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE)) { styleColor->mBackgroundImage = parentStyleColor->mBackgroundImage; styleColor->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE; } +#endif NS_RELEASE(parentContext); } @@ -520,6 +648,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy); @@ -541,6 +671,9 @@ protected: HTMLDocumentColorRule* mDocumentColorRule; TableBackgroundRule* mTableBackgroundRule; TableTHRule* mTableTHRule; + // NOTE: if adding more rules, be sure to update + // the SizeOf method to include them + nsHashtable mMappedAttrTable; }; @@ -1244,6 +1377,141 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } +struct MappedAttributeSizeEnumData { + MappedAttributeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem) + + { + aHandler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + } + // weak references all 'round + + nsISizeOfHandler *aHandler; + nsUniqueStyleItems *uniqueItems; +}; + +static +PRBool MappedSizeAttributes(nsHashKey *aKey, void *aData, void* closure) +{ + MappedAttributeSizeEnumData *pData = (MappedAttributeSizeEnumData *)closure; + NS_ASSERTION(pData,"null closure is not supported"); + nsIHTMLMappedAttributes* mapped = (nsIHTMLMappedAttributes*)aData; + NS_ASSERTION(mapped, "null item in enumeration fcn is not supported"); + // if there is an attribute and it has not been counted, the get its size + if(mapped){ + PRUint32 size=0; + mapped->SizeOf(pData->aHandler, size); + } + return PR_TRUE; +} + + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLStyleSheetImpl's size): +* 1) Not really delegated, but counted seperately: +* - mLinkRule +* - mVisitedRule +* - mActiveRule +* - mDocumentColorRule +* - mTableBackgroundRule +* - mTableTHRule +* - mMappedAttrTable +* 2) Delegates (really) to the MappedAttributes in the mMappedAttrTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // now gather up the sizes of the data members + // - mLinkRule : sizeof object + // - mVisitedRule : sizeof object + // - mActiveRule : sizeof object + // - mDocumentColorRule : sizeof object + // - mTableBackgroundRule : sizeof object + // - mTableTHRule : sizeof object + // - mMappedAttrTable + + if(mLinkRule && uniqueItems->AddItem((void*)mLinkRule)){ + localSize = sizeof(*mLinkRule); + tag = getter_AddRefs(NS_NewAtom("LinkRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mVisitedRule && uniqueItems->AddItem((void*)mVisitedRule)){ + localSize = sizeof(*mVisitedRule); + tag = getter_AddRefs(NS_NewAtom("VisitedRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mActiveRule && uniqueItems->AddItem((void*)mActiveRule)){ + localSize = sizeof(*mActiveRule); + tag = getter_AddRefs(NS_NewAtom("ActiveRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mDocumentColorRule && uniqueItems->AddItem((void*)mDocumentColorRule)){ + localSize = sizeof(*mDocumentColorRule); + tag = getter_AddRefs(NS_NewAtom("DocumentColorRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableBackgroundRule && uniqueItems->AddItem((void*)mTableBackgroundRule)){ + localSize = sizeof(*mTableBackgroundRule); + tag = getter_AddRefs(NS_NewAtom("TableBackgroundRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableTHRule && uniqueItems->AddItem((void*)mTableTHRule)){ + localSize = sizeof(*mTableTHRule); + tag = getter_AddRefs(NS_NewAtom("TableTHRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + + // for the AttrTable it is kindof sleezy: + // We want the hash table overhead as well as the entries it contains + // + // we get the overall size of the hashtable, and if there are entries, + // we calculate a rough overhead estimate as: + // number of entries X sizeof each hash-entry + // + the size of a hash table (see plhash.h and nsHashTable.h) + // then we add up the size of each unique attribute + localSize = sizeof(mMappedAttrTable); + if(mMappedAttrTable.Count() >0){ + localSize += sizeof(PLHashTable); + localSize += mMappedAttrTable.Count() * sizeof(PLHashEntry); + } + tag = getter_AddRefs(NS_NewAtom("MappedAttrTable")); + aSizeOfHandler->AddSize(tag,localSize); + + // now get each unique attribute + MappedAttributeSizeEnumData sizeEnumData(aSizeOfHandler, uniqueItems); + mMappedAttrTable.Enumerate(MappedSizeAttributes, &sizeEnumData); + + // that's it +} + + // XXX For convenience and backwards compatibility NS_HTML nsresult NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURI* aURL, diff --git a/mozilla/layout/html/style/src/nsICSSDeclaration.h b/mozilla/layout/html/style/src/nsICSSDeclaration.h index 40b92e276aa..f5386155198 100644 --- a/mozilla/layout/html/style/src/nsICSSDeclaration.h +++ b/mozilla/layout/html/style/src/nsICSSDeclaration.h @@ -31,6 +31,7 @@ #include "nsCSSValue.h" #include "nsCSSProps.h" +class nsISizeOfHandler; struct nsCSSStruct { virtual const nsID& GetID(void) = 0; @@ -412,6 +413,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const = 0; virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; }; extern NS_HTML nsresult diff --git a/mozilla/layout/html/style/src/nsICSSStyleRule.h b/mozilla/layout/html/style/src/nsICSSStyleRule.h index d3dac04f1cf..b77ec5ed8b6 100644 --- a/mozilla/layout/html/style/src/nsICSSStyleRule.h +++ b/mozilla/layout/html/style/src/nsICSSStyleRule.h @@ -27,6 +27,8 @@ #include "nsICSSRule.h" #include "nsString.h" +class nsISizeOfHandler; + class nsIAtom; class nsIArena; class nsICSSDeclaration; @@ -58,6 +60,8 @@ public: ~nsAttrSelector(void); PRBool Equals(const nsAttrSelector* aOther) const; + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + PRInt32 mNameSpace; nsIAtom* mAttr; PRUint8 mFunction; @@ -88,7 +92,9 @@ public: void SetOperator(PRUnichar aOperator); PRInt32 CalcWeight(void) const; - + + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + public: PRInt32 mNameSpace; nsIAtom* mTag; diff --git a/mozilla/layout/html/style/src/nsIHTMLAttributes.h b/mozilla/layout/html/style/src/nsIHTMLAttributes.h index 015ceb6db25..e270e77b7ea 100644 --- a/mozilla/layout/html/style/src/nsIHTMLAttributes.h +++ b/mozilla/layout/html/style/src/nsIHTMLAttributes.h @@ -30,7 +30,6 @@ class nsIAtom; class nsISupportsArray; class nsIHTMLStyleSheet; - // IID for the nsIHTMLAttributes interface {a18f85f0-c058-11d1-8031-006008159b5a} #define NS_IHTML_ATTRIBUTES_IID \ {0xa18f85f0, 0xc058, 0x11d1, \ @@ -94,7 +93,7 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; - NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const = 0; + virtual void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) = 0; }; class nsIHTMLMappedAttributes : public nsISupports { @@ -112,6 +111,8 @@ public: NS_IMETHOD SetUniqued(PRBool aUniqued) = 0; NS_IMETHOD GetUniqued(PRBool& aUniqued) = 0; NS_IMETHOD DropStyleSheetReference(void) = 0; + + virtual void SizeOf(nsISizeOfHandler* aSizer, PRUint32 &aResult) = 0; }; extern NS_HTML nsresult diff --git a/mozilla/layout/style/nsCSSDeclaration.cpp b/mozilla/layout/style/nsCSSDeclaration.cpp index 9025de4e49d..fa1f365a977 100644 --- a/mozilla/layout/style/nsCSSDeclaration.cpp +++ b/mozilla/layout/style/nsCSSDeclaration.cpp @@ -28,7 +28,11 @@ #include "nsStyleConsts.h" -//#define DEBUG_REFS +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); @@ -950,6 +954,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const; void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); NS_IMETHOD Count(PRUint32* aCount); NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsString& aReturn); @@ -993,7 +999,7 @@ CSSDeclarationImpl::CSSDeclarationImpl(void) NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; - fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (ctor): %ld\n", (long)gInstanceCount); #endif } @@ -1017,6 +1023,11 @@ CSSDeclarationImpl::CSSDeclarationImpl(const CSSDeclarationImpl& aCopy) DECL_IF_COPY(UserInterface); DECL_IF_COPY(Aural); +#ifdef DEBUG_REFS + ++gInstanceCount; + fprintf(stdout, "CSSDeclaration Instances (cp-ctor): %ld\n", (long)gInstanceCount); +#endif + if (aCopy.mImportant) { mImportant = new CSSDeclarationImpl(*(aCopy.mImportant)); NS_IF_ADDREF(mImportant); @@ -1060,7 +1071,7 @@ CSSDeclarationImpl::~CSSDeclarationImpl(void) #ifdef DEBUG_REFS --gInstanceCount; - fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (dtor): %ld\n", (long)gInstanceCount); #endif } @@ -3179,7 +3190,23 @@ PRBool CSSDeclarationImpl::AppendValueToString(nsCSSProperty aProperty, const ns aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { - aResult.Append(aValue.GetIntValue(), 10); + switch (aProperty) { + case eCSSProperty_color: + case eCSSProperty_background_color: { + // we can lookup the property in the ColorTable and then + // get a string mapping the name + nsCString str; + if (nsCSSProps::GetColorName(aValue.GetIntValue(), str)){ + aResult.Append(str); + } else { + aResult.Append(aValue.GetIntValue(), 10); + } + } + break; + + default: + aResult.Append(aValue.GetIntValue(), 10); + } } else if (eCSSUnit_Enumerated == unit) { if (eCSSProperty_text_decoration == aProperty) { @@ -3737,6 +3764,80 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSDeclarationImpl's size): +* 1) sizeof(*this) + the sizeof each non-null attribute +* +* Contained / Aggregated data (not reported as CSSDeclarationImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSDeclarationImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSDeclarationImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now add in all of the contained objects, checking for duplicates on all of them + if(mFont && uniqueItems->AddItem(mFont)){ + aSize += sizeof(*mFont); + } + if(mColor && uniqueItems->AddItem(mColor)){ + aSize += sizeof(*mColor); + } + if(mText && uniqueItems->AddItem(mText)){ + aSize += sizeof(*mText); + } + if(mMargin && uniqueItems->AddItem(mMargin)){ + aSize += sizeof(*mMargin); + } + if(mPosition && uniqueItems->AddItem(mPosition)){ + aSize += sizeof(*mPosition); + } + if(mList && uniqueItems->AddItem(mList)){ + aSize += sizeof(*mList); + } + if(mDisplay && uniqueItems->AddItem(mDisplay)){ + aSize += sizeof(*mDisplay); + } + if(mTable && uniqueItems->AddItem(mTable)){ + aSize += sizeof(*mTable); + } + if(mBreaks && uniqueItems->AddItem(mBreaks)){ + aSize += sizeof(*mBreaks); + } + if(mPage && uniqueItems->AddItem(mPage)){ + aSize += sizeof(*mPage); + } + if(mContent && uniqueItems->AddItem(mContent)){ + aSize += sizeof(*mContent); + } + if(mUserInterface && uniqueItems->AddItem(mUserInterface)){ + aSize += sizeof(*mUserInterface); + } + if(mAural && uniqueItems->AddItem(mAural)){ + aSize += sizeof(*mAural); + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSDeclarationImpl::Count(PRUint32* aCount) { diff --git a/mozilla/layout/style/nsCSSProps.cpp b/mozilla/layout/style/nsCSSProps.cpp index 709f2b9c749..4dc106dcd20 100644 --- a/mozilla/layout/style/nsCSSProps.cpp +++ b/mozilla/layout/style/nsCSSProps.cpp @@ -670,8 +670,7 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = { -1,-1 }; -static const nsCString& -SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +static PRInt32 SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[]) { PRInt32 i = 1; for (;;) { @@ -679,14 +678,23 @@ SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) break; } if (aValue == aTable[i]) { - return nsCSSKeywords::GetStringValue(nsCSSKeyword(aTable[i-1])); + return PRInt32(aTable[i-1]); } i += 2; } - return *kNullStr; + return -1; } - +static const nsCString& +SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) +{ + PRInt32 i = SearchKeywordTableInt(aValue, aTable); + if (i < 0) { + return *kNullStr; + } else { + return nsCSSKeywords::GetStringValue(nsCSSKeyword(i)); + } +} const nsCString& nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, PRInt32 aValue) @@ -1042,6 +1050,23 @@ static const PRInt32 kBackgroundYPositionKTable[] = { return *kNullStr; } +PRBool nsCSSProps::GetColorName(PRInt32 aPropValue, nsCString &aStr) +{ + PRBool rv = PR_FALSE; + PRInt32 keyword = -1; + + // first get the keyword corresponding to the property Value from the color table + keyword = SearchKeywordTableInt(aPropValue, kColorKTable); + + // next get the name as a string from the keywords table + if (keyword >= 0) { + nsCSSKeywords::AddRefTable(); + aStr = nsCSSKeywords::GetStringValue((nsCSSKeyword)keyword); + nsCSSKeywords::ReleaseTable(); + rv = PR_TRUE; + } + return rv; +} // define array of all CSS property hints #define CSS_PROP(_prop, _hint) NS_STYLE_HINT_##_hint, diff --git a/mozilla/layout/style/nsCSSProps.h b/mozilla/layout/style/nsCSSProps.h index 8180f359371..81778dd3ff8 100644 --- a/mozilla/layout/style/nsCSSProps.h +++ b/mozilla/layout/style/nsCSSProps.h @@ -60,6 +60,10 @@ public: // value. Return back nullstr if no value is found static const nsCString& LookupPropertyValue(nsCSSProperty aProperty, PRInt32 aValue); + // Get a color name for a predefined color value like buttonhighlight or activeborder + // Sets the aStr param to the name of the propertyID + static PRBool GetColorName(PRInt32 aPropID, nsCString &aStr); + static const PRInt32 kHintTable[]; // Keyword/Enum value tables diff --git a/mozilla/layout/style/nsCSSRules.cpp b/mozilla/layout/style/nsCSSRules.cpp index e4e9cba802f..32e544aa3e7 100644 --- a/mozilla/layout/style/nsCSSRules.cpp +++ b/mozilla/layout/style/nsCSSRules.cpp @@ -33,6 +33,9 @@ #include "nsLayoutAtoms.h" #include "nsICSSStyleSheet.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -82,6 +85,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -167,6 +172,43 @@ CSSCharsetRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSCharSetRuleImpl's size): +* 1) sizeof(*this) + the size of the mEncoding string +* +* Contained / Aggregated data (not reported as CSSCharsetRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSCharsetRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSCharsetRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add the string for encoding value + mEncoding.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mEncoding); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); +} + NS_IMETHODIMP CSSCharsetRuleImpl::GetType(PRInt32& aType) const { @@ -229,6 +271,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -317,6 +361,49 @@ CSSImportRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the size of the mMedia string +* +* Contained / Aggregated data (not reported as CSSImportRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add the strings for the URLSpec and the Media + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + mMedia.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mMedia); // counted in sizeof(*this) and nsString->SizeOf() + aSizeOfHandler->AddSize(tag,aSize); + +} + NS_IMETHODIMP CSSImportRuleImpl::GetType(PRInt32& aType) const { @@ -401,6 +488,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -563,6 +652,67 @@ CSSMediaRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSMediaRuleImpl's size): +* 1) sizeof(*this) + the size of each unique atom in the mMedia collection +* +* Contained / Aggregated data (not reported as CSSMediaRuleImpl's size): +* 1) Delegate to the rules in the mRules collection to report theri own size +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSMediaRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSMediaRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + if (mMedia) { + // get the sizes of the media atoms (if unique) + PRUint32 index = 0; + PRUint32 count; + mMedia->Count(&count); + while (index < count) { + nsIAtom* medium = (nsIAtom*)mMedia->ElementAt(index++); + if(medium && uniqueItems->AddItem(medium)){ + medium->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + NS_IF_RELEASE(medium); + } + } + // we are done with the size we report for ourself + aSizeOfHandler->AddSize(tag,aSize); + + if (mRules) { + // delegate to the rules themselves (do not sum into our size) + PRUint32 index = 0; + PRUint32 count; + mRules->Count(&count); + while (index < count) { + nsICSSRule* rule = (nsICSSRule*)mRules->ElementAt(index++); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } +} + NS_IMETHODIMP CSSMediaRuleImpl::GetType(PRInt32& aType) const { @@ -693,6 +843,8 @@ public: // nsIStyleRule methods NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsICSSRule methods NS_IMETHOD GetType(PRInt32& aType) const; NS_IMETHOD Clone(nsICSSRule*& aClone) const; @@ -788,6 +940,50 @@ CSSNameSpaceRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSNamespaceRuleImpl's size): +* 1) sizeof(*this) + the size of the mURLSpec string + +* the sizeof the mPrefix atom (if it ieists) +* +* Contained / Aggregated data (not reported as CSSNamespaceRuleImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSNameSpaceRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSNameSpaceRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // get the member data as part of this dump + mURLSpec.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mURLSpec); // counted in sizeof(*this) and nsString->SizeOf() + + if(mPrefix && uniqueItems->AddItem(mPrefix)){ + mPrefix->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSNameSpaceRuleImpl::GetType(PRInt32& aType) const { diff --git a/mozilla/layout/style/nsCSSStruct.cpp b/mozilla/layout/style/nsCSSStruct.cpp index 9025de4e49d..fa1f365a977 100644 --- a/mozilla/layout/style/nsCSSStruct.cpp +++ b/mozilla/layout/style/nsCSSStruct.cpp @@ -28,7 +28,11 @@ #include "nsStyleConsts.h" -//#define DEBUG_REFS +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS static NS_DEFINE_IID(kCSSFontSID, NS_CSS_FONT_SID); @@ -950,6 +954,8 @@ public: NS_IMETHOD Clone(nsICSSDeclaration*& aClone) const; void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); NS_IMETHOD Count(PRUint32* aCount); NS_IMETHOD GetNthProperty(PRUint32 aIndex, nsString& aReturn); @@ -993,7 +999,7 @@ CSSDeclarationImpl::CSSDeclarationImpl(void) NS_INIT_REFCNT(); #ifdef DEBUG_REFS ++gInstanceCount; - fprintf(stdout, "%d + CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (ctor): %ld\n", (long)gInstanceCount); #endif } @@ -1017,6 +1023,11 @@ CSSDeclarationImpl::CSSDeclarationImpl(const CSSDeclarationImpl& aCopy) DECL_IF_COPY(UserInterface); DECL_IF_COPY(Aural); +#ifdef DEBUG_REFS + ++gInstanceCount; + fprintf(stdout, "CSSDeclaration Instances (cp-ctor): %ld\n", (long)gInstanceCount); +#endif + if (aCopy.mImportant) { mImportant = new CSSDeclarationImpl(*(aCopy.mImportant)); NS_IF_ADDREF(mImportant); @@ -1060,7 +1071,7 @@ CSSDeclarationImpl::~CSSDeclarationImpl(void) #ifdef DEBUG_REFS --gInstanceCount; - fprintf(stdout, "%d - CSSDeclaration\n", gInstanceCount); + fprintf(stdout, "CSSDeclaration Instances (dtor): %ld\n", (long)gInstanceCount); #endif } @@ -3179,7 +3190,23 @@ PRBool CSSDeclarationImpl::AppendValueToString(nsCSSProperty aProperty, const ns aResult.Append(buffer); } else if (eCSSUnit_Integer == unit) { - aResult.Append(aValue.GetIntValue(), 10); + switch (aProperty) { + case eCSSProperty_color: + case eCSSProperty_background_color: { + // we can lookup the property in the ColorTable and then + // get a string mapping the name + nsCString str; + if (nsCSSProps::GetColorName(aValue.GetIntValue(), str)){ + aResult.Append(str); + } else { + aResult.Append(aValue.GetIntValue(), 10); + } + } + break; + + default: + aResult.Append(aValue.GetIntValue(), 10); + } } else if (eCSSUnit_Enumerated == unit) { if (eCSSProperty_text_decoration == aProperty) { @@ -3737,6 +3764,80 @@ void CSSDeclarationImpl::List(FILE* out, PRInt32 aIndent) const } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSDeclarationImpl's size): +* 1) sizeof(*this) + the sizeof each non-null attribute +* +* Contained / Aggregated data (not reported as CSSDeclarationImpl's size): +* none +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSDeclarationImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSDeclarationImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now add in all of the contained objects, checking for duplicates on all of them + if(mFont && uniqueItems->AddItem(mFont)){ + aSize += sizeof(*mFont); + } + if(mColor && uniqueItems->AddItem(mColor)){ + aSize += sizeof(*mColor); + } + if(mText && uniqueItems->AddItem(mText)){ + aSize += sizeof(*mText); + } + if(mMargin && uniqueItems->AddItem(mMargin)){ + aSize += sizeof(*mMargin); + } + if(mPosition && uniqueItems->AddItem(mPosition)){ + aSize += sizeof(*mPosition); + } + if(mList && uniqueItems->AddItem(mList)){ + aSize += sizeof(*mList); + } + if(mDisplay && uniqueItems->AddItem(mDisplay)){ + aSize += sizeof(*mDisplay); + } + if(mTable && uniqueItems->AddItem(mTable)){ + aSize += sizeof(*mTable); + } + if(mBreaks && uniqueItems->AddItem(mBreaks)){ + aSize += sizeof(*mBreaks); + } + if(mPage && uniqueItems->AddItem(mPage)){ + aSize += sizeof(*mPage); + } + if(mContent && uniqueItems->AddItem(mContent)){ + aSize += sizeof(*mContent); + } + if(mUserInterface && uniqueItems->AddItem(mUserInterface)){ + aSize += sizeof(*mUserInterface); + } + if(mAural && uniqueItems->AddItem(mAural)){ + aSize += sizeof(*mAural); + } + aSizeOfHandler->AddSize(tag, aSize); +} + NS_IMETHODIMP CSSDeclarationImpl::Count(PRUint32* aCount) { diff --git a/mozilla/layout/style/nsCSSStyleRule.cpp b/mozilla/layout/style/nsCSSStyleRule.cpp index a11c6c59461..e6557253425 100644 --- a/mozilla/layout/style/nsCSSStyleRule.cpp +++ b/mozilla/layout/style/nsCSSStyleRule.cpp @@ -52,6 +52,11 @@ #include "nsINameSpaceManager.h" #include "nsILookAndFeel.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + +// #define DEBUG_REFS + static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); static NS_DEFINE_IID(kICSSDeclarationIID, NS_ICSS_DECLARATION_IID); @@ -138,6 +143,10 @@ PRBool nsAtomList::Equals(const nsAtomList* aOther) const MOZ_DECL_CTOR_COUNTER(nsAttrSelector); +#ifdef DEBUG_REFS +PRUint32 gAttrSelectorCount=0; +#endif + nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) : mNameSpace(aNameSpace), mAttr(nsnull), @@ -147,6 +156,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -160,6 +175,12 @@ nsAttrSelector::nsAttrSelector(PRInt32 aNameSpace, const nsString& aAttr, PRUint mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (ctor): %ld\n", (long)gAttrSelectorCount); +#endif + mAttr = NS_NewAtom(aAttr); } @@ -172,6 +193,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) mNext(nsnull) { MOZ_COUNT_CTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount++; + printf( "nsAttrSelector Instances (cp-ctor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_ADDREF(mAttr); NS_IF_COPY(mNext, aCopy.mNext, nsAttrSelector); } @@ -179,6 +206,12 @@ nsAttrSelector::nsAttrSelector(const nsAttrSelector& aCopy) nsAttrSelector::~nsAttrSelector(void) { MOZ_COUNT_DTOR(nsAttrSelector); + +#ifdef DEBUG_REFS + gAttrSelectorCount--; + printf( "nsAttrSelector Instances (dtor): %ld\n", (long)gAttrSelectorCount); +#endif + NS_IF_RELEASE(mAttr); NS_IF_DELETE(mNext); } @@ -203,8 +236,56 @@ PRBool nsAttrSelector::Equals(const nsAttrSelector* aOther) const return PR_FALSE; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsAttrSelector's size): +* 1) sizeof(*this) + the size of mAttr atom (if it exists and is unique) +* +* Contained / Aggregated data (not reported as nsAttrSelector's size): +* none +* +* Children / siblings / parents: +* 1) Recurses to the mMext instance which is reported as a seperate instance +* +******************************************************************************/ +void nsAttrSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsAttrSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // add in the mAttr atom + if (mAttr && uniqueItems->AddItem(mAttr)){ + mAttr->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // recurse to the next one... + if(mNext){ + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + MOZ_DECL_CTOR_COUNTER(nsCSSSelector); +#ifdef DEBUG_REFS +PRUint32 gSelectorCount=0; +#endif + nsCSSSelector::nsCSSSelector(void) : mNameSpace(kNameSpaceID_Unknown), mTag(nsnull), mID(nsnull), @@ -215,6 +296,11 @@ nsCSSSelector::nsCSSSelector(void) mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) @@ -232,12 +318,22 @@ nsCSSSelector::nsCSSSelector(const nsCSSSelector& aCopy) NS_IF_COPY(mClassList, aCopy.mClassList, nsAtomList); NS_IF_COPY(mPseudoClassList, aCopy.mPseudoClassList, nsAtomList); NS_IF_COPY(mAttrList, aCopy.mAttrList, nsAttrSelector); + +#ifdef DEBUG_REFS + gSelectorCount++; + printf( "nsCSSSelector Instances (cp-ctor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector::~nsCSSSelector(void) { MOZ_COUNT_DTOR(nsCSSSelector); Reset(); + +#ifdef DEBUG_REFS + gSelectorCount--; + printf( "nsCSSSelector Instances (dtor): %ld\n", (long)gSelectorCount); +#endif } nsCSSSelector& nsCSSSelector::operator=(const nsCSSSelector& aCopy) @@ -429,6 +525,90 @@ PRInt32 nsCSSSelector::CalcWeight(void) const return weight; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as nsCSSSelector's size): +* 1) sizeof(*this) + the size of the mTag and mID atoms (if unique) +* + the size of the mClassList and mPseudoClassList unique items +* +* Contained / Aggregated data (not reported as nsCSSSelector's size): +* 1) AttributeList is called out to seperately if it exists +* +* Children / siblings / parents: +* 1) Recurses to mNext which is counted as it's own instance +* +******************************************************************************/ +void nsCSSSelector::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("nsCSSSelector")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + + // now get the member-atoms and add them in + if(mTag && uniqueItems->AddItem(mTag)){ + localSize = 0; + mTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + if(mID && uniqueItems->AddItem(mID)){ + localSize = 0; + mID->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + // a couple of simple atom lists + if(mClassList && uniqueItems->AddItem(mClassList)){ + aSize += sizeof(*mClassList); + nsAtomList *pNext = nsnull; + pNext = mClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + if(mPseudoClassList && uniqueItems->AddItem(mPseudoClassList)){ + nsAtomList *pNext = nsnull; + pNext = mPseudoClassList; + while(pNext){ + if(pNext->mAtom && uniqueItems->AddItem(pNext->mAtom)){ + localSize = 0; + pNext->mAtom->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + pNext = pNext->mNext; + } + } + // done with undelegated sizes + aSizeOfHandler->AddSize(tag, aSize); + + // the AttributeList gets its own delegation-call + if(mAttrList){ + localSize = 0; + mAttrList->SizeOf(aSizeOfHandler, localSize); + } + // finally chain to the next... + if(mNext){ + localSize = 0; + mNext->SizeOf(aSizeOfHandler, localSize); + } +} + // -- CSSImportantRule ------------------------------- static nscoord CalcLength(const nsCSSValue& aValue, const nsFont& aFont, @@ -467,6 +647,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: virtual ~CSSImportantRule(void); @@ -555,6 +737,48 @@ CSSImportantRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSImportantRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSImportantRule's size): +* 1) mDeclaration is sized seperately +* 2) mSheet is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSImportantRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSImportantRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSImportantRule); + aSizeOfHandler->AddSize(tag,aSize); + + // now dump the mDeclaration and mSheet + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mSheet){ + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // -- nsDOMStyleRuleDeclaration ------------------------------- class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration @@ -729,6 +953,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + // nsIDOMCSSRule interface NS_IMETHOD GetType(PRUint16* aType); NS_IMETHOD GetCssText(nsString& aCssText); @@ -762,6 +988,10 @@ protected: void* mScriptObject; }; +#ifdef DEBUG_REFS +PRUint32 gStyleRuleCount=0; +#endif + CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) : nsCSSRule(), mSelector(aSelector), mSelectorText(), mDeclaration(nsnull), @@ -769,6 +999,10 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const nsCSSSelector& aSelector) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (ctor): %ld\n", (long)gStyleRuleCount); +#endif } CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) @@ -781,6 +1015,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) mDOMDeclaration(nsnull), mScriptObject(nsnull) { +#ifdef DEBUG_REFS + gStyleRuleCount++; + printf( "CSSStyleRuleImpl Instances (cp-ctor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* copySel = aCopy.mSelector.mNext; nsCSSSelector* ourSel = &mSelector; @@ -799,6 +1038,11 @@ CSSStyleRuleImpl::CSSStyleRuleImpl(const CSSStyleRuleImpl& aCopy) CSSStyleRuleImpl::~CSSStyleRuleImpl(void) { +#ifdef DEBUG_REFS + gStyleRuleCount--; + printf( "CSSStyleRuleImpl Instances (dtor): %ld\n", (long)gStyleRuleCount); +#endif + nsCSSSelector* next = mSelector.mNext; while (nsnull != next) { @@ -2856,6 +3100,64 @@ CSSStyleRuleImpl::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleRuleImpl's size): +* 1) sizeof(*this) + size of the mSelectorText +* + sizeof the DOMDeclaration if it exists and is unique +* +* Contained / Aggregated data (not reported as CSSStyleRuleImpl's size): +* 1) mDeclaration if it exists +* 2) mImportantRule if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleRuleImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleRuleImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // remove the sizeof the mSelector's class since we count it seperately below + aSize -= sizeof(mSelector); + + // add in the length of the selectorText + mSelectorText.SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + aSize -= sizeof(mSelectorText); // counted in sizeof(*this) and nsString.SizeOf() + + // and add the size of the DOMDeclaration + // XXX - investigate the size and quantity of these + if(mDOMDeclaration && uniqueItems->AddItem(mDOMDeclaration)){ + aSize += sizeof(DOMCSSDeclarationImpl); + } + aSizeOfHandler->AddSize(tag,aSize); + + // now delegate to the Selector, Declaration, and ImportantRule + mSelector.SizeOf(aSizeOfHandler, localSize); + + if(mDeclaration){ + mDeclaration->SizeOf(aSizeOfHandler, localSize); + } + if(mImportantRule){ + mImportantRule->SizeOf(aSizeOfHandler, localSize); + } +} + NS_IMETHODIMP CSSStyleRuleImpl::GetType(PRUint16* aType) { @@ -2970,6 +3272,5 @@ NS_HTML nsresult if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } - return it->QueryInterface(kICSSStyleRuleIID, (void **) aInstancePtrResult); } diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index 5c1d752a598..4ebea9b15b1 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -62,7 +62,12 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsITextContent.h" #include "prlog.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + //#define DEBUG_RULES +//#define EVENT_DEBUG static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -407,6 +412,8 @@ public: nsIAtom* aMedium, nsIContent* aContent); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + protected: RuleCascadeData* GetRuleCascade(nsIAtom* aMedium); @@ -433,6 +440,8 @@ public: virtual void RebuildNameSpaces(void); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsVoidArray mSheets; nsIURI* mURL; @@ -521,6 +530,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + // nsIDOMStyleSheet interface NS_IMETHOD GetType(nsString& aType); NS_IMETHOD GetDisabled(PRBool* aDisabled); @@ -1048,6 +1059,80 @@ CSSStyleSheetInner::RebuildNameSpaces(void) } } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetInner's size): +* 1) sizeof(*this) + sizeof mSheets array (not contents though) +* + size of the mOrderedRules array (not the contents though) +* +* Contained / Aggregated data (not reported as CSSStyleSheetInner's size): +* 1) mSheets: each style sheet is sized seperately +* 2) mOrderedRules: each fule is sized seperately +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSStyleSheetInner::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + PRBool rulesCounted=PR_FALSE; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheetInner")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetInner); + + // add in the size of the mSheets array itself + mSheets.SizeOf(aSizeOfHandler,&localSize); + aSize += localSize; + + // and the mOrderedRules array (if there is one) + if(mOrderedRules && uniqueItems->AddItem(mOrderedRules)){ + rulesCounted=PR_TRUE; + // no SizeOf method so we just get the basic object size + aSize += sizeof(*mOrderedRules); + } + aSizeOfHandler->AddSize(tag,aSize); + + + // delegate to the contained containers + // mSheets : nsVoidArray + { + PRUint32 sheetCount, sheetCur; + sheetCount = mSheets.Count(); + for(sheetCur=0; sheetCur < sheetCount; sheetCur++){ + nsICSSStyleSheet* sheet = (nsICSSStyleSheet*)mSheets.ElementAt(sheetCur); + if(sheet){ + sheet->SizeOf(aSizeOfHandler, localSize); + } + } + } + // mOrderedRules : nsISupportsArray* + if(mOrderedRules && rulesCounted){ + PRUint32 ruleCount, ruleCur; + mOrderedRules->Count(&ruleCount); + for(ruleCur=0; ruleCur < ruleCount; ruleCur++){ + nsICSSRule* rule = (nsICSSRule*)mOrderedRules->ElementAt(ruleCur); + if(rule){ + rule->SizeOf(aSizeOfHandler, localSize); + NS_IF_RELEASE(rule); + } + } + } +} + // ------------------------------- // CSS Style Sheet @@ -1837,6 +1922,59 @@ void CSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const ListRules(mInner->mOrderedRules, out, aIndent); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSStyleSheetImpl's size): +* 1) sizeof(*this) + sizeof the mImportsCollection + sizeof mCuleCollection) +* +* Contained / Aggregated data (not reported as CSSStyleSheetImpl's size): +* 1) mInner is delegated to be counted seperately +* +* Children / siblings / parents: +* 1) Recurse to mFirstChild +* +******************************************************************************/ +void CSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is already accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSStyleSheetImpl); + + // add up the contained objects we won't delegate to: + // NOTE that we just add the sizeof the objects + // since the style data they contain is accounted for elsewhere + // - mImportsCollection + // - mRuleCollection + aSize += sizeof(mImportsCollection); + aSize += sizeof(mRuleCollection); + aSizeOfHandler->AddSize(tag,aSize); + + // size the inner + if(mInner){ + mInner->SizeOf(aSizeOfHandler, localSize); + } + + // now travers the children (recursively, I'm sorry to say) + if(mFirstChild){ + PRUint32 childSize=0; + mFirstChild->SizeOf(aSizeOfHandler, childSize); + } +} + static PRBool EnumClearRuleCascades(void* aProcessor, void* aData) { @@ -2308,6 +2446,29 @@ static PRBool IsLinkPseudo(nsIAtom* aAtom) (nsCSSAtoms::visitedPseudo == aAtom)); } +static PRBool IsEventSensitive(nsIAtom *aPseudo, nsIAtom *aContentTag, PRBool aSelectorIsGlobal) +{ + // if the selector is global, meaning it is not tied to a tag, then + // we restrict the application of the event pseudo to the following tags + if (aSelectorIsGlobal) { + return PRBool ((nsHTMLAtoms::a == aContentTag) || + (nsHTMLAtoms::button == aContentTag) || + (nsHTMLAtoms::img == aContentTag) || + (nsHTMLAtoms::input == aContentTag) || + (nsHTMLAtoms::li == aContentTag) || + (nsHTMLAtoms::label == aContentTag) || + (nsHTMLAtoms::select == aContentTag) || + (nsHTMLAtoms::textarea == aContentTag) || + (nsHTMLAtoms::textPseudo == aContentTag) || + // We require a Layout Atom too + (nsLayoutAtoms::textTagName == aContentTag) + ); + } else { + // selector is not global, so apply the event pseudo to everything except HTML and BODY + return PRBool ((nsHTMLAtoms::html != aContentTag) && + (nsHTMLAtoms::body != aContentTag)); + } +} static PRBool SelectorMatches(nsIPresContext* aPresContext, nsCSSSelector* aSelector, nsIContent* aContent, PRBool aTestState) @@ -2488,12 +2649,49 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, result = PR_FALSE; } else if (IsEventPseudo(pseudoClass->mAtom)) { - if (aTestState) { + // check if the element is event-sensitive + if (!contentTag) { + if (aContent) { + aContent->GetTag(contentTag); + } + } + +#ifdef EVENT_DEBUG + nsAutoString strTag; + // easier to watch the string value than the ATOM + if (contentTag) { + contentTag->ToString(strTag); + } +#endif + // Quirk Mode: check to see if the element is event-sensitive + // - see if the selector applies to event pseudo classes + // NOTE: we distinguish between global and subjected selectors so + // pass that information on to the determining routine + nsCompatibility quirkMode = eCompatibility_Standard; + aPresContext->GetCompatibilityMode(&quirkMode); + PRBool isSelectorGlobal = aSelector->mTag==nsnull ? PR_TRUE : PR_FALSE; + if ((eCompatibility_NavQuirks == quirkMode) && + (!IsEventSensitive(pseudoClass->mAtom, contentTag, isSelectorGlobal))){ + result = PR_FALSE; + } else if (aTestState) { if (! eventStateManager) { aPresContext->GetEventStateManager(&eventStateManager); - if (eventStateManager) { - eventStateManager->GetContentState(aContent, eventState); + } + if (eventStateManager) { + eventStateManager->GetContentState(aContent, eventState); + +#ifdef EVENT_DEBUG + nsAutoString strPseudo, strTag; + pseudoClass->mAtom->ToString(strPseudo); + if (!contentTag) { + if (aContent) aContent->GetTag(contentTag); } + if (contentTag) { + contentTag->ToString(strTag); + } + printf("Tag: %s PseudoClass: %s EventState: %d\n", + strTag.ToNewCString(), strPseudo.ToNewCString(), (int)eventState); +#endif } if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE)); @@ -2507,14 +2705,14 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext, else if (nsCSSAtoms::dragOverPseudo == pseudoClass->mAtom) { result = PRBool(0 != (eventState & NS_EVENT_STATE_DRAGOVER)); } - } + } } else if (IsLinkPseudo(pseudoClass->mAtom)) { // XXX xml link too - if(!tagset) { - tagset=PR_TRUE; - aContent->GetTag(contentTag); - } + if(!tagset) { + tagset=PR_TRUE; + aContent->GetTag(contentTag); + } if (nsHTMLAtoms::a == contentTag) { // make sure this anchor has a link even if we are not testing state // if there is no link, then this anchor is not really a linkpseudo. @@ -2888,6 +3086,159 @@ CSSRuleProcessor::HasStateDependentStyle(nsIPresContext* aPresContext, return ((isStateful) ? NS_OK : NS_COMFALSE); } + +struct CascadeSizeEnumData { + + CascadeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem, + nsIAtom *aTag) + { + handler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + tag = aTag; + } + // weak references all 'round + + nsISizeOfHandler *handler; + nsUniqueStyleItems *uniqueItems; + nsIAtom *tag; +}; + +static +PRBool StateSelectorsSizeEnumFunc( void *aSelector, void *aData ) +{ + nsCSSSelector* selector = (nsCSSSelector*)aSelector; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(selector && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)selector)){ + return PR_TRUE; + } + + // pass the call to the selector + PRUint32 localSize = 0; + selector->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool WeightedRulesSizeEnumFunc( nsISupports *aRule, void *aData ) +{ + nsICSSStyleRule* rule = (nsICSSStyleRule*)aRule; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(rule && pData, "null arguments not supported"); + + if(! pData->uniqueItems->AddItem((void*)rule)){ + return PR_TRUE; + } + + PRUint32 localSize=0; + + // pass the call to the rule + rule->SizeOf(pData->handler, localSize); + + return PR_TRUE; +} + +static +PRBool CascadeSizeEnumFunc(nsHashKey* aKey, void *aCascade, void *aData) +{ + RuleCascadeData* cascade = (RuleCascadeData *) aCascade; + CascadeSizeEnumData *pData = (CascadeSizeEnumData *)aData; + NS_ASSERTION(cascade && pData, "null arguments not supported"); + + // see if the cascade has already been counted + if(!(pData->uniqueItems->AddItem(cascade))){ + return PR_TRUE; + } + // record the size of the cascade data itself + PRUint32 localSize = sizeof(RuleCascadeData); + pData->handler->AddSize(pData->tag, localSize); + + // next add up the selectors and the weighted rules for the cascade + nsCOMPtr stateSelectorSizeTag; + stateSelectorSizeTag = getter_AddRefs(NS_NewAtom("CascadeStateSelectors")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,stateSelectorSizeTag); + cascade->mStateSelectors.EnumerateForwards(StateSelectorsSizeEnumFunc, &stateData); + + if(cascade->mWeightedRules){ + nsCOMPtr weightedRulesSizeTag; + weightedRulesSizeTag = getter_AddRefs(NS_NewAtom("CascadeWeightedRules")); + CascadeSizeEnumData stateData(pData->handler,pData->uniqueItems,weightedRulesSizeTag); + cascade->mWeightedRules->EnumerateForwards(WeightedRulesSizeEnumFunc, &stateData); + } + return PR_TRUE; +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSRuleProcessor's size): +* 1) sizeof(*this) + mMediumCascadeTable hashtable overhead +* +* Contained / Aggregated data (not reported as CSSRuleProcessor's size): +* 1) Delegate to the StyleSheets in the mSheets collection +* 2) Delegate to the Rules in the CascadeTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSRuleProcessor::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSRuleProcessor")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(CSSRuleProcessor); + + // collect sizes for the data + // - mSheets + // - mMediumCascadeTable + + // sheets first + if(mSheets && uniqueItems->AddItem(mSheets)){ + PRUint32 sheetCount, curSheet, localSize; + mSheets->Count(&sheetCount); + for(curSheet=0; curSheet < sheetCount; curSheet++){ + nsICSSStyleSheet *pSheet = (nsICSSStyleSheet *)mSheets->ElementAt(curSheet); + if(pSheet && uniqueItems->AddItem((void*)pSheet)){ + pSheet->SizeOf(aSizeOfHandler, localSize); + // XXX aSize += localSize; + } + } + } + + // and for the medium cascade table we account for the hash table overhead, + // and then compute the sizeof each rule-cascade in the table + if(mMediumCascadeTable){ + PRUint32 count; + count = mMediumCascadeTable->Count(); + localSize = sizeof(PLHashTable); + if(count > 0){ + aSize += sizeof(PLHashEntry) * count; + // now go ghrough each RuleCascade in the table + nsCOMPtr tag = getter_AddRefs(NS_NewAtom("RuleCascade")); + CascadeSizeEnumData data(aSizeOfHandler, uniqueItems, tag); + mMediumCascadeTable->Enumerate(CascadeSizeEnumFunc, &data); + } + } + + // now add the size of the RuleProcessor + aSizeOfHandler->AddSize(tag,aSize); +} + static PRBool DeleteRuleCascade(nsHashKey* aKey, void* aValue, void* closure) { delete ((RuleCascadeData*)aValue); diff --git a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp index cfa778db981..c635932d139 100644 --- a/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLCSSStyleSheet.cpp @@ -38,6 +38,10 @@ #include "nsIMutableStyleContext.h" #include "nsIPresContext.h" #include "nsIDocument.h" +#include "nsCOMPtr.h" + +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" static NS_DEFINE_IID(kIHTMLCSSStyleSheetIID, NS_IHTML_CSS_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); @@ -61,6 +65,8 @@ public: nsIPresContext* aPresContext); NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLCSSStyleSheet* mSheet; }; @@ -188,6 +194,44 @@ CSSFirstLineRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as CSSFirstLineRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as CSSFirstLineRule's size): +* 1) Delegate to mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void CSSFirstLineRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("CSSFirstLine-LetterRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + // ----------------------------------------------------------- class CSSFirstLetterRule : public CSSFirstLineRule { @@ -321,6 +365,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLCSSStyleSheetImpl(const HTMLCSSStyleSheetImpl& aCopy); @@ -666,6 +712,56 @@ void HTMLCSSStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const fputs("\n", out); } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLCSSStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLCSSStyleSheetImpl's size): +* 1) We don't really delegate but count seperately the FirstLineRule and +* the FirstLetterRule if the exist and are unique instances +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLCSSStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLCSSStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLCSSStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // Now the associated rules (if they exist) + // - mFirstLineRule + // - mFirstLetterRule + if(mFirstLineRule && uniqueItems->AddItem((void*)mFirstLineRule)){ + localSize = sizeof(*mFirstLineRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLineRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mFirstLetterRule && uniqueItems->AddItem((void*)mFirstLetterRule)){ + localSize = sizeof(*mFirstLetterRule); + aSize += localSize; + tag = getter_AddRefs(NS_NewAtom("FirstLetterRule")); + aSizeOfHandler->AddSize(tag,localSize); + } +} // XXX For backwards compatibility and convenience NS_HTML nsresult diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index 506af22d0f5..3487fcc832d 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -54,6 +54,9 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsINameSpaceManager.h" #include "nsLayoutAtoms.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIHTMLStyleSheetIID, NS_IHTML_STYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleSheetIID, NS_ISTYLE_SHEET_IID); static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -77,6 +80,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + nscolor mColor; nsIHTMLStyleSheet* mSheet; }; @@ -88,6 +93,8 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nscolor mBackgroundColor; PRBool mForegroundSet; PRBool mBackgroundSet; @@ -158,6 +165,44 @@ HTMLColorRule::List(FILE* out, PRInt32 aIndent) const return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLColorRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as HTMLColorRule's size): +* 1) delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize=0; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + HTMLDocumentColorRule::HTMLDocumentColorRule(nsIHTMLStyleSheet* aSheet) : HTMLColorRule(aSheet) { @@ -186,6 +231,44 @@ HTMLDocumentColorRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresCon return NS_OK; } +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLDocumentColorRule's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLDocumentColorRule's size): +* 1) Delegate to the mSheet +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLDocumentColorRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLDocumentColorRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + class GenericTableRule: public nsIStyleRule { public: GenericTableRule(nsIHTMLStyleSheet* aSheet); @@ -207,6 +290,8 @@ public: NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + nsIHTMLStyleSheet* mSheet; // not ref-counted, cleared by content }; @@ -269,6 +354,46 @@ GenericTableRule::List(FILE* out, PRInt32 aIndent) const { return NS_OK; } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as GenericTableRule's size): +* 1) sizeof(*this) + +* +* Contained / Aggregated data (not reported as GenericTableRule's size): +* 1) Delegate to the mSheet if it exists +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void GenericTableRule::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("GenericTableRule")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + aSizeOfHandler->AddSize(tag,aSize); + + if(mSheet){ + PRUint32 localSize; + mSheet->SizeOf(aSizeOfHandler, localSize); + } +} + + // ----------------------------------------------------------- // this rule only applies in NavQuirks mode // ----------------------------------------------------------- @@ -307,10 +432,13 @@ TableBackgroundRule::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresConte styleColor->mBackgroundFlags &= ~NS_STYLE_BG_COLOR_TRANSPARENT; } +// NOTE: Nav does not inherit the background image: this was over-zealous and mistaken +#if 0 if (!(parentStyleColor->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE)) { styleColor->mBackgroundImage = parentStyleColor->mBackgroundImage; styleColor->mBackgroundFlags &= ~NS_STYLE_BG_IMAGE_NONE; } +#endif NS_RELEASE(parentContext); } @@ -520,6 +648,8 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + private: // These are not supported and are not implemented! HTMLStyleSheetImpl(const HTMLStyleSheetImpl& aCopy); @@ -541,6 +671,9 @@ protected: HTMLDocumentColorRule* mDocumentColorRule; TableBackgroundRule* mTableBackgroundRule; TableTHRule* mTableTHRule; + // NOTE: if adding more rules, be sure to update + // the SizeOf method to include them + nsHashtable mMappedAttrTable; }; @@ -1244,6 +1377,141 @@ void HTMLStyleSheetImpl::List(FILE* out, PRInt32 aIndent) const } +struct MappedAttributeSizeEnumData { + MappedAttributeSizeEnumData(nsISizeOfHandler *aSizeOfHandler, + nsUniqueStyleItems *aUniqueStyleItem) + + { + aHandler = aSizeOfHandler; + uniqueItems = aUniqueStyleItem; + } + // weak references all 'round + + nsISizeOfHandler *aHandler; + nsUniqueStyleItems *uniqueItems; +}; + +static +PRBool MappedSizeAttributes(nsHashKey *aKey, void *aData, void* closure) +{ + MappedAttributeSizeEnumData *pData = (MappedAttributeSizeEnumData *)closure; + NS_ASSERTION(pData,"null closure is not supported"); + nsIHTMLMappedAttributes* mapped = (nsIHTMLMappedAttributes*)aData; + NS_ASSERTION(mapped, "null item in enumeration fcn is not supported"); + // if there is an attribute and it has not been counted, the get its size + if(mapped){ + PRUint32 size=0; + mapped->SizeOf(pData->aHandler, size); + } + return PR_TRUE; +} + + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as HTMLStyleSheetImpl's size): +* 1) sizeof(*this) +* +* Contained / Aggregated data (not reported as HTMLStyleSheetImpl's size): +* 1) Not really delegated, but counted seperately: +* - mLinkRule +* - mVisitedRule +* - mActiveRule +* - mDocumentColorRule +* - mTableBackgroundRule +* - mTableTHRule +* - mMappedAttrTable +* 2) Delegates (really) to the MappedAttributes in the mMappedAttrTable +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + if(! uniqueItems->AddItem((void*)this)){ + // this style sheet is lared accounted for + return; + } + + PRUint32 localSize=0; + + // create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("HTMLStyleSheet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(HTMLStyleSheetImpl); + aSizeOfHandler->AddSize(tag,aSize); + + // now gather up the sizes of the data members + // - mLinkRule : sizeof object + // - mVisitedRule : sizeof object + // - mActiveRule : sizeof object + // - mDocumentColorRule : sizeof object + // - mTableBackgroundRule : sizeof object + // - mTableTHRule : sizeof object + // - mMappedAttrTable + + if(mLinkRule && uniqueItems->AddItem((void*)mLinkRule)){ + localSize = sizeof(*mLinkRule); + tag = getter_AddRefs(NS_NewAtom("LinkRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mVisitedRule && uniqueItems->AddItem((void*)mVisitedRule)){ + localSize = sizeof(*mVisitedRule); + tag = getter_AddRefs(NS_NewAtom("VisitedRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mActiveRule && uniqueItems->AddItem((void*)mActiveRule)){ + localSize = sizeof(*mActiveRule); + tag = getter_AddRefs(NS_NewAtom("ActiveRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mDocumentColorRule && uniqueItems->AddItem((void*)mDocumentColorRule)){ + localSize = sizeof(*mDocumentColorRule); + tag = getter_AddRefs(NS_NewAtom("DocumentColorRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableBackgroundRule && uniqueItems->AddItem((void*)mTableBackgroundRule)){ + localSize = sizeof(*mTableBackgroundRule); + tag = getter_AddRefs(NS_NewAtom("TableBackgroundRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + if(mTableTHRule && uniqueItems->AddItem((void*)mTableTHRule)){ + localSize = sizeof(*mTableTHRule); + tag = getter_AddRefs(NS_NewAtom("TableTHRule")); + aSizeOfHandler->AddSize(tag,localSize); + } + + // for the AttrTable it is kindof sleezy: + // We want the hash table overhead as well as the entries it contains + // + // we get the overall size of the hashtable, and if there are entries, + // we calculate a rough overhead estimate as: + // number of entries X sizeof each hash-entry + // + the size of a hash table (see plhash.h and nsHashTable.h) + // then we add up the size of each unique attribute + localSize = sizeof(mMappedAttrTable); + if(mMappedAttrTable.Count() >0){ + localSize += sizeof(PLHashTable); + localSize += mMappedAttrTable.Count() * sizeof(PLHashEntry); + } + tag = getter_AddRefs(NS_NewAtom("MappedAttrTable")); + aSizeOfHandler->AddSize(tag,localSize); + + // now get each unique attribute + MappedAttributeSizeEnumData sizeEnumData(aSizeOfHandler, uniqueItems); + mMappedAttrTable.Enumerate(MappedSizeAttributes, &sizeEnumData); + + // that's it +} + + // XXX For convenience and backwards compatibility NS_HTML nsresult NS_NewHTMLStyleSheet(nsIHTMLStyleSheet** aInstancePtrResult, nsIURI* aURL, diff --git a/mozilla/layout/style/nsICSSStyleRule.h b/mozilla/layout/style/nsICSSStyleRule.h index d3dac04f1cf..b77ec5ed8b6 100644 --- a/mozilla/layout/style/nsICSSStyleRule.h +++ b/mozilla/layout/style/nsICSSStyleRule.h @@ -27,6 +27,8 @@ #include "nsICSSRule.h" #include "nsString.h" +class nsISizeOfHandler; + class nsIAtom; class nsIArena; class nsICSSDeclaration; @@ -58,6 +60,8 @@ public: ~nsAttrSelector(void); PRBool Equals(const nsAttrSelector* aOther) const; + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + PRInt32 mNameSpace; nsIAtom* mAttr; PRUint8 mFunction; @@ -88,7 +92,9 @@ public: void SetOperator(PRUnichar aOperator); PRInt32 CalcWeight(void) const; - + + void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + public: PRInt32 mNameSpace; nsIAtom* mTag; diff --git a/mozilla/layout/style/nsIStyleRule.h b/mozilla/layout/style/nsIStyleRule.h index e5107e4d019..4de54696d92 100644 --- a/mozilla/layout/style/nsIStyleRule.h +++ b/mozilla/layout/style/nsIStyleRule.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIMutableStyleContext; class nsIPresContext; @@ -51,6 +53,9 @@ public: NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext) = 0; NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) = 0; }; + #endif /* nsIStyleRule_h___ */ diff --git a/mozilla/layout/style/nsIStyleRuleProcessor.h b/mozilla/layout/style/nsIStyleRuleProcessor.h index cedb70bc0d7..b4dafa92e12 100644 --- a/mozilla/layout/style/nsIStyleRuleProcessor.h +++ b/mozilla/layout/style/nsIStyleRuleProcessor.h @@ -27,6 +27,8 @@ #include "nslayout.h" #include "nsISupports.h" +class nsISizeOfHandler; + class nsIStyleSheet; class nsIStyleContext; class nsIPresContext; @@ -67,6 +69,8 @@ public: NS_IMETHOD HasStateDependentStyle(nsIPresContext* aPresContext, nsIAtom* aMedium, nsIContent* aContent) = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleRuleProcessor_h___ */ diff --git a/mozilla/layout/style/nsIStyleSheet.h b/mozilla/layout/style/nsIStyleSheet.h index 03b4d6bbd5a..023ae19454f 100644 --- a/mozilla/layout/style/nsIStyleSheet.h +++ b/mozilla/layout/style/nsIStyleSheet.h @@ -24,6 +24,9 @@ #include #include "nsISupports.h" + +class nsISizeOfHandler; + class nsIAtom; class nsString; class nsIURI; @@ -66,6 +69,8 @@ public: // XXX style rule enumerations virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize) = 0; }; #endif /* nsIStyleSheet_h___ */ diff --git a/mozilla/layout/style/nsStyleContext.cpp b/mozilla/layout/style/nsStyleContext.cpp index a4e66ad78d1..3c6dbc276f2 100644 --- a/mozilla/layout/style/nsStyleContext.cpp +++ b/mozilla/layout/style/nsStyleContext.cpp @@ -45,10 +45,18 @@ #include "nsIFrame.h" +#include "nsCOMPtr.h" +#include "nsIStyleSet.h" +#include "nsISizeOfHandler.h" +#include "nsIPresShell.h" + static NS_DEFINE_IID(kIStyleContextIID, NS_ISTYLECONTEXT_IID); #define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nsnull; } +//#ifdef DEBUG_SC_SHARING + + // -------------------- // nsStyleFont // @@ -1673,6 +1681,8 @@ public: virtual void List(FILE* out, PRInt32 aIndent); + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); + protected: void AppendChild(StyleContextImpl* aChild); void RemoveChild(StyleContextImpl* aChild); @@ -1701,6 +1711,8 @@ protected: StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; + + nsCOMPtr mStyleSet; }; static PRInt32 gLastDataCode; @@ -1748,6 +1760,21 @@ StyleContextImpl::StyleContextImpl(nsIStyleContext* aParent, if (nsnull != mRules) { mRules->EnumerateForwards(HashStyleRule, &mRuleHash); } + +#ifdef DEBUG_SC_SHARING + // add this instance to the style set + nsIPresShell* shell = nsnull; + aPresContext->GetShell(&shell); + if (shell) { + shell->GetStyleSet( getter_AddRefs(mStyleSet) ); + if (mStyleSet) { + // add it to the set: the set does NOT addref or release + // NOTE: QI here is not a good idea - this is the constructor so we are not whole yet... + mStyleSet->AddStyleContext((nsIStyleContext *)this); + } + NS_RELEASE( shell ); + } +#endif // DEBUG_SC_SHARING } StyleContextImpl::~StyleContextImpl() @@ -1760,8 +1787,14 @@ StyleContextImpl::~StyleContextImpl() } NS_IF_RELEASE(mPseudoTag); - NS_IF_RELEASE(mRules); + +#ifdef DEBUG_SC_SHARING + // remove this instance from the style set (remember, the set does not AddRef or Release us) + if (mStyleSet) { + mStyleSet->RemoveStyleContext((nsIStyleContext *)this); + } +#endif // DEBUG_SC_SHARING } NS_IMPL_ADDREF(StyleContextImpl) @@ -2446,6 +2479,123 @@ void StyleContextImpl::List(FILE* out, PRInt32 aIndent) } } + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleContextImpl's size): +* 1) sizeof(*this) which gets all of the data members +* 2) adds in the size of the PseudoTag, if there is one +* +* Contained / Aggregated data (not reported as StyleContextImpl's size): +* 1) the Style Rules in mRules are not counted as part of sizeof(*this) +* (though the size of the nsISupportsArray ptr. is) so we need to +* count the rules seperately. For each rule in the mRules collection +* we call the SizeOf method and let it report itself. +* +* Children / siblings / parents: +* 1) We recurse over the mChild and mEmptyChild instances if they exist. +* These instances will then be accumulated seperately (not part of +* the containing instance's size) +* 2) We recurse over the siblings of the Child and Empty Child instances +* and count then seperately as well. +* 3) We recurse over our direct siblings (if any). +* +******************************************************************************/ +void StyleContextImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + static PRBool bDetailDumpDone = PR_FALSE; + if (!bDetailDumpDone) { + bDetailDumpDone = PR_TRUE; + PRUint32 totalSize=0; + + printf( "Detailed StyleContextImpl dump: basic class sizes of members\n" ); + printf( "*************************************\n"); + printf( " - StyleFontImpl: %ld\n", (long)sizeof(mFont) ); + totalSize += (long)sizeof(mFont); + printf( " - StyleColorImpl: %ld\n", (long)sizeof(mColor) ); + totalSize += (long)sizeof(mColor); + printf( " - StyleSpacingImpl: %ld\n", (long)sizeof(mSpacing) ); + totalSize += (long)sizeof(mSpacing); + printf( " - StyleListImpl: %ld\n", (long)sizeof(mList) ); + totalSize += (long)sizeof(mList); + printf( " - StylePositionImpl: %ld\n", (long)sizeof(mPosition) ); + totalSize += (long)sizeof(mPosition); + printf( " - StyleTextImpl: %ld\n", (long)sizeof(mText) ); + totalSize += (long)sizeof(mText); + printf( " - StyleDisplayImpl: %ld\n", (long)sizeof(mDisplay) ); + totalSize += (long)sizeof(mDisplay); + printf( " - StyleTableImpl: %ld\n", (long)sizeof(mTable) ); + totalSize += (long)sizeof(mTable); + printf( " - StyleContentImpl: %ld\n", (long)sizeof(mContent) ); + totalSize += (long)sizeof(mContent); + printf( " - StyleUserInterfaceImpl: %ld\n", (long)sizeof(mUserInterface) ); + totalSize += (long)sizeof(mUserInterface); + printf( " - StylePrintImpl: %ld\n", (long)sizeof(mPrint)); + totalSize += (long)sizeof(mPrint); + printf( " - Total: %ld\n", (long)totalSize); + printf( "*************************************\n"); + } + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + // object has already been accounted for + return; + } + + PRUint32 localSize=0; + + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleContextImpl")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(*this); + // add in the size of the member mPseudoTag + if(mPseudoTag){ + mPseudoTag->SizeOf(aSizeOfHandler, &localSize); + aSize += localSize; + } + aSizeOfHandler->AddSize(tag,aSize); + + // size up the rules (if not already done) + // XXX - overhead of the collection??? + if(mRules && uniqueItems->AddItem(mRules)){ + PRUint32 curRule, ruleCount; + mRules->Count(&ruleCount); + if (ruleCount > 0) { + for (curRule = 0; curRule < ruleCount; curRule++) { + nsIStyleRule* rule = (nsIStyleRule*)mRules->ElementAt(curRule); + NS_ASSERTION(rule, "null entry in Rules list is bad news"); + rule->SizeOf(aSizeOfHandler, localSize); + NS_RELEASE(rule); + } + } + } + // now follow up with the child (and empty child) recursion + if (nsnull != mChild) { + StyleContextImpl* child = mChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mChild != child); + } + if (nsnull != mEmptyChild) { + StyleContextImpl* child = mEmptyChild; + do { + child->SizeOf(aSizeOfHandler, localSize); + child = child->mNextSibling; + } while (mEmptyChild != child); + } + // and finally our direct siblings (if any) + if (nsnull != mNextSibling) { + mNextSibling->SizeOf(aSizeOfHandler, localSize); + } +} + NS_LAYOUT nsresult NS_NewStyleContext(nsIStyleContext** aInstancePtrResult, nsIStyleContext* aParentContext, diff --git a/mozilla/layout/style/nsStyleSet.cpp b/mozilla/layout/style/nsStyleSet.cpp index 7472ff0ddb1..3346da6cbd0 100644 --- a/mozilla/layout/style/nsStyleSet.cpp +++ b/mozilla/layout/style/nsStyleSet.cpp @@ -46,9 +46,12 @@ #define STYLESET_STOP_TIMER(a) ((void)0) #endif +#include "nsISizeOfHandler.h" + static NS_DEFINE_IID(kIStyleSetIID, NS_ISTYLE_SET_IID); static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID); +// #ifdef DEBUG_SC_SHARING class StyleSetImpl : public nsIStyleSet #ifdef MOZ_PERF_METRICS @@ -175,6 +178,15 @@ public: virtual void List(FILE* out = stdout, PRInt32 aIndent = 0); + virtual void SizeOf(nsISizeOfHandler *aSizeofHandler, PRUint32 &aSize); + virtual void ResetUniqueStyleItems(void); + +#ifdef DEBUG_SC_SHARING + // add and remove from the cache of all contexts + NS_IMETHOD AddStyleContext(nsIStyleContext *aNewStyleContext); + NS_IMETHOD RemoveStyleContext(nsIStyleContext *aNewStyleContext); +#endif + #ifdef MOZ_PERF_METRICS NS_DECL_NSITIMERECORDER #endif @@ -207,6 +219,11 @@ protected: nsIStyleFrameConstruction* mFrameConstructor; +#ifdef DEBUG_SC_SHARING + nsVoidArray mStyleContextCache; // a cache of all style contexts for faster searching + // when we want to find style contexts in GetContext +#endif + MOZ_TIMER_DECLARE(mStyleResolutionWatch) #ifdef MOZ_PERF_METRICS @@ -222,6 +239,9 @@ StyleSetImpl::StyleSetImpl() mRuleProcessors(nsnull), mRecycler(nsnull), mFrameConstructor(nsnull) +#ifdef DEBUG_SC_SHARING + ,mStyleContextCache(0) +#endif #ifdef MOZ_PERF_METRICS ,mTimerEnabled(PR_FALSE) #endif @@ -237,6 +257,9 @@ StyleSetImpl::~StyleSetImpl() NS_IF_RELEASE(mRuleProcessors); NS_IF_RELEASE(mFrameConstructor); NS_IF_RELEASE(mRecycler); +#ifdef DEBUG_SC_SHARING + NS_ASSERTION( mStyleContextCache.Count() == 0, "StyleContextCache is not empty: leaking style context?"); +#endif } #ifndef MOZ_PERF_METRICS @@ -565,6 +588,10 @@ EnumRulesMatching(nsISupports* aProcessor, void* aData) return PR_TRUE; } +#ifdef DEBUG_SC_SHARING + static int gNewCount=0; + static int gSharedCount=0; +#endif nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, nsIStyleContext* aParentContext, nsIAtom* aPseudoTag, @@ -572,11 +599,41 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, PRBool aForceUnique, PRBool& aUsedRules) { nsIStyleContext* result = nsnull; - aUsedRules = PR_FALSE; + +#ifdef DEBUG_SC_SHARING + static PRBool bCheckCache = PR_FALSE; // DEBUGGING: set to true or false in debugger... + + if ((PR_FALSE == aForceUnique) && (aParentContext != nsnull)) { + aParentContext->FindChildWithRules(aPseudoTag, aRules, result); + } + if (result == nsnull && bCheckCache) { + // check the context cache for another context to search... + if (PR_FALSE == aForceUnique) { + PRInt32 count = mStyleContextCache.Count(); + PRInt32 i; + for (i=0; iAddRef(); + pContext->FindChildWithRules(aPseudoTag, aRules, result); + pContext->Release(); + if (result != nsnull) { + printf( "StyleContext with matching rules found: %d of %d\n", (int)i, (int)count); + break; + } + } + } + } + } +#else if ((PR_FALSE == aForceUnique) && (nsnull != aParentContext)) { aParentContext->FindChildWithRules(aPseudoTag, aRules, result); } +#endif + if (nsnull == result) { if (NS_OK == NS_NewStyleContext(&result, aParentContext, aPseudoTag, aRules, aPresContext)) { if (PR_TRUE == aForceUnique) { @@ -584,11 +641,16 @@ nsIStyleContext* StyleSetImpl::GetContext(nsIPresContext* aPresContext, } aUsedRules = PRBool(nsnull != aRules); } -//fprintf(stdout, "+"); +#ifdef DEBUG_SC_SHARING + fprintf(stdout, "+++ NewSC %d +++\n", ++gNewCount); +#endif } +#ifdef DEBUG_SC_SHARING else { -//fprintf(stdout, "-"); + fprintf(stdout, "--- SharedSC %d ---\n", ++gSharedCount); } +#endif + return result; } @@ -842,8 +904,8 @@ StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext, nsIStyleContext** aNewStyleContext) { NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); - NS_ASSERTION(aPresContext, "must have pres context"); + NS_ASSERTION(aStyleContext, "must have style context"); + NS_ASSERTION(aNewStyleContext, "must have new style context"); nsresult result = NS_ERROR_NULL_POINTER; @@ -1241,3 +1303,177 @@ StyleSetImpl::PrintTimer(PRUint32 aTimerID) #endif +//----------------------------------------------------------------------------- + +#ifdef DEBUG_SC_SHARING +NS_IMETHODIMP +StyleSetImpl::AddStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in AddStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) == -1), "StyleContext added in AddStyleContext is already in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.AppendElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} + +NS_IMETHODIMP +StyleSetImpl::RemoveStyleContext(nsIStyleContext *aNewStyleContext) +{ + nsresult rv = NS_OK; + +#ifdef DEBUG + // ASSERT the input is valid + NS_ASSERTION(aNewStyleContext != nsnull, "NULL style context not allowed in RemoveStyleContext"); + // ASSERT it is not already in the collection + NS_ASSERTION((mStyleContextCache.IndexOf(aNewStyleContext) != -1), "StyleContext removed in AddStyleContext is not in cache"); + if (aNewStyleContext) { + rv = mStyleContextCache.RemoveElement(aNewStyleContext); + // printf( "StyleContextCount: %ld\n", (long)mStyleContextCache.Count()); + } +#endif + return rv; +} +#endif // DEBUG_SC_SHARING + +//----------------------------------------------------------------------------- + +// static +nsUniqueStyleItems *nsUniqueStyleItems ::mInstance = nsnull; + +void StyleSetImpl::ResetUniqueStyleItems(void) +{ + UNIQUE_STYLE_ITEMS(uniqueItems); + uniqueItems->Clear(); +} + +/****************************************************************************** +* SizeOf method: +* +* Self (reported as StyleSetImpl's size): +* 1) sizeof(*this) + sizeof (overhead only) each collection that exists +* and the FrameConstructor overhead +* +* Contained / Aggregated data (not reported as StyleSetImpl's size): +* 1) Override Sheets, DocSheets, BackstopSheets, RuleProcessors, Recycler +* are all delegated to. +* +* Children / siblings / parents: +* none +* +******************************************************************************/ +void StyleSetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + NS_ASSERTION(aSizeOfHandler != nsnull, "SizeOf handler cannot be null"); + + // first get the unique items collection + UNIQUE_STYLE_ITEMS(uniqueItems); + + if(! uniqueItems->AddItem((void*)this) ){ + NS_ASSERTION(0, "StyleSet has already been conted in SizeOf operation"); + // styleset has already been accounted for + return; + } + // get or create a tag for this instance + nsCOMPtr tag; + tag = getter_AddRefs(NS_NewAtom("StyleSet")); + // get the size of an empty instance and add to the sizeof handler + aSize = sizeof(StyleSetImpl); + + // Next get the size of the OVERHEAD of objects we will delegate to: + if (mOverrideSheets && uniqueItems->AddItem(mOverrideSheets)){ + aSize += sizeof(*mOverrideSheets); + } + if (mDocSheets && uniqueItems->AddItem(mDocSheets)){ + aSize += sizeof(*mDocSheets); + } + if (mBackstopSheets && uniqueItems->AddItem(mBackstopSheets)){ + aSize += sizeof(*mBackstopSheets); + } + if (mRuleProcessors && uniqueItems->AddItem(mRuleProcessors)){ + aSize += sizeof(*mRuleProcessors); + } + if (mRecycler && uniqueItems->AddItem(mRecycler)){ + aSize += sizeof(*mRecycler); + } + /////////////////////////////////////////////// + // now the FrameConstructor + if(mFrameConstructor && uniqueItems->AddItem((void*)mFrameConstructor)){ + aSize += sizeof(mFrameConstructor); + } + aSizeOfHandler->AddSize(tag,aSize); + + /////////////////////////////////////////////// + // Now travers the collections and delegate + PRInt32 numSheets, curSheet; + PRUint32 localSize=0; + numSheets = GetNumberOfOverrideStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetOverrideStyleSheetAt(curSheet); //addref + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfDocStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetDocStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + + numSheets = GetNumberOfBackstopStyleSheets(); + for(curSheet=0; curSheet < numSheets; curSheet++){ + nsIStyleSheet* pSheet = GetBackstopStyleSheetAt(curSheet); + if(pSheet){ + localSize=0; + pSheet->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(pSheet); + } + /////////////////////////////////////////////// + // rule processors + PRUint32 numRuleProcessors,curRuleProcessor; + if(mRuleProcessors){ + mRuleProcessors->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRuleProcessors->ElementAt(curRuleProcessor); + if(processor){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + /////////////////////////////////////////////// + // and the recycled ones too + if(mRecycler){ + mRecycler->Count(&numRuleProcessors); + for(curRuleProcessor=0; curRuleProcessor < numRuleProcessors; curRuleProcessor++){ + nsIStyleRuleProcessor* processor = + (nsIStyleRuleProcessor* )mRecycler->ElementAt(curRuleProcessor); + if(processor && uniqueItems->AddItem((void*)processor)){ + localSize=0; + processor->SizeOf(aSizeOfHandler, localSize); + } + NS_IF_RELEASE(processor); + } + } + + // now delegate the sizeof to the larger or more complex aggregated objects + // - none +} diff --git a/mozilla/rdf/content/src/nsXULElement.cpp b/mozilla/rdf/content/src/nsXULElement.cpp index 460cdb4dc9f..0064572fea1 100644 --- a/mozilla/rdf/content/src/nsXULElement.cpp +++ b/mozilla/rdf/content/src/nsXULElement.cpp @@ -113,6 +113,8 @@ // The XUL doc interface #include "nsIDOMXULDocument.h" +#include "nsISizeOfHandler.h" + // XXX This is sure to change. Copied from mozilla/layout/xul/content/src/nsXULAtoms.cpp #define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" static const char kXULNameSpaceURI[] = XUL_NAMESPACE_URI; @@ -4221,6 +4223,13 @@ nsXULElement::MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPr return NS_OK; } +void nsXULElement::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize) +{ + // XXX - implement this if you want the sizes of XUL style rules + // dumped during StyleSize dump + return; +} + PRBool nsXULElement::ParseNumericValue(const nsString& aString, PRInt32& aIntValue, diff --git a/mozilla/rdf/content/src/nsXULElement.h b/mozilla/rdf/content/src/nsXULElement.h index a18ea1ae9aa..6980eb40b18 100644 --- a/mozilla/rdf/content/src/nsXULElement.h +++ b/mozilla/rdf/content/src/nsXULElement.h @@ -59,6 +59,8 @@ #include "nsXULAttributes.h" #include "nsIChromeEventHandler.h" +class nsISizeOfHandler; + class nsIDocument; class nsIRDFService; class nsISupportsArray; @@ -503,6 +505,8 @@ public: NS_IMETHOD GetStrength(PRInt32& aStrength) const; NS_IMETHOD MapFontStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); NS_IMETHOD MapStyleInto(nsIMutableStyleContext* aContext, nsIPresContext* aPresContext); + + virtual void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); // nsIChromeEventHandler NS_DECL_NSICHROMEEVENTHANDLER diff --git a/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp b/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp index efef5b4d4fc..f2876f2c663 100644 --- a/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp +++ b/mozilla/webshell/tests/viewer/nsBrowserWindow.cpp @@ -3369,10 +3369,49 @@ nsBrowserWindow::ShowContentSize(FILE* out) //---------------------------------------------------------------------- -void -nsBrowserWindow::ShowStyleSize() +static void +GatherStyleDataSizes(nsISizeOfHandler* aHandler, nsIDocShell* aDocShell) { - // XXX not yet implemented + if (nsnull != aDocShell) { + nsIPresShell* shell = GetPresShellFor(aDocShell); + if (nsnull != shell) { + nsIStyleSet *styleSet; + shell->GetStyleSet(&styleSet); + if(styleSet){ + PRUint32 ssSize; + styleSet->ResetUniqueStyleItems(); + // size of the style set + styleSet->SizeOf(aHandler, ssSize); + NS_RELEASE(styleSet); + } + nsIFrame* root; + shell->GetRootFrame(&root); + if (nsnull == root) { + puts("null root frame\n"); + } else { + nsIStyleContext* rootContext; + root->GetStyleContext(&rootContext); + if (nsnull != rootContext) { + PRUint32 contextSize; + // get the sizes from the root context + rootContext->SizeOf(aHandler, contextSize); + NS_RELEASE(rootContext); + } + } + NS_RELEASE(shell); + } + } +} + +void +nsBrowserWindow::ShowStyleSize(FILE* out) +{ + nsCOMPtr handler; + nsresult rv = NS_NewSizeOfHandler(getter_AddRefs(handler)); + if (NS_SUCCEEDED(rv) && handler) { + GatherStyleDataSizes(handler, mDocShell); + ShowReport(out, handler); + } } void diff --git a/mozilla/webshell/tests/viewer/nsBrowserWindow.h b/mozilla/webshell/tests/viewer/nsBrowserWindow.h index 4dec3494f31..992faf3e87b 100644 --- a/mozilla/webshell/tests/viewer/nsBrowserWindow.h +++ b/mozilla/webshell/tests/viewer/nsBrowserWindow.h @@ -184,7 +184,7 @@ public: void ShowContentSize(FILE* out = stdout); void ShowFrameSize(FILE* out = stdout); - void ShowStyleSize(); + void ShowStyleSize(FILE* out = stdout); void DoDebugSave(); void DoToggleSelection(); void DoDebugRobot();