Bug 730181 (part 1) - Merge the "dom+style" and "layout" memory reporter trees. r=khuey.

--HG--
extra : rebase_source : dabcf525d823639c5ff465c7a21de8ae533e82ff
This commit is contained in:
Nicholas Nethercote 2012-02-21 07:10:11 -08:00
parent c95a36849d
commit fa887ff20c
7 changed files with 124 additions and 215 deletions

View File

@ -9149,6 +9149,13 @@ nsIDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
aWindowSizes->mDOM +=
nsINode::SizeOfExcludingThis(aWindowSizes->mMallocSizeOf);
if (mPresShell) {
mPresShell->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf,
&aWindowSizes->mLayoutArenas,
&aWindowSizes->mLayoutStyleSets,
&aWindowSizes->mLayoutTextRuns);
}
// Measurement of the following members may be added later if DMD finds it
// is worthwhile:
// - many!

View File

@ -88,18 +88,11 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
return true;
}
struct WindowTotals
{
WindowTotals() : mDom(0), mStyleSheets(0) {}
size_t mDom;
size_t mStyleSheets;
};
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "dom+style")
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
static void
CollectWindowReports(nsGlobalWindow *aWindow,
WindowTotals *aWindowTotals,
nsWindowSizes *aWindowTotalSizes,
nsIMemoryMultiReporterCallback *aCb,
nsISupports *aClosure)
{
@ -126,7 +119,7 @@ CollectWindowReports(nsGlobalWindow *aWindow,
// The path we give to the reporter callback for inner windows are
// as follows:
//
// explicit/dom+style/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
// explicit/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
//
// Where:
// - <category> is active, cached, or other, as described above.
@ -145,12 +138,12 @@ CollectWindowReports(nsGlobalWindow *aWindow,
//
// For outer windows we simply use:
//
// explicit/dom+style/window-objects/<category>/outer-windows
// explicit/window-objects/<category>/outer-windows
//
// Which gives us simple counts of how many outer windows (and their
// combined sizes) per category.
nsCAutoString windowPath("explicit/dom+style/window-objects/");
nsCAutoString windowPath("explicit/window-objects/");
nsIDocShell *docShell = aWindow->GetDocShell();
@ -199,28 +192,40 @@ CollectWindowReports(nsGlobalWindow *aWindow,
windowPath += NS_LITERAL_CSTRING("outer-windows");
}
if (windowSizes.mDOM > 0) {
nsCAutoString domPath(windowPath);
domPath += "/dom";
NS_NAMED_LITERAL_CSTRING(kWindowDesc,
"Memory used by a window and the DOM within it.");
aCb->Callback(EmptyCString(), domPath, nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, windowSizes.mDOM,
kWindowDesc, aClosure);
aWindowTotals->mDom += windowSizes.mDOM;
}
#define REPORT(_path1, _path2, _amount, _desc) \
do { \
if (_amount > 0) { \
nsCAutoString path(_path1); \
path += _path2; \
aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP, \
nsIMemoryReporter::UNITS_BYTES, _amount, \
NS_LITERAL_CSTRING(_desc), aClosure); \
} \
} while (0)
if (windowSizes.mStyleSheets > 0) {
nsCAutoString styleSheetsPath(windowPath);
styleSheetsPath += "/style-sheets";
NS_NAMED_LITERAL_CSTRING(kStyleSheetsDesc,
"Memory used by style sheets within a window.");
aCb->Callback(EmptyCString(), styleSheetsPath,
nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, windowSizes.mStyleSheets,
kStyleSheetsDesc, aClosure);
aWindowTotals->mStyleSheets += windowSizes.mStyleSheets;
}
REPORT(windowPath, "/dom", windowSizes.mDOM,
"Memory used by a window and the DOM within it.");
aWindowTotalSizes->mDOM += windowSizes.mDOM;
REPORT(windowPath, "/style-sheets", windowSizes.mStyleSheets,
"Memory used by style sheets within a window.");
aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
REPORT(windowPath, "/layout/arenas", windowSizes.mLayoutArenas,
"Memory used by layout PresShell, PresContext, and other related "
"areas within a window.");
aWindowTotalSizes->mLayoutArenas += windowSizes.mLayoutArenas;
REPORT(windowPath, "/layout/style-sets", windowSizes.mLayoutStyleSets,
"Memory used by style sets within a window.");
aWindowTotalSizes->mLayoutStyleSets += windowSizes.mLayoutStyleSets;
REPORT(windowPath, "/layout/text-runs", windowSizes.mLayoutTextRuns,
"Memory used for text-runs (glyph layout) in the PresShell's frame "
"tree, within a window.");
aWindowTotalSizes->mLayoutTextRuns += windowSizes.mLayoutTextRuns;
#undef REPORT
}
typedef nsTArray< nsRefPtr<nsGlobalWindow> > WindowArray;
@ -237,7 +242,7 @@ GetWindows(const PRUint64& aId, nsGlobalWindow*& aWindow, void* aClosure)
NS_IMETHODIMP
nsDOMMemoryMultiReporter::GetName(nsACString &aName)
{
aName.AssignLiteral("dom+style");
aName.AssignLiteral("window-objects");
return NS_OK;
}
@ -257,27 +262,42 @@ nsDOMMemoryMultiReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
// Collect window memory usage.
nsRefPtr<nsGlobalWindow> *w = windows.Elements();
nsRefPtr<nsGlobalWindow> *end = w + windows.Length();
WindowTotals windowTotals;
nsWindowSizes windowTotalSizes(NULL);
for (; w != end; ++w) {
CollectWindowReports(*w, &windowTotals, aCb, aClosure);
CollectWindowReports(*w, &windowTotalSizes, aCb, aClosure);
}
NS_NAMED_LITERAL_CSTRING(kDomTotalWindowsDesc,
"Memory used for the DOM within windows. This is the sum of all windows' "
"'dom' numbers.");
aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("dom-total-window"),
nsIMemoryReporter::KIND_OTHER,
nsIMemoryReporter::UNITS_BYTES, windowTotals.mDom,
kDomTotalWindowsDesc, aClosure);
#define REPORT(_path, _amount, _desc) \
do { \
aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
nsIMemoryReporter::KIND_OTHER, \
nsIMemoryReporter::UNITS_BYTES, _amount, \
NS_LITERAL_CSTRING(_desc), aClosure); \
} while (0)
NS_NAMED_LITERAL_CSTRING(kLayoutTotalWindowStyleSheetsDesc,
"Memory used for style sheets within windows. This is the sum of all windows' "
"'style-sheets' numbers.");
aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING("style-sheets-total-window"),
nsIMemoryReporter::KIND_OTHER,
nsIMemoryReporter::UNITS_BYTES, windowTotals.mStyleSheets,
kLayoutTotalWindowStyleSheetsDesc, aClosure);
REPORT("window-objects-dom", windowTotalSizes.mDOM,
"Memory used for the DOM within windows. "
"This is the sum of all windows' 'dom' numbers.");
REPORT("window-objects-style-sheets", windowTotalSizes.mStyleSheets,
"Memory used for style sheets within windows. "
"This is the sum of all windows' 'style-sheets' numbers.");
REPORT("window-objects-layout-arenas", windowTotalSizes.mLayoutArenas,
"Memory used by layout PresShell, PresContext, and other related "
"areas within windows. This is the sum of all windows' "
"'layout/arenas' numbers.");
REPORT("window-objects-layout-style-sets", windowTotalSizes.mLayoutStyleSets,
"Memory used for style sets within windows. "
"This is the sum of all windows' 'layout/style-sets' numbers.");
REPORT("window-objects-layout-text-runs", windowTotalSizes.mLayoutTextRuns,
"Memory used for text runs within windows. "
"This is the sum of all windows' 'layout/text-runs' numbers.");
#undef REPORT
return NS_OK;
}

