Added additional reflow count info on a frame by frame basis

Bug 69361 r=attinasi sr=waterson
This commit is contained in:
rods%netscape.com 2001-02-22 13:58:17 +00:00
Родитель 4b58c0409c
Коммит 6059a83cca
10 изменённых файлов: 319 добавлений и 29 удалений

Просмотреть файл

@ -509,7 +509,7 @@ public:
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD ClearTotals() = 0; NS_IMETHOD ClearTotals() = 0;
NS_IMETHOD DumpReflows() = 0; NS_IMETHOD DumpReflows() = 0;
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
#endif #endif
}; };

Просмотреть файл

@ -1333,10 +1333,10 @@ nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType) nsPresContext::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)
{ {
if (mShell) { if (mShell) {
mShell->CountReflows(aName, aType); mShell->CountReflows(aName, aType, aFrame);
} }
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -380,7 +380,7 @@ public:
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
#endif #endif
}; };
@ -403,7 +403,7 @@ extern NS_LAYOUT nsresult
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) \ #define DO_GLOBAL_REFLOW_COUNT(_name, _type) \
aPresContext->CountReflows((_name), (_type)); aPresContext->CountReflows((_name), (_type), (nsIFrame*)this);
#else #else
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) #define DO_GLOBAL_REFLOW_COUNT(_name, _type)
#endif // MOZ_REFLOW_PERF #endif // MOZ_REFLOW_PERF

Просмотреть файл

