From b8588fe2ca11f465f24468041753985e5250f434 Mon Sep 17 00:00:00 2001 From: "pierre%netscape.com" Date: Mon, 8 Jan 2001 00:24:41 +0000 Subject: [PATCH] Not part of the build. Momentarily check in the StyleContext metrics before doing deeper changes. --- content/base/src/nsStyleContext.cpp | 560 ++++++++++++++++++++++++++++ layout/base/src/nsStyleContext.cpp | 560 ++++++++++++++++++++++++++++ layout/style/nsStyleContext.cpp | 560 ++++++++++++++++++++++++++++ 3 files changed, 1680 insertions(+) diff --git a/content/base/src/nsStyleContext.cpp b/content/base/src/nsStyleContext.cpp index d32265c92a3..f10e153777a 100644 --- a/content/base/src/nsStyleContext.cpp +++ b/content/base/src/nsStyleContext.cpp @@ -1958,6 +1958,175 @@ PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const #ifdef SHARE_STYLECONTEXTS +//======================== +#ifdef DEBUG +// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre +//#define LOG_STYLE_STRUCTS +#endif + +#ifdef LOG_STYLE_STRUCTS +// StyleFontImpl mFont; +struct StyleFontImplLog: public StyleFontImpl { + StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont) + : StyleFontImpl(aVariableFont, aFixedFont), + mInternalFont(aVariableFont, aFixedFont) + {} + void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); + StyleFontImpl mInternalFont; + bool mSetFromParent; +}; + +void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) +{ + StyleFontImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalFont); + mSetFromParent = (aParent != nsnull); +} + +// StyleColorImpl mColor; +struct StyleColorImplLog: public StyleColorImpl { + void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); + StyleColorImpl mInternalColor; + bool mSetFromParent; +}; + +void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) +{ + StyleColorImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalColor); + mSetFromParent = (aParent != nsnull); +} + +// StyleSpacingImpl mSpacing; +struct StyleSpacingImplLog: public StyleSpacingImpl { + void ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext); + StyleSpacingImpl mInternalSpacing; + bool mSetFromParent; +}; + +void StyleSpacingImplLog::ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext) +{ + StyleSpacingImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalSpacing); + mSetFromParent = (aParent != nsnull); +} + +// StyleListImpl mList; +struct StyleListImplLog: public StyleListImpl { + void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); + StyleListImpl mInternalList; + bool mSetFromParent; +}; + +void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) +{ + StyleListImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalList); + mSetFromParent = (aParent != nsnull); +} + +// StylePositionImpl mPosition; +struct StylePositionImplLog: public StylePositionImpl { + void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); + StylePositionImpl mInternalPosition; + bool mSetFromParent; +}; + +void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) +{ + StylePositionImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPosition); + mSetFromParent = (aParent != nsnull); +} + +// StyleTextImpl mText; +struct StyleTextImplLog: public StyleTextImpl { + void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); + StyleTextImpl mInternalText; + bool mSetFromParent; +}; + +void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) +{ + StyleTextImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalText); + mSetFromParent = (aParent != nsnull); +} + +// StyleDisplayImpl mDisplay; +struct StyleDisplayImplLog: public StyleDisplayImpl { + void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); + StyleDisplayImpl mInternalDisplay; + bool mSetFromParent; +}; + +void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) +{ + StyleDisplayImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalDisplay); + mSetFromParent = (aParent != nsnull); +} + +// StyleTableImpl mTable; +struct StyleTableImplLog: public StyleTableImpl { + void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); + StyleTableImpl mInternalTable; + bool mSetFromParent; +}; + +void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) +{ + StyleTableImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalTable); + mSetFromParent = (aParent != nsnull); +} + +// StyleContentImpl mContent; +struct StyleContentImplLog: public StyleContentImpl { + void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); + StyleContentImpl mInternalContent; + bool mSetFromParent; +}; + +void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) +{ + StyleContentImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalContent); + mSetFromParent = (aParent != nsnull); +} + +// StyleUserInterfaceImpl mUserInterface; +struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl { + void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); + StyleUserInterfaceImpl mInternalUserInterface; + bool mSetFromParent; +}; + +void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) +{ + StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalUserInterface); + mSetFromParent = (aParent != nsnull); +} + +// StylePrintImpl mPrint; +struct StylePrintImplLog: public StylePrintImpl { + void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); + StylePrintImpl mInternalPrint; + bool mSetFromParent; +}; + +void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) +{ + StylePrintImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPrint); + mSetFromParent = (aParent != nsnull); +} + + +#endif // LOG_STYLE_STRUCTS +//======================== + class nsStyleContextData { public: @@ -1966,7 +2135,11 @@ public: void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); +#ifdef LOG_STYLE_STRUCTS +public: +#else private: // all data and methods private: only friends have access +#endif static nsStyleContextData *Create(nsIPresContext *aPresContext); @@ -1983,6 +2156,19 @@ private: // all data and methods private: only friends have access // the style data... // - StyleContextImpl gets friend-access // +#ifdef LOG_STYLE_STRUCTS + StyleFontImplLog mFont; + StyleColorImplLog mColor; + StyleSpacingImplLog mSpacing; + StyleListImplLog mList; + StylePositionImplLog mPosition; + StyleTextImplLog mText; + StyleDisplayImplLog mDisplay; + StyleTableImplLog mTable; + StyleContentImplLog mContent; + StyleUserInterfaceImplLog mUserInterface; + StylePrintImplLog mPrint; +#else StyleFontImpl mFont; StyleColorImpl mColor; StyleSpacingImpl mSpacing; @@ -1994,6 +2180,7 @@ private: // all data and methods private: only friends have access StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; +#endif PRUint32 mRefCnt; PRUint32 mCRC; @@ -2059,10 +2246,213 @@ nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext) { } +//========================================================================================================= + +#ifdef LOG_STYLE_STRUCTS //XXX pierre + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpStyleStructs() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} +static void LogStyleStructs(nsStyleContextData* aStyleContextData) +{ +#define max_structs eStyleStruct_Print + + static unsigned long totalCount = 0; + static unsigned long defaultStruct[max_structs]; + static unsigned long setFromParent[max_structs]; + + static bool resetCounters = true; + + if (IsTimeToDumpStyleStructs()) { + resetCounters = true; + printf("\n\n\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Count of nsStyleContextData: %ld\n", totalCount); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%'); + unsigned long totalFootprint = 0; + unsigned long totalPotentialGain = 0; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + short sizeOfStruct = 0; + unsigned long footprint = 0; + unsigned long potentialGain = 0; + switch (index) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); sizeOfStruct = sizeof(StyleSpacingImpl); break; + case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break; + } + short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount)); + short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i])); + + footprint = totalCount * sizeOfStruct; + totalFootprint += footprint; + + potentialGain = defaultStruct[i] * sizeOfStruct; + totalPotentialGain += potentialGain; + + printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024); + } + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Current footprint: %4ld Kb\n", totalFootprint / 1024); + printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%'); + printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n"); + printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + totalCount = 0; + for (short i = 0; i < max_structs; i ++) { + defaultStruct[i] = 0L; + setFromParent[i] = 0L; + } + } + + if (!aStyleContextData) { + printf ("*** aStyleContextData is nil\n"); + return; + } + + totalCount++; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + switch (index) { + case eStyleStruct_Font: + if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mFont.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Color: + if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mColor.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Spacing: + if (aStyleContextData->mSpacing.CalcDifference(aStyleContextData->mSpacing.mInternalSpacing) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mSpacing.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_List: + if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mList.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Position: + if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPosition.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Text: + if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mText.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Display: + if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mDisplay.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Table: + if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mTable.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Content: + if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mContent.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_UserInterface: + if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mUserInterface.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Print: + if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPrint.mSetFromParent) + setFromParent[i]++; + } + break; + } + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_STYLE_STRUCTS + +//========================================================================================================= + nsStyleContextData::~nsStyleContextData(void) { NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData"); // debug here... +#ifdef LOG_STYLE_STRUCTS + LogStyleStructs(this); +#endif } PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const @@ -2524,9 +2914,175 @@ PRUint32 StyleContextImpl::HashValue(void) const return mRuleHash; } +//========================================================================================================= +#ifdef DEBUG +//#define LOG_GET_STYLE_DATA_CALLS // define this to get stats on the calls to GetStyleData() //XXX pierre +#endif + +#ifdef LOG_GET_STYLE_DATA_CALLS + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpGetStyleDataCalls() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} + + +static void LogGetStyleDataCall(nsStyleStructID aSID, bool aMutable, nsIStyleContext* aStyleContext) +{ +#define max_structs eStyleStruct_Print +#define small_depth_threshold 8 + + static unsigned long calls[max_structs*2]; + static unsigned long callspercent[max_structs*2]; + static unsigned long depth[max_structs*2]; + static unsigned long maxdepth[max_structs*2]; + static unsigned long smalldepth[max_structs*2]; + + static bool resetCounters = true; + + if (IsTimeToDumpGetStyleDataCalls()) { + resetCounters = true; + + unsigned long totalCalls; + unsigned long totalMaxdepth; + unsigned long totalDepth; + for (short i = 0; i < (max_structs*2); i ++) { + + if (i%max_structs == 0) { + switch (i) { + case 0: + printf("\n\n\n"); + printf("----GetStyleData--------------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + case max_structs: + printf("----GetMutableStyleData-------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + } + + totalCalls = totalMaxdepth = totalDepth = 0; + for (short j = i; j < i + max_structs; j++) { + totalCalls += calls[j]; + totalDepth += depth[j]; + if (totalMaxdepth < maxdepth[j]) { + totalMaxdepth = maxdepth[j]; + } + } + } + + switch (i%max_structs + 1) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); break; + case eStyleStruct_List: printf("eStyleStruct_List "); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); break; + } + short percent = 100*calls[i]/totalCalls; + short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i])); + short smdepth = 100*smalldepth[i]/calls[i]; + if (percent == 0) { + printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth); + } + else { + printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth); + } + + if (i%max_structs + 1 == max_structs) { + short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls)); + printf("TOTAL "); + printf(" %7ld 100 %3ld %3d\n", totalCalls, totalMaxdepth, totaldepth); + } + + } + printf("------------------------------------------------------------------------------------------\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + for (short i = 0; i < (max_structs*2); i ++) { + calls[i] = 0L; + depth[i] = 0L; + maxdepth[i] = 0L; + smalldepth[i] = 0L; + } + } + + short index = aSID - 1; + if (aMutable) { + index += max_structs; + } + + calls[index]++; + + unsigned long curdepth = 0; + nsCOMPtr childContext; + nsCOMPtr parentContext; + childContext = aStyleContext; + parentContext = getter_AddRefs(childContext->GetParent()); + while (parentContext != nsnull) { + curdepth++; + parentContext = getter_AddRefs(childContext->GetParent()); + if (parentContext == childContext) { + break; + } + childContext = parentContext; + } + depth[index] += curdepth; + if (maxdepth[index] < curdepth) { + maxdepth[index] = curdepth; + } + if (curdepth <= small_depth_threshold) { + smalldepth[index]++; + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_GET_STYLE_DATA_CALLS +//========================================================================================================= + const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, false, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) { @@ -2572,6 +3128,10 @@ const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, true, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) { diff --git a/layout/base/src/nsStyleContext.cpp b/layout/base/src/nsStyleContext.cpp index d32265c92a3..f10e153777a 100644 --- a/layout/base/src/nsStyleContext.cpp +++ b/layout/base/src/nsStyleContext.cpp @@ -1958,6 +1958,175 @@ PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const #ifdef SHARE_STYLECONTEXTS +//======================== +#ifdef DEBUG +// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre +//#define LOG_STYLE_STRUCTS +#endif + +#ifdef LOG_STYLE_STRUCTS +// StyleFontImpl mFont; +struct StyleFontImplLog: public StyleFontImpl { + StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont) + : StyleFontImpl(aVariableFont, aFixedFont), + mInternalFont(aVariableFont, aFixedFont) + {} + void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); + StyleFontImpl mInternalFont; + bool mSetFromParent; +}; + +void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) +{ + StyleFontImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalFont); + mSetFromParent = (aParent != nsnull); +} + +// StyleColorImpl mColor; +struct StyleColorImplLog: public StyleColorImpl { + void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); + StyleColorImpl mInternalColor; + bool mSetFromParent; +}; + +void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) +{ + StyleColorImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalColor); + mSetFromParent = (aParent != nsnull); +} + +// StyleSpacingImpl mSpacing; +struct StyleSpacingImplLog: public StyleSpacingImpl { + void ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext); + StyleSpacingImpl mInternalSpacing; + bool mSetFromParent; +}; + +void StyleSpacingImplLog::ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext) +{ + StyleSpacingImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalSpacing); + mSetFromParent = (aParent != nsnull); +} + +// StyleListImpl mList; +struct StyleListImplLog: public StyleListImpl { + void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); + StyleListImpl mInternalList; + bool mSetFromParent; +}; + +void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) +{ + StyleListImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalList); + mSetFromParent = (aParent != nsnull); +} + +// StylePositionImpl mPosition; +struct StylePositionImplLog: public StylePositionImpl { + void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); + StylePositionImpl mInternalPosition; + bool mSetFromParent; +}; + +void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) +{ + StylePositionImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPosition); + mSetFromParent = (aParent != nsnull); +} + +// StyleTextImpl mText; +struct StyleTextImplLog: public StyleTextImpl { + void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); + StyleTextImpl mInternalText; + bool mSetFromParent; +}; + +void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) +{ + StyleTextImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalText); + mSetFromParent = (aParent != nsnull); +} + +// StyleDisplayImpl mDisplay; +struct StyleDisplayImplLog: public StyleDisplayImpl { + void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); + StyleDisplayImpl mInternalDisplay; + bool mSetFromParent; +}; + +void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) +{ + StyleDisplayImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalDisplay); + mSetFromParent = (aParent != nsnull); +} + +// StyleTableImpl mTable; +struct StyleTableImplLog: public StyleTableImpl { + void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); + StyleTableImpl mInternalTable; + bool mSetFromParent; +}; + +void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) +{ + StyleTableImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalTable); + mSetFromParent = (aParent != nsnull); +} + +// StyleContentImpl mContent; +struct StyleContentImplLog: public StyleContentImpl { + void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); + StyleContentImpl mInternalContent; + bool mSetFromParent; +}; + +void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) +{ + StyleContentImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalContent); + mSetFromParent = (aParent != nsnull); +} + +// StyleUserInterfaceImpl mUserInterface; +struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl { + void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); + StyleUserInterfaceImpl mInternalUserInterface; + bool mSetFromParent; +}; + +void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) +{ + StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalUserInterface); + mSetFromParent = (aParent != nsnull); +} + +// StylePrintImpl mPrint; +struct StylePrintImplLog: public StylePrintImpl { + void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); + StylePrintImpl mInternalPrint; + bool mSetFromParent; +}; + +void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) +{ + StylePrintImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPrint); + mSetFromParent = (aParent != nsnull); +} + + +#endif // LOG_STYLE_STRUCTS +//======================== + class nsStyleContextData { public: @@ -1966,7 +2135,11 @@ public: void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); +#ifdef LOG_STYLE_STRUCTS +public: +#else private: // all data and methods private: only friends have access +#endif static nsStyleContextData *Create(nsIPresContext *aPresContext); @@ -1983,6 +2156,19 @@ private: // all data and methods private: only friends have access // the style data... // - StyleContextImpl gets friend-access // +#ifdef LOG_STYLE_STRUCTS + StyleFontImplLog mFont; + StyleColorImplLog mColor; + StyleSpacingImplLog mSpacing; + StyleListImplLog mList; + StylePositionImplLog mPosition; + StyleTextImplLog mText; + StyleDisplayImplLog mDisplay; + StyleTableImplLog mTable; + StyleContentImplLog mContent; + StyleUserInterfaceImplLog mUserInterface; + StylePrintImplLog mPrint; +#else StyleFontImpl mFont; StyleColorImpl mColor; StyleSpacingImpl mSpacing; @@ -1994,6 +2180,7 @@ private: // all data and methods private: only friends have access StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; +#endif PRUint32 mRefCnt; PRUint32 mCRC; @@ -2059,10 +2246,213 @@ nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext) { } +//========================================================================================================= + +#ifdef LOG_STYLE_STRUCTS //XXX pierre + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpStyleStructs() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} +static void LogStyleStructs(nsStyleContextData* aStyleContextData) +{ +#define max_structs eStyleStruct_Print + + static unsigned long totalCount = 0; + static unsigned long defaultStruct[max_structs]; + static unsigned long setFromParent[max_structs]; + + static bool resetCounters = true; + + if (IsTimeToDumpStyleStructs()) { + resetCounters = true; + printf("\n\n\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Count of nsStyleContextData: %ld\n", totalCount); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%'); + unsigned long totalFootprint = 0; + unsigned long totalPotentialGain = 0; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + short sizeOfStruct = 0; + unsigned long footprint = 0; + unsigned long potentialGain = 0; + switch (index) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); sizeOfStruct = sizeof(StyleSpacingImpl); break; + case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break; + } + short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount)); + short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i])); + + footprint = totalCount * sizeOfStruct; + totalFootprint += footprint; + + potentialGain = defaultStruct[i] * sizeOfStruct; + totalPotentialGain += potentialGain; + + printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024); + } + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Current footprint: %4ld Kb\n", totalFootprint / 1024); + printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%'); + printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n"); + printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + totalCount = 0; + for (short i = 0; i < max_structs; i ++) { + defaultStruct[i] = 0L; + setFromParent[i] = 0L; + } + } + + if (!aStyleContextData) { + printf ("*** aStyleContextData is nil\n"); + return; + } + + totalCount++; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + switch (index) { + case eStyleStruct_Font: + if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mFont.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Color: + if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mColor.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Spacing: + if (aStyleContextData->mSpacing.CalcDifference(aStyleContextData->mSpacing.mInternalSpacing) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mSpacing.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_List: + if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mList.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Position: + if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPosition.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Text: + if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mText.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Display: + if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mDisplay.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Table: + if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mTable.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Content: + if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mContent.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_UserInterface: + if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mUserInterface.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Print: + if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPrint.mSetFromParent) + setFromParent[i]++; + } + break; + } + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_STYLE_STRUCTS + +//========================================================================================================= + nsStyleContextData::~nsStyleContextData(void) { NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData"); // debug here... +#ifdef LOG_STYLE_STRUCTS + LogStyleStructs(this); +#endif } PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const @@ -2524,9 +2914,175 @@ PRUint32 StyleContextImpl::HashValue(void) const return mRuleHash; } +//========================================================================================================= +#ifdef DEBUG +//#define LOG_GET_STYLE_DATA_CALLS // define this to get stats on the calls to GetStyleData() //XXX pierre +#endif + +#ifdef LOG_GET_STYLE_DATA_CALLS + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpGetStyleDataCalls() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} + + +static void LogGetStyleDataCall(nsStyleStructID aSID, bool aMutable, nsIStyleContext* aStyleContext) +{ +#define max_structs eStyleStruct_Print +#define small_depth_threshold 8 + + static unsigned long calls[max_structs*2]; + static unsigned long callspercent[max_structs*2]; + static unsigned long depth[max_structs*2]; + static unsigned long maxdepth[max_structs*2]; + static unsigned long smalldepth[max_structs*2]; + + static bool resetCounters = true; + + if (IsTimeToDumpGetStyleDataCalls()) { + resetCounters = true; + + unsigned long totalCalls; + unsigned long totalMaxdepth; + unsigned long totalDepth; + for (short i = 0; i < (max_structs*2); i ++) { + + if (i%max_structs == 0) { + switch (i) { + case 0: + printf("\n\n\n"); + printf("----GetStyleData--------------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + case max_structs: + printf("----GetMutableStyleData-------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + } + + totalCalls = totalMaxdepth = totalDepth = 0; + for (short j = i; j < i + max_structs; j++) { + totalCalls += calls[j]; + totalDepth += depth[j]; + if (totalMaxdepth < maxdepth[j]) { + totalMaxdepth = maxdepth[j]; + } + } + } + + switch (i%max_structs + 1) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); break; + case eStyleStruct_List: printf("eStyleStruct_List "); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); break; + } + short percent = 100*calls[i]/totalCalls; + short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i])); + short smdepth = 100*smalldepth[i]/calls[i]; + if (percent == 0) { + printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth); + } + else { + printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth); + } + + if (i%max_structs + 1 == max_structs) { + short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls)); + printf("TOTAL "); + printf(" %7ld 100 %3ld %3d\n", totalCalls, totalMaxdepth, totaldepth); + } + + } + printf("------------------------------------------------------------------------------------------\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + for (short i = 0; i < (max_structs*2); i ++) { + calls[i] = 0L; + depth[i] = 0L; + maxdepth[i] = 0L; + smalldepth[i] = 0L; + } + } + + short index = aSID - 1; + if (aMutable) { + index += max_structs; + } + + calls[index]++; + + unsigned long curdepth = 0; + nsCOMPtr childContext; + nsCOMPtr parentContext; + childContext = aStyleContext; + parentContext = getter_AddRefs(childContext->GetParent()); + while (parentContext != nsnull) { + curdepth++; + parentContext = getter_AddRefs(childContext->GetParent()); + if (parentContext == childContext) { + break; + } + childContext = parentContext; + } + depth[index] += curdepth; + if (maxdepth[index] < curdepth) { + maxdepth[index] = curdepth; + } + if (curdepth <= small_depth_threshold) { + smalldepth[index]++; + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_GET_STYLE_DATA_CALLS +//========================================================================================================= + const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, false, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) { @@ -2572,6 +3128,10 @@ const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, true, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) { diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index d32265c92a3..f10e153777a 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -1958,6 +1958,175 @@ PRUint32 StylePrintImpl::ComputeCRC32(PRUint32 aCrc) const #ifdef SHARE_STYLECONTEXTS +//======================== +#ifdef DEBUG +// define this to get stats on the use of the |nsStyleStruct|s inside a |nsStyleContextData|. //XXX pierre +//#define LOG_STYLE_STRUCTS +#endif + +#ifdef LOG_STYLE_STRUCTS +// StyleFontImpl mFont; +struct StyleFontImplLog: public StyleFontImpl { + StyleFontImplLog(const nsFont& aVariableFont, const nsFont& aFixedFont) + : StyleFontImpl(aVariableFont, aFixedFont), + mInternalFont(aVariableFont, aFixedFont) + {} + void ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext); + StyleFontImpl mInternalFont; + bool mSetFromParent; +}; + +void StyleFontImplLog::ResetFrom(const nsStyleFont* aParent, nsIPresContext* aPresContext) +{ + StyleFontImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalFont); + mSetFromParent = (aParent != nsnull); +} + +// StyleColorImpl mColor; +struct StyleColorImplLog: public StyleColorImpl { + void ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext); + StyleColorImpl mInternalColor; + bool mSetFromParent; +}; + +void StyleColorImplLog::ResetFrom(const nsStyleColor* aParent, nsIPresContext* aPresContext) +{ + StyleColorImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalColor); + mSetFromParent = (aParent != nsnull); +} + +// StyleSpacingImpl mSpacing; +struct StyleSpacingImplLog: public StyleSpacingImpl { + void ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext); + StyleSpacingImpl mInternalSpacing; + bool mSetFromParent; +}; + +void StyleSpacingImplLog::ResetFrom(const nsStyleSpacing* aParent, nsIPresContext* aPresContext) +{ + StyleSpacingImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalSpacing); + mSetFromParent = (aParent != nsnull); +} + +// StyleListImpl mList; +struct StyleListImplLog: public StyleListImpl { + void ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext); + StyleListImpl mInternalList; + bool mSetFromParent; +}; + +void StyleListImplLog::ResetFrom(const nsStyleList* aParent, nsIPresContext* aPresContext) +{ + StyleListImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalList); + mSetFromParent = (aParent != nsnull); +} + +// StylePositionImpl mPosition; +struct StylePositionImplLog: public StylePositionImpl { + void ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext); + StylePositionImpl mInternalPosition; + bool mSetFromParent; +}; + +void StylePositionImplLog::ResetFrom(const nsStylePosition* aParent, nsIPresContext* aPresContext) +{ + StylePositionImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPosition); + mSetFromParent = (aParent != nsnull); +} + +// StyleTextImpl mText; +struct StyleTextImplLog: public StyleTextImpl { + void ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext); + StyleTextImpl mInternalText; + bool mSetFromParent; +}; + +void StyleTextImplLog::ResetFrom(const nsStyleText* aParent, nsIPresContext* aPresContext) +{ + StyleTextImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalText); + mSetFromParent = (aParent != nsnull); +} + +// StyleDisplayImpl mDisplay; +struct StyleDisplayImplLog: public StyleDisplayImpl { + void ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext); + StyleDisplayImpl mInternalDisplay; + bool mSetFromParent; +}; + +void StyleDisplayImplLog::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* aPresContext) +{ + StyleDisplayImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalDisplay); + mSetFromParent = (aParent != nsnull); +} + +// StyleTableImpl mTable; +struct StyleTableImplLog: public StyleTableImpl { + void ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext); + StyleTableImpl mInternalTable; + bool mSetFromParent; +}; + +void StyleTableImplLog::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPresContext) +{ + StyleTableImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalTable); + mSetFromParent = (aParent != nsnull); +} + +// StyleContentImpl mContent; +struct StyleContentImplLog: public StyleContentImpl { + void ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext); + StyleContentImpl mInternalContent; + bool mSetFromParent; +}; + +void StyleContentImplLog::ResetFrom(const StyleContentImpl* aParent, nsIPresContext* aPresContext) +{ + StyleContentImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalContent); + mSetFromParent = (aParent != nsnull); +} + +// StyleUserInterfaceImpl mUserInterface; +struct StyleUserInterfaceImplLog: public StyleUserInterfaceImpl { + void ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext); + StyleUserInterfaceImpl mInternalUserInterface; + bool mSetFromParent; +}; + +void StyleUserInterfaceImplLog::ResetFrom(const nsStyleUserInterface* aParent, nsIPresContext* aPresContext) +{ + StyleUserInterfaceImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalUserInterface); + mSetFromParent = (aParent != nsnull); +} + +// StylePrintImpl mPrint; +struct StylePrintImplLog: public StylePrintImpl { + void ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext); + StylePrintImpl mInternalPrint; + bool mSetFromParent; +}; + +void StylePrintImplLog::ResetFrom(const nsStylePrint* aParent, nsIPresContext* aPresContext) +{ + StylePrintImpl::ResetFrom(aParent, aPresContext); + CopyTo(mInternalPrint); + mSetFromParent = (aParent != nsnull); +} + + +#endif // LOG_STYLE_STRUCTS +//======================== + class nsStyleContextData { public: @@ -1966,7 +2135,11 @@ public: void SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize); +#ifdef LOG_STYLE_STRUCTS +public: +#else private: // all data and methods private: only friends have access +#endif static nsStyleContextData *Create(nsIPresContext *aPresContext); @@ -1983,6 +2156,19 @@ private: // all data and methods private: only friends have access // the style data... // - StyleContextImpl gets friend-access // +#ifdef LOG_STYLE_STRUCTS + StyleFontImplLog mFont; + StyleColorImplLog mColor; + StyleSpacingImplLog mSpacing; + StyleListImplLog mList; + StylePositionImplLog mPosition; + StyleTextImplLog mText; + StyleDisplayImplLog mDisplay; + StyleTableImplLog mTable; + StyleContentImplLog mContent; + StyleUserInterfaceImplLog mUserInterface; + StylePrintImplLog mPrint; +#else StyleFontImpl mFont; StyleColorImpl mColor; StyleSpacingImpl mSpacing; @@ -1994,6 +2180,7 @@ private: // all data and methods private: only friends have access StyleContentImpl mContent; StyleUserInterfaceImpl mUserInterface; StylePrintImpl mPrint; +#endif PRUint32 mRefCnt; PRUint32 mCRC; @@ -2059,10 +2246,213 @@ nsStyleContextData::nsStyleContextData(nsIPresContext *aPresContext) { } +//========================================================================================================= + +#ifdef LOG_STYLE_STRUCTS //XXX pierre + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpStyleStructs() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} +static void LogStyleStructs(nsStyleContextData* aStyleContextData) +{ +#define max_structs eStyleStruct_Print + + static unsigned long totalCount = 0; + static unsigned long defaultStruct[max_structs]; + static unsigned long setFromParent[max_structs]; + + static bool resetCounters = true; + + if (IsTimeToDumpStyleStructs()) { + resetCounters = true; + printf("\n\n\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Count of nsStyleContextData: %ld\n", totalCount); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf(" unchanged unchanged%c set-from-parent%c size-of-struct potential-gain-Kb\n", '%', '%'); + unsigned long totalFootprint = 0; + unsigned long totalPotentialGain = 0; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + short sizeOfStruct = 0; + unsigned long footprint = 0; + unsigned long potentialGain = 0; + switch (index) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); sizeOfStruct = sizeof(StyleFontImpl); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); sizeOfStruct = sizeof(StyleColorImpl); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); sizeOfStruct = sizeof(StyleSpacingImpl); break; + case eStyleStruct_List: printf("eStyleStruct_List "); sizeOfStruct = sizeof(StyleListImpl); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); sizeOfStruct = sizeof(StylePositionImpl); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); sizeOfStruct = sizeof(StyleTextImpl); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); sizeOfStruct = sizeof(StyleDisplayImpl); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); sizeOfStruct = sizeof(StyleTableImpl); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); sizeOfStruct = sizeof(StyleContentImpl); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); sizeOfStruct = sizeof(StyleUserInterfaceImpl); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); sizeOfStruct = sizeof(StylePrintImpl); break; + } + short percentDefault = (totalCount == 0 ? 0 : ((100 * defaultStruct[i]) / totalCount)); + short percentFromParent = (defaultStruct[i] == 0 ? 0 : ((100 * setFromParent[i]) / defaultStruct[i])); + + footprint = totalCount * sizeOfStruct; + totalFootprint += footprint; + + potentialGain = defaultStruct[i] * sizeOfStruct; + totalPotentialGain += potentialGain; + + printf(" %7ld %3d %3d %5d %5d\n", defaultStruct[i], percentDefault, percentFromParent, sizeOfStruct, potentialGain / 1024); + } + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("Current footprint: %4ld Kb\n", totalFootprint / 1024); + printf("Potential gain: %4ld Kb (or %d%c)\n", totalPotentialGain / 1024, totalPotentialGain*100/totalFootprint, '%'); + printf("Would remain: %4ld Kb\n", (totalFootprint - totalPotentialGain) / 1024); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("These stats come from the nsStyleContextData structures that have been deleted since the last output.\n"); + printf("To get the stats for a particular page: load page, dump stats, load 'about:blank', dump stats again.\n"); + printf("-------------------------------------------------------------------------------------------------------------\n"); + printf("\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + totalCount = 0; + for (short i = 0; i < max_structs; i ++) { + defaultStruct[i] = 0L; + setFromParent[i] = 0L; + } + } + + if (!aStyleContextData) { + printf ("*** aStyleContextData is nil\n"); + return; + } + + totalCount++; + for (short i = 0; i < max_structs; i ++) { + short index = i+1; + switch (index) { + case eStyleStruct_Font: + if (aStyleContextData->mFont.CalcDifference(aStyleContextData->mFont.mInternalFont) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mFont.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Color: + if (aStyleContextData->mColor.CalcDifference(aStyleContextData->mColor.mInternalColor) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mColor.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Spacing: + if (aStyleContextData->mSpacing.CalcDifference(aStyleContextData->mSpacing.mInternalSpacing) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mSpacing.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_List: + if (aStyleContextData->mList.CalcDifference(aStyleContextData->mList.mInternalList) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mList.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Position: + if (aStyleContextData->mPosition.CalcDifference(aStyleContextData->mPosition.mInternalPosition) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPosition.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Text: + if (aStyleContextData->mText.CalcDifference(aStyleContextData->mText.mInternalText) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mText.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Display: + if (aStyleContextData->mDisplay.CalcDifference(aStyleContextData->mDisplay.mInternalDisplay) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mDisplay.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Table: + if (aStyleContextData->mTable.CalcDifference(aStyleContextData->mTable.mInternalTable) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mTable.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Content: + if (aStyleContextData->mContent.CalcDifference(aStyleContextData->mContent.mInternalContent) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mContent.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_UserInterface: + if (aStyleContextData->mUserInterface.CalcDifference(aStyleContextData->mUserInterface.mInternalUserInterface) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mUserInterface.mSetFromParent) + setFromParent[i]++; + } + break; + case eStyleStruct_Print: + if (aStyleContextData->mPrint.CalcDifference(aStyleContextData->mPrint.mInternalPrint) == NS_STYLE_HINT_NONE) { + defaultStruct[i]++; + if (aStyleContextData->mPrint.mSetFromParent) + setFromParent[i]++; + } + break; + } + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_STYLE_STRUCTS + +//========================================================================================================= + nsStyleContextData::~nsStyleContextData(void) { NS_ASSERTION(0 == mRefCnt, "RefCount error in ~nsStyleContextData"); // debug here... +#ifdef LOG_STYLE_STRUCTS + LogStyleStructs(this); +#endif } PRUint32 nsStyleContextData::ComputeCRC32(PRUint32 aCrc) const @@ -2524,9 +2914,175 @@ PRUint32 StyleContextImpl::HashValue(void) const return mRuleHash; } +//========================================================================================================= +#ifdef DEBUG +//#define LOG_GET_STYLE_DATA_CALLS // define this to get stats on the calls to GetStyleData() //XXX pierre +#endif + +#ifdef LOG_GET_STYLE_DATA_CALLS + +#ifdef XP_MAC +#include +static bool MacKeyDown(unsigned char theKey) +{ + KeyMap map; + GetKeys(map); + return ((*((unsigned char *)map + (theKey >> 3)) >> (theKey & 7)) & 1) != 0; +} +#endif + + +static bool IsTimeToDumpGetStyleDataCalls() +{ + bool timeToDump = false; +#ifdef XP_MAC + static unsigned long lastTicks = 0; + if (MacKeyDown(0x3b)) { // control key + if ((unsigned long)(::TickCount() - lastTicks) > 60) { + lastTicks = ::TickCount(); + timeToDump = true; + } + } +#endif + return timeToDump; +} + + +static void LogGetStyleDataCall(nsStyleStructID aSID, bool aMutable, nsIStyleContext* aStyleContext) +{ +#define max_structs eStyleStruct_Print +#define small_depth_threshold 8 + + static unsigned long calls[max_structs*2]; + static unsigned long callspercent[max_structs*2]; + static unsigned long depth[max_structs*2]; + static unsigned long maxdepth[max_structs*2]; + static unsigned long smalldepth[max_structs*2]; + + static bool resetCounters = true; + + if (IsTimeToDumpGetStyleDataCalls()) { + resetCounters = true; + + unsigned long totalCalls; + unsigned long totalMaxdepth; + unsigned long totalDepth; + for (short i = 0; i < (max_structs*2); i ++) { + + if (i%max_structs == 0) { + switch (i) { + case 0: + printf("\n\n\n"); + printf("----GetStyleData--------------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + case max_structs: + printf("----GetMutableStyleData-------------------------------------------------------------------\n"); + printf(" calls calls%c max depth avg depth (depth<%d)%\n", '%', small_depth_threshold); + break; + } + + totalCalls = totalMaxdepth = totalDepth = 0; + for (short j = i; j < i + max_structs; j++) { + totalCalls += calls[j]; + totalDepth += depth[j]; + if (totalMaxdepth < maxdepth[j]) { + totalMaxdepth = maxdepth[j]; + } + } + } + + switch (i%max_structs + 1) { + case eStyleStruct_Font: printf("eStyleStruct_Font "); break; + case eStyleStruct_Color: printf("eStyleStruct_Color "); break; + case eStyleStruct_Spacing: printf("eStyleStruct_Spacing "); break; + case eStyleStruct_List: printf("eStyleStruct_List "); break; + case eStyleStruct_Position: printf("eStyleStruct_Position "); break; + case eStyleStruct_Text: printf("eStyleStruct_Text "); break; + case eStyleStruct_Display: printf("eStyleStruct_Display "); break; + case eStyleStruct_Table: printf("eStyleStruct_Table "); break; + case eStyleStruct_Content: printf("eStyleStruct_Content "); break; + case eStyleStruct_UserInterface: printf("eStyleStruct_UserInterface "); break; + case eStyleStruct_Print: printf("eStyleStruct_Print "); break; + } + short percent = 100*calls[i]/totalCalls; + short avdepth = calls[i] == 0 ? 0 : round(float(depth[i])/float(calls[i])); + short smdepth = 100*smalldepth[i]/calls[i]; + if (percent == 0) { + printf(" %7ld - %3ld %3d %3d\n", calls[i], maxdepth[i], avdepth, smdepth); + } + else { + printf(" %7ld %2ld %3ld %3d %3d\n", calls[i], percent, maxdepth[i], avdepth, smdepth); + } + + if (i%max_structs + 1 == max_structs) { + short totaldepth = totalCalls == 0 ? 0 : round(float(totalDepth)/float(totalCalls)); + printf("TOTAL "); + printf(" %7ld 100 %3ld %3d\n", totalCalls, totalMaxdepth, totaldepth); + } + + } + printf("------------------------------------------------------------------------------------------\n\n\n"); + } + + if (resetCounters) { + resetCounters = false; + for (short i = 0; i < (max_structs*2); i ++) { + calls[i] = 0L; + depth[i] = 0L; + maxdepth[i] = 0L; + smalldepth[i] = 0L; + } + } + + short index = aSID - 1; + if (aMutable) { + index += max_structs; + } + + calls[index]++; + + unsigned long curdepth = 0; + nsCOMPtr childContext; + nsCOMPtr parentContext; + childContext = aStyleContext; + parentContext = getter_AddRefs(childContext->GetParent()); + while (parentContext != nsnull) { + curdepth++; + parentContext = getter_AddRefs(childContext->GetParent()); + if (parentContext == childContext) { + break; + } + childContext = parentContext; + } + depth[index] += curdepth; + if (maxdepth[index] < curdepth) { + maxdepth[index] = curdepth; + } + if (curdepth <= small_depth_threshold) { + smalldepth[index]++; + } + + static short inCount = 0; + static short outCount = 0; + if (inCount++ % 1000 == 0) { + switch (outCount++) { + case 0: printf("still logging"); break; + case 20: printf("\n"); outCount = 0; break; + default: printf("."); fflush(stdout); break; + } + } +} +#endif // LOG_GET_STYLE_DATA_CALLS +//========================================================================================================= + const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, false, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) { @@ -2572,6 +3128,10 @@ const nsStyleStruct* StyleContextImpl::GetStyleData(nsStyleStructID aSID) nsStyleStruct* StyleContextImpl::GetMutableStyleData(nsStyleStructID aSID) { +#ifdef LOG_GET_STYLE_DATA_CALLS + LogGetStyleDataCall(aSID, true, this); +#endif + nsStyleStruct* result = nsnull; switch (aSID) {