View File

@ -49,14 +49,16 @@
class nsWindowSizes {
public:
nsWindowSizes(nsMallocSizeOfFun aMallocSizeOf)
: mMallocSizeOf(aMallocSizeOf),
mDOM(0),
mStyleSheets(0)
{}
nsWindowSizes(nsMallocSizeOfFun aMallocSizeOf) {
memset(this, 0, sizeof(nsWindowSizes));
mMallocSizeOf = aMallocSizeOf;
}
nsMallocSizeOfFun mMallocSizeOf;
size_t mDOM;
size_t mStyleSheets;
size_t mLayoutArenas;
size_t mLayoutStyleSets;
size_t mLayoutTextRuns;
};
class nsDOMMemoryMultiReporter: public nsIMemoryMultiReporter

View File

@ -144,8 +144,8 @@ typedef struct CapturingContentInfo {
} CapturingContentInfo;
#define NS_IPRESSHELL_IID \
{ 0x87719fd6, 0xe50c, 0x4d72, \
{ 0xbd, 0x55, 0x05, 0xf9, 0x5f, 0x33, 0x9e, 0xf2 } }
{ 0x4dc4db09, 0x03d4, 0x4427, \
{ 0xbe, 0xfb, 0xc9, 0x29, 0xac, 0x5c, 0x62, 0xab } }
// Constants for ScrollContentIntoView() function
#define NS_PRESSHELL_SCROLL_TOP 0
@ -1176,6 +1176,11 @@ public:
virtual bool IsVisible() = 0;
virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
size_t *aArenasSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize) const = 0;
/**
* Refresh observer management.
*/
@ -1283,10 +1288,6 @@ protected:
float mXResolution;
float mYResolution;
// Live pres shells, for memory and other tracking
typedef nsPtrHashKey<nsIPresShell> PresShellPtrKey;
static nsTHashtable<PresShellPtrKey> *sLiveShells;
static nsIContent* gKeyDownTarget;
};