@ -194,8 +194,7 @@ static const char * kGrandTotalsStr = "Grand Totals";
// Counting Class // Counting Class
class ReflowCounter { class ReflowCounter {
public: public:
ReflowCounter() { mMgr = nsnull; } ReflowCounter(ReflowCountMgr * aMgr = nsnull);
ReflowCounter(ReflowCountMgr * aMgr);
~ReflowCounter(); ~ReflowCounter();
void ClearTotals(); void ClearTotals();
@ -211,6 +210,8 @@ public:
void SetMgr(ReflowCountMgr * aMgr) { mMgr = aMgr; } void SetMgr(ReflowCountMgr * aMgr) { mMgr = aMgr; }
PRUint32 GetTotalByType(nsReflowReason aType) { if (aType >= eReflowReason_Initial && aType <= eReflowReason_Dirty) return mTotals[aType]; else return 0; }
protected: protected:
void DisplayTotals(PRUint32 * aArray, const char * aTitle); void DisplayTotals(PRUint32 * aArray, const char * aTitle);
void DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle); void DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle);
@ -221,6 +222,24 @@ protected:
ReflowCountMgr * mMgr; ReflowCountMgr * mMgr;
}; };
// Counting Class
class IndiReflowCounter {
public:
IndiReflowCounter(ReflowCountMgr * aMgr = nsnull):mMgr(aMgr),mCounter(aMgr),mFrame(nsnull),mParent(nsnull), mCount(0), mHasBeenOutput(PR_FALSE) {}
virtual ~IndiReflowCounter() {}
nsAutoString mName;
nsIFrame * mFrame;
nsIFrame * mParent;
PRInt32 mCount;
ReflowCountMgr * mMgr;
ReflowCounter mCounter;
PRBool mHasBeenOutput;
};
// Manager Class // Manager Class
class ReflowCountMgr { class ReflowCountMgr {
public: public:
@ -235,21 +254,30 @@ public:
void DisplayHTMLTotals(const char * aStr); void DisplayHTMLTotals(const char * aStr);
void DisplayDiffsInTotals(const char * aStr); void DisplayDiffsInTotals(const char * aStr);
void Add(const char * aName, nsReflowReason aType); void Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame);
ReflowCounter * LookUp(const char * aName); ReflowCounter * LookUp(const char * aName);
FILE * GetOutFile() { return mFD; } FILE * GetOutFile() { return mFD; }
PLHashTable * GetIndiFrameHT() { return mIndiFrameCounts; }
void SetPresContext(nsIPresContext * aPresContext) { mPresContext = aPresContext; } // weak reference
void SetPresShell(nsIPresShell* aPresShell) { mPresShell= aPresShell; } // weak reference
protected: protected:
void DisplayTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle); void DisplayTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
void DisplayHTMLTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle); void DisplayHTMLTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
static PRIntn RemoveItems(PLHashEntry *he, PRIntn i, void *arg); static PRIntn RemoveItems(PLHashEntry *he, PRIntn i, void *arg);
static PRIntn RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg);
void CleanUp(); void CleanUp();
// stdout Output Methods // stdout Output Methods
static PRIntn DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg);
static PRIntn DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg);
void DoGrandTotals(); void DoGrandTotals();
void DoIndiTotalsTree();
// HTML Output Methods // HTML Output Methods
static PRIntn DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg);
@ -262,10 +290,15 @@ protected:
static PRIntn DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg);
PLHashTable * mCounts; PLHashTable * mCounts;
PLHashTable * mIndiFrameCounts;
FILE * mFD; FILE * mFD;
PRBool mCycledOnce; PRBool mCycledOnce;
// Root Frame for Individual Tracking
nsIPresContext * mPresContext;
nsIPresShell* mPresShell;
// ReflowCountMgr gReflowCountMgr; // ReflowCountMgr gReflowCountMgr;
}; };
#endif #endif
@ -953,7 +986,7 @@ public:
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD ClearTotals(); NS_IMETHOD ClearTotals();
NS_IMETHOD DumpReflows(); NS_IMETHOD DumpReflows();
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType); NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame);
#endif #endif
protected: protected:
@ -1210,6 +1243,8 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
mReflowCountMgr = new ReflowCountMgr(); mReflowCountMgr = new ReflowCountMgr();
mReflowCountMgr->SetPresContext(mPresContext);
mReflowCountMgr->SetPresShell(this);
#endif #endif
} }
@ -6003,10 +6038,10 @@ PresShell::DumpReflows()
//------------------------------------------------------------- //-------------------------------------------------------------
NS_IMETHODIMP NS_IMETHODIMP
PresShell::CountReflows(const char * aName, PRUint32 aType) PresShell::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)
{ {
if (mReflowCountMgr) { if (mReflowCountMgr) {
mReflowCountMgr->Add(aName, (nsReflowReason)aType); mReflowCountMgr->Add(aName, (nsReflowReason)aType, aFrame);
} }
return NS_OK; return NS_OK;
} }
@ -6138,6 +6173,8 @@ ReflowCountMgr::ReflowCountMgr()
{ {
mCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, mCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull); PL_CompareValues, nsnull, nsnull);
mIndiFrameCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull);
mCycledOnce = PR_FALSE; mCycledOnce = PR_FALSE;
} }
@ -6162,8 +6199,10 @@ ReflowCounter * ReflowCountMgr::LookUp(const char * aName)
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
void ReflowCountMgr::Add(const char * aName, nsReflowReason aType) void ReflowCountMgr::Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame)
{ {
NS_ASSERTION(aName != nsnull, "Name shouldn't be null!");
if (nsnull != mCounts) { if (nsnull != mCounts) {
ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName); ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName);
if (counter == nsnull) { if (counter == nsnull) {
@ -6175,6 +6214,25 @@ void ReflowCountMgr::Add(const char * aName, nsReflowReason aType)
} }
counter->Add(aType); counter->Add(aType);
} }
if (nsnull != mIndiFrameCounts && aFrame != nsnull) {
char * key = new char[16];
sprintf(key, "%p", aFrame);
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
if (counter == nsnull) {
counter = new IndiReflowCounter(this);
NS_ASSERTION(counter != nsnull, "null ptr");
counter->mFrame = aFrame;
aFrame->GetParent(&counter->mParent);
counter->mName.AssignWithConversion(aName);
PL_HashTableAdd(mIndiFrameCounts, key, counter);
}
// this eliminates extra counts from super classes
if (counter->mName.EqualsWithConversion(aName)) {
counter->mCount++;
counter->mCounter.Add(aType, 1);
}
}
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -6188,13 +6246,27 @@ PRIntn ReflowCountMgr::RemoveItems(PLHashEntry *he, PRIntn i, void *arg)
return HT_ENUMERATE_REMOVE; return HT_ENUMERATE_REMOVE;
} }
//------------------------------------------------------------------
PRIntn ReflowCountMgr::RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg)
{
char *str = (char *)he->key;
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
delete counter;
delete [] str;
return HT_ENUMERATE_REMOVE;
}
//------------------------------------------------------------------ //------------------------------------------------------------------
void ReflowCountMgr::CleanUp() void ReflowCountMgr::CleanUp()
{ {
if (nsnull != mCounts) { if (nsnull != mCounts) {
PL_HashTableEnumerateEntries(mCounts, RemoveItems, nsnull); PL_HashTableEnumerateEntries(mCounts, RemoveItems, nsnull);
PL_HashTableEnumerateEntries(mIndiFrameCounts, RemoveIndiItems, nsnull);
PL_HashTableDestroy(mCounts); PL_HashTableDestroy(mCounts);
PL_HashTableDestroy(mIndiFrameCounts);
mCounts = nsnull; mCounts = nsnull;
mCounts = mIndiFrameCounts;
} }
} }
@ -6236,6 +6308,78 @@ void ReflowCountMgr::DoGrandTotals()
} }
} }
static void RecurseIndiTotals(nsIPresContext* aPresContext,
PLHashTable * aHT,
nsIFrame * aParentFrame,
PRInt32 aLevel)
{
if (aParentFrame == nsnull) {
return;
}
char key[16];
sprintf(key, "%p", aParentFrame);
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(aHT, key);
if (counter) {
counter->mHasBeenOutput = PR_TRUE;
char * name = counter->mName.ToNewCString();
for (PRInt32 i=0;i<aLevel;i++) printf(" ");
printf("%s - %p [%d][", name, aParentFrame, counter->mCount);
for (PRInt32 inx=0;inx<5;inx++) {
if (inx != 0) printf(",");
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
}
printf("]\n");
nsMemory::Free(name);
}
nsIFrame * child;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
while (child) {
RecurseIndiTotals(aPresContext, aHT, child, aLevel+1);
child->GetNextSibling(&child);
}
}
//------------------------------------------------------------------
PRIntn ReflowCountMgr::DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg)
{
char *str = (char *)he->key;
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
if (counter && !counter->mHasBeenOutput) {
char * name = counter->mName.ToNewCString();
printf("%s - %p [%d][", name, counter->mFrame, counter->mCount);
for (PRInt32 inx=0;inx<5;inx++) {
if (inx != 0) printf(",");
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
}
printf("]\n");
nsMemory::Free(name);
}
return HT_ENUMERATE_NEXT;
}
//------------------------------------------------------------------
void ReflowCountMgr::DoIndiTotalsTree()
{
if (nsnull != mCounts) {
printf("\n------------------------------------------------\n");
printf("-- Individual Frame Counts\n");
printf("------------------------------------------------\n");
if (mPresShell) {
nsIFrame * rootFrame;
mPresShell->GetRootFrame(&rootFrame);
RecurseIndiTotals(mPresContext, mIndiFrameCounts, rootFrame, 0);
printf("------------------------------------------------\n");
printf("-- Individual Counts of Frames not in Root Tree\n");
printf("------------------------------------------------\n");
PL_HashTableEnumerateEntries(mIndiFrameCounts, DoSingleIndi, this);
}
}
}
//------------------------------------------------------------------ //------------------------------------------------------------------
PRIntn ReflowCountMgr::DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg) PRIntn ReflowCountMgr::DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg)
{ {
@ -6275,6 +6419,7 @@ void ReflowCountMgr::DisplayTotals(const char * aStr)
{ {
printf("%s\n", aStr?aStr:"No name"); printf("%s\n", aStr?aStr:"No name");
DoGrandTotals(); DoGrandTotals();
DoIndiTotalsTree();
} }
//------------------------------------ //------------------------------------

Просмотреть файл

@ -380,7 +380,7 @@ public:
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
#endif #endif
}; };
@ -403,7 +403,7 @@ extern NS_LAYOUT nsresult
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) \ #define DO_GLOBAL_REFLOW_COUNT(_name, _type) \
aPresContext->CountReflows((_name), (_type)); aPresContext->CountReflows((_name), (_type), (nsIFrame*)this);
#else #else
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) #define DO_GLOBAL_REFLOW_COUNT(_name, _type)
#endif // MOZ_REFLOW_PERF #endif // MOZ_REFLOW_PERF

