зеркало из https://github.com/mozilla/gecko-dev.git
Bug 713799 - Rearrange the "window-objects" sub-tree in about:memory to make per-tab memory usage more obvious. r=jst.
--HG-- extra : rebase_source : f4e9407ad9a5c20ae8523d2ec087b4ee99c43877
This commit is contained in:
Родитель
f564b11cf6
Коммит
feb306dd5d
|
@ -53,7 +53,7 @@ nsWindowMemoryReporter::Init()
|
|||
NS_RegisterMemoryMultiReporter(new nsWindowMemoryReporter());
|
||||
}
|
||||
|
||||
static bool
|
||||
static void
|
||||
AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
|
||||
|
@ -71,21 +71,19 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
|
|||
}
|
||||
}
|
||||
|
||||
if (!uri) {
|
||||
return false;
|
||||
if (uri) {
|
||||
nsCString spec;
|
||||
uri->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('/', '\\');
|
||||
|
||||
aStr += spec;
|
||||
} else {
|
||||
aStr += NS_LITERAL_CSTRING("[system]");
|
||||
}
|
||||
|
||||
nsCString spec;
|
||||
uri->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('/', '\\');
|
||||
|
||||
aStr += spec;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
|
||||
|
@ -104,99 +102,68 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
|||
// cached) yet held alive by either a website or our code. The
|
||||
// latter case may be a memory leak, but not necessarily.
|
||||
//
|
||||
// For inner windows we show how much memory the window and its
|
||||
// document etc use, and we report those per URI, where the URI is
|
||||
// the document URI, if available, or the codebase of the principal
|
||||
// in the window. In the case where we're unable to find a URI we're
|
||||
// dealing with a chrome window with no document in it (or
|
||||
// somesuch), and for that we make the URI be the string "[system]".
|
||||
// For each window we show how much memory the window and its
|
||||
// document, etc, use, and we report those per URI, where the URI is
|
||||
// the document URI, if available, or the codebase of the principal in
|
||||
// the window. In the case where we're unable to find a URI we're
|
||||
// dealing with a chrome window with no document in it (or somesuch),
|
||||
// and for that we make the URI be the string "[system]".
|
||||
//
|
||||
// For outer windows we simply group them all together and just show
|
||||
// the combined count and amount of memory used, which is generally
|
||||
// a constant amount per window (since all the actual data lives in
|
||||
// the inner window).
|
||||
// Outer windows are lumped in with inner windows, because the amount
|
||||
// of memory used by outer windows is small.
|
||||
//
|
||||
// The path we give to the reporter callback for inner windows are
|
||||
// as follows:
|
||||
// The path we give to the reporter callback for "active" and "cached"
|
||||
// windows (both inner and outer) is as follows:
|
||||
//
|
||||
// explicit/window-objects/<category>/top=<top-outer-id> (inner=<top-inner-id>)/inner-window(id=<id>, uri=<uri>)
|
||||
// explicit/window-objects/top(<top-outer-uri>, id=<top-outer-id>)/<category>/window(<window-uri>)/...
|
||||
//
|
||||
// The path we give for "other" windows is as follows:
|
||||
//
|
||||
// explicit/window-objects/top(none)/window(<window-uri>)/...
|
||||
//
|
||||
// Where:
|
||||
// - <category> is active, cached, or other, as described above.
|
||||
// - <category> is "active" or "cached", as described above.
|
||||
// - <top-outer-id> is the window id (nsPIDOMWindow::WindowID()) of
|
||||
// the top outer window (i.e. tab, or top level chrome window).
|
||||
// - <top-inner-id> is the window id of the top window's inner
|
||||
// window.
|
||||
// - <id> is the window id of the inner window in question.
|
||||
// - <uri> is the URI per above description.
|
||||
// - <top-inner-uri> is the URI of the top outer window. Excepting
|
||||
// special windows (such as browser.xul or hiddenWindow.html) it's
|
||||
// what the address bar shows for the tab.
|
||||
// - <window-uri> is the URI of aWindow.
|
||||
//
|
||||
// Exposing the window ids is done to get logical grouping in
|
||||
// about:memory, and also for debuggability since one can get to the
|
||||
// nsGlobalWindow for a window id by calling the static method
|
||||
// nsGlobalWindow::GetInnerWindowWithId(id) (or
|
||||
// GetOuterWindowWithId(id) in a debugger.
|
||||
//
|
||||
// For outer windows we simply use:
|
||||
//
|
||||
// explicit/window-objects/<category>/outer-windows
|
||||
//
|
||||
// Which gives us simple counts of how many outer windows (and their
|
||||
// combined sizes) per category.
|
||||
// Exposing the top-outer-id ensures that each tab gets its own
|
||||
// sub-tree, even if multiple tabs are showing the same URI.
|
||||
|
||||
nsCAutoString windowPath("explicit/window-objects/");
|
||||
|
||||
nsIDocShell *docShell = aWindow->GetDocShell();
|
||||
|
||||
nsGlobalWindow *top = aWindow->GetTop();
|
||||
nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
|
||||
aWindow->SizeOfIncludingThis(&windowSizes);
|
||||
|
||||
if (docShell && aWindow->IsFrozen()) {
|
||||
windowPath += NS_LITERAL_CSTRING("cached/");
|
||||
} else if (docShell) {
|
||||
windowPath += NS_LITERAL_CSTRING("active/");
|
||||
windowPath += NS_LITERAL_CSTRING("top(");
|
||||
if (top) {
|
||||
AppendWindowURI(top, windowPath);
|
||||
windowPath += NS_LITERAL_CSTRING(", id=");
|
||||
windowPath.AppendInt(top->WindowID());
|
||||
} else {
|
||||
windowPath += NS_LITERAL_CSTRING("other/");
|
||||
windowPath += NS_LITERAL_CSTRING("none");
|
||||
}
|
||||
windowPath += NS_LITERAL_CSTRING(")/");
|
||||
|
||||
nsIDocShell *docShell = aWindow->GetDocShell();
|
||||
if (docShell) {
|
||||
MOZ_ASSERT(top, "'cached' or 'active' window lacks a top window");
|
||||
windowPath += aWindow->IsFrozen() ? NS_LITERAL_CSTRING("cached/")
|
||||
: NS_LITERAL_CSTRING("active/");
|
||||
} else {
|
||||
MOZ_ASSERT(!top, "'other' window has a top window");
|
||||
}
|
||||
|
||||
if (aWindow->IsInnerWindow()) {
|
||||
windowPath += NS_LITERAL_CSTRING("top=");
|
||||
windowPath += NS_LITERAL_CSTRING("window(");
|
||||
AppendWindowURI(aWindow, windowPath);
|
||||
windowPath += NS_LITERAL_CSTRING(")");
|
||||
|
||||
if (top) {
|
||||
windowPath.AppendInt(top->WindowID());
|
||||
|
||||
nsGlobalWindow *topInner = top->GetCurrentInnerWindowInternal();
|
||||
if (topInner) {
|
||||
windowPath += NS_LITERAL_CSTRING(" (inner=");
|
||||
windowPath.AppendInt(topInner->WindowID());
|
||||
windowPath += NS_LITERAL_CSTRING(")");
|
||||
}
|
||||
} else {
|
||||
windowPath += NS_LITERAL_CSTRING("none");
|
||||
}
|
||||
|
||||
windowPath += NS_LITERAL_CSTRING("/inner-window(id=");
|
||||
windowPath.AppendInt(aWindow->WindowID());
|
||||
windowPath += NS_LITERAL_CSTRING(", uri=");
|
||||
|
||||
if (!AppendWindowURI(aWindow, windowPath)) {
|
||||
windowPath += NS_LITERAL_CSTRING("[system]");
|
||||
}
|
||||
|
||||
windowPath += NS_LITERAL_CSTRING(")");
|
||||
} else {
|
||||
// Combine all outer windows per section (active/cached/other) as
|
||||
// they basically never contain anything of interest, and are
|
||||
// always pretty much the same size.
|
||||
|
||||
windowPath += NS_LITERAL_CSTRING("outer-windows");
|
||||
}
|
||||
|
||||
#define REPORT(_path1, _path2, _amount, _desc) \
|
||||
#define REPORT(_pathTail, _amount, _desc) \
|
||||
do { \
|
||||
if (_amount > 0) { \
|
||||
nsCAutoString path(_path1); \
|
||||
path += _path2; \
|
||||
nsCAutoString path(windowPath); \
|
||||
path += _pathTail; \
|
||||
nsresult rv; \
|
||||
rv = aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP,\
|
||||
nsIMemoryReporter::UNITS_BYTES, _amount, \
|
||||
|
@ -205,24 +172,27 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
REPORT(windowPath, "/dom", windowSizes.mDOM,
|
||||
nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
|
||||
aWindow->SizeOfIncludingThis(&windowSizes);
|
||||
|
||||
REPORT("/dom", windowSizes.mDOM,
|
||||
"Memory used by a window and the DOM within it.");
|
||||
aWindowTotalSizes->mDOM += windowSizes.mDOM;
|
||||
|
||||
REPORT(windowPath, "/style-sheets", windowSizes.mStyleSheets,
|
||||
REPORT("/style-sheets", windowSizes.mStyleSheets,
|
||||
"Memory used by style sheets within a window.");
|
||||
aWindowTotalSizes->mStyleSheets += windowSizes.mStyleSheets;
|
||||
|
||||
REPORT(windowPath, "/layout/arenas", windowSizes.mLayoutArenas,
|
||||
REPORT("/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,
|
||||
REPORT("/layout/style-sets", windowSizes.mLayoutStyleSets,
|
||||
"Memory used by style sets within a window.");
|
||||
aWindowTotalSizes->mLayoutStyleSets += windowSizes.mLayoutStyleSets;
|
||||
|
||||
REPORT(windowPath, "/layout/text-runs", windowSizes.mLayoutTextRuns,
|
||||
REPORT("/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;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
let areJsCompartmentsPresent = false;
|
||||
let isSandboxLocationShown = false;
|
||||
let areInnerWindowsPresent = false;
|
||||
let areWindowObjectsPresent = false;
|
||||
let isPlacesPresent = false;
|
||||
let isImagesPresent = false;
|
||||
let isXptiWorkingSetPresent = false;
|
||||
|
@ -72,8 +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\/window-objects\/.*inner-window\(/) >= 0) {
|
||||
areInnerWindowsPresent = true;
|
||||
} else if (aPath.search(/^explicit\/window-objects\/top\(/) >= 0) {
|
||||
areWindowObjectsPresent = true;
|
||||
} else if (aPath.search(/^explicit\/storage\/sqlite\/places.sqlite/) >= 0) {
|
||||
isPlacesPresent = true;
|
||||
} else if (aPath.search(/^explicit\/images/) >= 0) {
|
||||
|
@ -131,7 +131,7 @@
|
|||
|
||||
ok(areJsCompartmentsPresent, "js compartments are present");
|
||||
ok(isSandboxLocationShown, "sandbox locations are present");
|
||||
ok(areInnerWindowsPresent, "inner-windows are present");
|
||||
ok(areWindowObjectsPresent, "window objects are present");
|
||||
ok(isPlacesPresent, "places is present");
|
||||
ok(isImagesPresent, "images is present");
|
||||
ok(isXptiWorkingSetPresent, "xpti-working-set is present");
|
||||
|
|
Загрузка…
Ссылка в новой задаче