View File

@ -201,9 +201,6 @@
#include "imgIEncoder.h"
#include "gfxPlatform.h"
/* for NS_MEMORY_REPORTER_IMPLEMENT */
#include "nsIMemoryReporter.h"
#include "mozilla/FunctionTimer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
@ -608,113 +605,6 @@ struct nsCallbackEventRequest
GetPresContext()->RefreshDriver()-> \
IsLayoutFlushObserver(this), "Unexpected state")
NS_IMPL_ISUPPORTS1(PresShell::MemoryReporter, nsIMemoryMultiReporter)
namespace {
struct MemoryReporterData
{
nsIMemoryMultiReporterCallback* callback;
nsISupports* closure;
};
} // anonymous namespace
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutMallocSizeOf, "layout")
/* static */ PLDHashOperator
PresShell::MemoryReporter::SizeEnumerator(PresShellPtrKey *aEntry,
void *userArg)
{
PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey());
MemoryReporterData *data = (MemoryReporterData*)userArg;
// Build the string "explicit/layout/shell(<uri of the document>)"
nsCAutoString str("explicit/layout/shell(");
nsIDocument* doc = aShell->GetDocument();
if (doc) {
nsIURI* docURI = doc->GetDocumentURI();
if (docURI) {
nsCString spec;
docURI->GetSpec(spec);
// A hack: replace forward slashes with '\\' so they aren't
// treated as path separators. Users of the reporters
// (such as about:memory) have to undo this change.
spec.ReplaceChar('/', '\\');
str += spec;
}
}
str += NS_LITERAL_CSTRING(")");
NS_NAMED_LITERAL_CSTRING(kArenaDesc, "Memory used by layout PresShell, PresContext, and other related areas.");
NS_NAMED_LITERAL_CSTRING(kStyleDesc, "Memory used by the style system.");
NS_NAMED_LITERAL_CSTRING(kTextRunsDesc, "Memory used for text-runs (glyph layout) in the PresShell's frame tree.");
nsCAutoString arenaPath = str + NS_LITERAL_CSTRING("/arenas");
nsCAutoString stylePath = str + NS_LITERAL_CSTRING("/styledata");
nsCAutoString textRunsPath = str + NS_LITERAL_CSTRING("/textruns");
PRInt64 arenasSize =
aShell->SizeOfIncludingThis(LayoutMallocSizeOf) +
aShell->mPresContext->SizeOfIncludingThis(LayoutMallocSizeOf);
PRInt64 styleSize =
aShell->StyleSet()->SizeOfIncludingThis(LayoutMallocSizeOf);
PRInt64 textRunsSize = aShell->SizeOfTextRuns(LayoutMallocSizeOf);
data->callback->
Callback(EmptyCString(), arenaPath, nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, arenasSize, kArenaDesc,
data->closure);
data->callback->
Callback(EmptyCString(), stylePath, nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, styleSize, kStyleDesc,
data->closure);
if (textRunsSize) {
data->callback->
Callback(EmptyCString(), textRunsPath, nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, textRunsSize, kTextRunsDesc,
data->closure);
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
PresShell::MemoryReporter::GetName(nsACString &aName)
{
aName.AssignLiteral("layout");
return NS_OK;
}
NS_IMETHODIMP
PresShell::MemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
nsISupports* aClosure)
{
MemoryReporterData data;
data.callback = aCb;
data.closure = aClosure;
sLiveShells->EnumerateEntries(SizeEnumerator, &data);
return NS_OK;
}
NS_IMETHODIMP
PresShell::MemoryReporter::GetExplicitNonHeap(PRInt64 *aAmount) {
// This reporter doesn't do any KIND_NONHEAP measurements.
*aAmount = 0;
return NS_OK;
}
class nsAutoCauseReflowNotifier
{
public:
@ -915,7 +805,6 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult)
return NS_OK;
}
nsTHashtable<PresShell::PresShellPtrKey> *nsIPresShell::sLiveShells = 0;
static bool sSynthMouseMove = true;
PresShell::PresShell()
@ -943,15 +832,12 @@ PresShell::PresShell()
mYResolution = 1.0;
mViewportOverridden = false;
static bool registeredReporter = false;
if (!registeredReporter) {
NS_RegisterMemoryMultiReporter(new MemoryReporter);
static bool addedSynthMouseMove = false;
if (!addedSynthMouseMove) {
Preferences::AddBoolVarCache(&sSynthMouseMove,
"layout.reflow.synthMouseMove", true);
registeredReporter = true;
addedSynthMouseMove = true;
}
sLiveShells->PutEntry(this);
}
NS_IMPL_ISUPPORTS7(PresShell, nsIPresShell, nsIDocumentObserver,
@ -961,8 +847,6 @@ NS_IMPL_ISUPPORTS7(PresShell, nsIPresShell, nsIDocumentObserver,
PresShell::~PresShell()
{
sLiveShells->RemoveEntry(this);
if (!mHaveShutDown) {
NS_NOTREACHED("Someone did not call nsIPresShell::destroy");
Destroy();
@ -9085,19 +8969,18 @@ nsIPresShell::AccService()
}
#endif
static bool inited = false;
void nsIPresShell::InitializeStatics()
{
NS_ASSERTION(sLiveShells == nsnull, "InitializeStatics called multiple times!");
sLiveShells = new nsTHashtable<PresShellPtrKey>();
sLiveShells->Init();
NS_ASSERTION(!inited, "InitializeStatics called multiple times!");
gCaptureTouchList.Init();
inited = true;
}
void nsIPresShell::ReleaseStatics()
{
NS_ASSERTION(sLiveShells, "ReleaseStatics called without Initialize!");
delete sLiveShells;
sLiveShells = nsnull;
NS_ASSERTION(inited, "ReleaseStatics called without Initialize!");
}
// Asks our docshell whether we're active.
@ -9203,8 +9086,23 @@ PresShell::GetRootPresShell()
return nsnull;
}
void
PresShell::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
size_t *aArenasSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize) const
{
*aArenasSize = aMallocSizeOf(this);
*aArenasSize += mStackArena.SizeOfExcludingThis(aMallocSizeOf);
*aArenasSize += mFrameArena.SizeOfExcludingThis(aMallocSizeOf);
*aStyleSetsSize = StyleSet()->SizeOfIncludingThis(aMallocSizeOf);
*aTextRunsSize = SizeOfTextRuns(aMallocSizeOf);
}
size_t
PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf)
PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const
{
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (!rootFrame) {

View File

@ -901,26 +901,11 @@ private:
public:
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
size_t n = 0;
n += aMallocSizeOf(this);
n += mStackArena.SizeOfExcludingThis(aMallocSizeOf);
n += mFrameArena.SizeOfExcludingThis(aMallocSizeOf);
return n;
}
size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf);
class MemoryReporter : public nsIMemoryMultiReporter
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMEMORYMULTIREPORTER
protected:
static PLDHashOperator SizeEnumerator(PresShellPtrKey *aEntry, void *userArg);
};
void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
size_t *aArenasSize,
size_t *aStyleSetsSize,
size_t *aTextRunsSize) const;
size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const;
protected:
void QueryIsActive();