Просмотреть файл

@ -509,7 +509,7 @@ public:
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD ClearTotals() = 0; NS_IMETHOD ClearTotals() = 0;
NS_IMETHOD DumpReflows() = 0; NS_IMETHOD DumpReflows() = 0;
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
#endif #endif
}; };

Просмотреть файл

@ -380,7 +380,7 @@ public:
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0;
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame) = 0;
#endif #endif
}; };
@ -403,7 +403,7 @@ extern NS_LAYOUT nsresult
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) \ #define DO_GLOBAL_REFLOW_COUNT(_name, _type) \
aPresContext->CountReflows((_name), (_type)); aPresContext->CountReflows((_name), (_type), (nsIFrame*)this);
#else #else
#define DO_GLOBAL_REFLOW_COUNT(_name, _type) #define DO_GLOBAL_REFLOW_COUNT(_name, _type)
#endif // MOZ_REFLOW_PERF #endif // MOZ_REFLOW_PERF

Просмотреть файл

@ -1333,10 +1333,10 @@ nsPresContext::IsRenderingOnlySelection(PRBool* aResult)
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHODIMP NS_IMETHODIMP
nsPresContext::CountReflows(const char * aName, PRUint32 aType) nsPresContext::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)
{ {
if (mShell) { if (mShell) {
mShell->CountReflows(aName, aType); mShell->CountReflows(aName, aType, aFrame);
} }
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -160,7 +160,7 @@ public:
NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult); NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult);
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType); NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame);
#endif #endif
// nsIObserver method // nsIObserver method

Просмотреть файл

@ -194,8 +194,7 @@ static const char * kGrandTotalsStr = "Grand Totals";
// Counting Class // Counting Class
class ReflowCounter { class ReflowCounter {
public: public:
ReflowCounter() { mMgr = nsnull; } ReflowCounter(ReflowCountMgr * aMgr = nsnull);
ReflowCounter(ReflowCountMgr * aMgr);
~ReflowCounter(); ~ReflowCounter();
void ClearTotals(); void ClearTotals();
@ -211,6 +210,8 @@ public:
void SetMgr(ReflowCountMgr * aMgr) { mMgr = aMgr; } void SetMgr(ReflowCountMgr * aMgr) { mMgr = aMgr; }
PRUint32 GetTotalByType(nsReflowReason aType) { if (aType >= eReflowReason_Initial && aType <= eReflowReason_Dirty) return mTotals[aType]; else return 0; }
protected: protected:
void DisplayTotals(PRUint32 * aArray, const char * aTitle); void DisplayTotals(PRUint32 * aArray, const char * aTitle);
void DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle); void DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle);
@ -221,6 +222,24 @@ protected:
ReflowCountMgr * mMgr; ReflowCountMgr * mMgr;
}; };
// Counting Class
class IndiReflowCounter {
public:
IndiReflowCounter(ReflowCountMgr * aMgr = nsnull):mMgr(aMgr),mCounter(aMgr),mFrame(nsnull),mParent(nsnull), mCount(0), mHasBeenOutput(PR_FALSE) {}
virtual ~IndiReflowCounter() {}
nsAutoString mName;
nsIFrame * mFrame;
nsIFrame * mParent;
PRInt32 mCount;
ReflowCountMgr * mMgr;
ReflowCounter mCounter;
PRBool mHasBeenOutput;
};
// Manager Class // Manager Class
class ReflowCountMgr { class ReflowCountMgr {
public: public:
@ -235,21 +254,30 @@ public:
void DisplayHTMLTotals(const char * aStr); void DisplayHTMLTotals(const char * aStr);
void DisplayDiffsInTotals(const char * aStr); void DisplayDiffsInTotals(const char * aStr);
void Add(const char * aName, nsReflowReason aType); void Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame);
ReflowCounter * LookUp(const char * aName); ReflowCounter * LookUp(const char * aName);
FILE * GetOutFile() { return mFD; } FILE * GetOutFile() { return mFD; }
PLHashTable * GetIndiFrameHT() { return mIndiFrameCounts; }
void SetPresContext(nsIPresContext * aPresContext) { mPresContext = aPresContext; } // weak reference
void SetPresShell(nsIPresShell* aPresShell) { mPresShell= aPresShell; } // weak reference
protected: protected:
void DisplayTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle); void DisplayTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
void DisplayHTMLTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle); void DisplayHTMLTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
static PRIntn RemoveItems(PLHashEntry *he, PRIntn i, void *arg); static PRIntn RemoveItems(PLHashEntry *he, PRIntn i, void *arg);
static PRIntn RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg);
void CleanUp(); void CleanUp();
// stdout Output Methods // stdout Output Methods
static PRIntn DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg);
static PRIntn DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg);
void DoGrandTotals(); void DoGrandTotals();
void DoIndiTotalsTree();
// HTML Output Methods // HTML Output Methods
static PRIntn DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg);
@ -262,10 +290,15 @@ protected:
static PRIntn DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg); static PRIntn DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg);
PLHashTable * mCounts; PLHashTable * mCounts;
PLHashTable * mIndiFrameCounts;
FILE * mFD; FILE * mFD;
PRBool mCycledOnce; PRBool mCycledOnce;
// Root Frame for Individual Tracking
nsIPresContext * mPresContext;
nsIPresShell* mPresShell;
// ReflowCountMgr gReflowCountMgr; // ReflowCountMgr gReflowCountMgr;
}; };
#endif #endif
@ -953,7 +986,7 @@ public:
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
NS_IMETHOD ClearTotals(); NS_IMETHOD ClearTotals();
NS_IMETHOD DumpReflows(); NS_IMETHOD DumpReflows();
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType); NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame);
#endif #endif
protected: protected:
@ -1210,6 +1243,8 @@ PresShell::PresShell():mAnonymousContentTable(nsnull),
#ifdef MOZ_REFLOW_PERF #ifdef MOZ_REFLOW_PERF
mReflowCountMgr = new ReflowCountMgr(); mReflowCountMgr = new ReflowCountMgr();
mReflowCountMgr->SetPresContext(mPresContext);
mReflowCountMgr->SetPresShell(this);
#endif #endif
} }
@ -6003,10 +6038,10 @@ PresShell::DumpReflows()
//------------------------------------------------------------- //-------------------------------------------------------------
NS_IMETHODIMP NS_IMETHODIMP
PresShell::CountReflows(const char * aName, PRUint32 aType) PresShell::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)
{ {
if (mReflowCountMgr) { if (mReflowCountMgr) {
mReflowCountMgr->Add(aName, (nsReflowReason)aType); mReflowCountMgr->Add(aName, (nsReflowReason)aType, aFrame);
} }
return NS_OK; return NS_OK;
} }
@ -6138,6 +6173,8 @@ ReflowCountMgr::ReflowCountMgr()
{ {
mCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, mCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull); PL_CompareValues, nsnull, nsnull);
mIndiFrameCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull);
mCycledOnce = PR_FALSE; mCycledOnce = PR_FALSE;
} }
@ -6162,8 +6199,10 @@ ReflowCounter * ReflowCountMgr::LookUp(const char * aName)
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
void ReflowCountMgr::Add(const char * aName, nsReflowReason aType) void ReflowCountMgr::Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame)
{ {
NS_ASSERTION(aName != nsnull, "Name shouldn't be null!");
if (nsnull != mCounts) { if (nsnull != mCounts) {
ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName); ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName);
if (counter == nsnull) { if (counter == nsnull) {
@ -6175,6 +6214,25 @@ void ReflowCountMgr::Add(const char * aName, nsReflowReason aType)
} }
counter->Add(aType); counter->Add(aType);
} }
if (nsnull != mIndiFrameCounts && aFrame != nsnull) {
char * key = new char[16];
sprintf(key, "%p", aFrame);
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
if (counter == nsnull) {
counter = new IndiReflowCounter(this);
NS_ASSERTION(counter != nsnull, "null ptr");
counter->mFrame = aFrame;
aFrame->GetParent(&counter->mParent);
counter->mName.AssignWithConversion(aName);
PL_HashTableAdd(mIndiFrameCounts, key, counter);
}
// this eliminates extra counts from super classes
if (counter->mName.EqualsWithConversion(aName)) {
counter->mCount++;
counter->mCounter.Add(aType, 1);
}
}
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -6188,13 +6246,27 @@ PRIntn ReflowCountMgr::RemoveItems(PLHashEntry *he, PRIntn i, void *arg)
return HT_ENUMERATE_REMOVE; return HT_ENUMERATE_REMOVE;
} }
//------------------------------------------------------------------
PRIntn ReflowCountMgr::RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg)
{
char *str = (char *)he->key;
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
delete counter;
delete [] str;
return HT_ENUMERATE_REMOVE;
}
//------------------------------------------------------------------ //------------------------------------------------------------------
void ReflowCountMgr::CleanUp() void ReflowCountMgr::CleanUp()
{ {
if (nsnull != mCounts) { if (nsnull != mCounts) {
PL_HashTableEnumerateEntries(mCounts, RemoveItems, nsnull); PL_HashTableEnumerateEntries(mCounts, RemoveItems, nsnull);
PL_HashTableEnumerateEntries(mIndiFrameCounts, RemoveIndiItems, nsnull);
PL_HashTableDestroy(mCounts); PL_HashTableDestroy(mCounts);
PL_HashTableDestroy(mIndiFrameCounts);
mCounts = nsnull; mCounts = nsnull;
mCounts = mIndiFrameCounts;
} }
} }
@ -6236,6 +6308,78 @@ void ReflowCountMgr::DoGrandTotals()
} }
} }
static void RecurseIndiTotals(nsIPresContext* aPresContext,
PLHashTable * aHT,
nsIFrame * aParentFrame,
PRInt32 aLevel)
{
if (aParentFrame == nsnull) {
return;
}
char key[16];
sprintf(key, "%p", aParentFrame);
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(aHT, key);
if (counter) {
counter->mHasBeenOutput = PR_TRUE;
char * name = counter->mName.ToNewCString();
for (PRInt32 i=0;i<aLevel;i++) printf(" ");
printf("%s - %p [%d][", name, aParentFrame, counter->mCount);
for (PRInt32 inx=0;inx<5;inx++) {
if (inx != 0) printf(",");
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
}
printf("]\n");
nsMemory::Free(name);
}
nsIFrame * child;
aParentFrame->FirstChild(aPresContext, nsnull, &child);
while (child) {
RecurseIndiTotals(aPresContext, aHT, child, aLevel+1);
child->GetNextSibling(&child);
}
}
//------------------------------------------------------------------
PRIntn ReflowCountMgr::DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg)
{
char *str = (char *)he->key;
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
if (counter && !counter->mHasBeenOutput) {
char * name = counter->mName.ToNewCString();
printf("%s - %p [%d][", name, counter->mFrame, counter->mCount);
for (PRInt32 inx=0;inx<5;inx++) {
if (inx != 0) printf(",");
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
}
printf("]\n");
nsMemory::Free(name);
}
return HT_ENUMERATE_NEXT;
}
//------------------------------------------------------------------
void ReflowCountMgr::DoIndiTotalsTree()
{
if (nsnull != mCounts) {
printf("\n------------------------------------------------\n");
printf("-- Individual Frame Counts\n");
printf("------------------------------------------------\n");
if (mPresShell) {
nsIFrame * rootFrame;
mPresShell->GetRootFrame(&rootFrame);
RecurseIndiTotals(mPresContext, mIndiFrameCounts, rootFrame, 0);
printf("------------------------------------------------\n");
printf("-- Individual Counts of Frames not in Root Tree\n");
printf("------------------------------------------------\n");
PL_HashTableEnumerateEntries(mIndiFrameCounts, DoSingleIndi, this);
}
}
}
//------------------------------------------------------------------ //------------------------------------------------------------------
PRIntn ReflowCountMgr::DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg) PRIntn ReflowCountMgr::DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg)
{ {
@ -6275,6 +6419,7 @@ void ReflowCountMgr::DisplayTotals(const char * aStr)
{ {
printf("%s\n", aStr?aStr:"No name"); printf("%s\n", aStr?aStr:"No name");
DoGrandTotals(); DoGrandTotals();
DoIndiTotalsTree();
} }
//------------------------------------ //------------------------------------