View File

@ -44,8 +44,7 @@
let areJsCompartmentsPresent = false;
let isSandboxLocationShown = false;
let areLayoutShellsPresent = false;
let areDomInnerWindowsPresent = false;
let areInnerWindowsPresent = false;
let isPlacesPresent = false;
let isImagesPresent = false;
let isXptiWorkingSetPresent = false;
@ -73,10 +72,8 @@
// Check the presence of some other notable reporters.
} else if (aPath.search(/^explicit\/js\/compartment\(/) >= 0) {
areJsCompartmentsPresent = true;
} else if (aPath.search(/^explicit\/layout\/shell\(/) >= 0) {
areLayoutShellsPresent = true;
} else if (aPath.search(/^explicit\/dom\+style\/window-objects\/.*inner-window\(/) >= 0) {
areDomInnerWindowsPresent = true;
} else if (aPath.search(/^explicit\/window-objects\/.*inner-window\(/) >= 0) {
areInnerWindowsPresent = true;
} else if (aPath.search(/^explicit\/storage\/sqlite\/places.sqlite/) >= 0) {
isPlacesPresent = true;
} else if (aPath.search(/^explicit\/images/) >= 0) {
@ -134,8 +131,7 @@
ok(areJsCompartmentsPresent, "js compartments are present");
ok(isSandboxLocationShown, "sandbox locations are present");
ok(areLayoutShellsPresent, "layout shells are present");
ok(areDomInnerWindowsPresent, "dom inner-windows are present");
ok(areInnerWindowsPresent, "inner-windows are present");
ok(isPlacesPresent, "places is present");
ok(isImagesPresent, "images is present");
ok(isXptiWorkingSetPresent, "xpti-working-set is present");