static void CollectWindowReports(nsGlobalWindow *aWindow, WindowTotals *aWindowTotals, nsIMemoryMultiReporterCallback *aCb, nsISupports *aClosure) { // DOM window objects fall into one of three categories: // - "active" windows are currently either displayed in an active // tab, or a child of such a window. // - "cached" windows are in the fastback cache. // - "other" windows are closed (or navigated away from w/o being // 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 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). // // 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>) // // Where: // - <category> is active, cached, or other, 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. // // 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/dom+style/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/"); nsIDocShell *docShell = aWindow->GetDocShell(); nsGlobalWindow *top = aWindow->GetTop(); PRInt64 windowDOMSize = aWindow->SizeOf(); PRInt64 styleSheetsSize = aWindow->SizeOfStyleSheets(WindowStyleSheetsMallocSizeOf); if (docShell && aWindow->IsFrozen()) { windowPath += NS_LITERAL_CSTRING("cached/"); } else if (docShell) { windowPath += NS_LITERAL_CSTRING("active/"); } else { windowPath += NS_LITERAL_CSTRING("other/"); } if (aWindow->IsInnerWindow()) { windowPath += NS_LITERAL_CSTRING("top="); 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"); } if (windowDOMSize > 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, windowDOMSize, kWindowDesc, aClosure); aWindowTotals->mDom += windowDOMSize; } if (styleSheetsSize > 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, styleSheetsSize, kStyleSheetsDesc, aClosure); aWindowTotals->mStyleSheets += styleSheetsSize; } }
static void CollectWindowReports(nsGlobalWindow *aWindow, nsWindowSizes *aWindowTotalSizes, nsIMemoryMultiReporterCallback *aCb, nsISupports *aClosure) { // DOM window objects fall into one of three categories: // - "active" windows are currently either displayed in an active // tab, or a child of such a window. // - "cached" windows are in the fastback cache. // - "other" windows are closed (or navigated away from w/o being // 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 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). // // The path we give to the reporter callback for inner windows are // as follows: // // 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. // - <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. // // 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. 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/"); } else { windowPath += NS_LITERAL_CSTRING("other/"); } if (aWindow->IsInnerWindow()) { windowPath += NS_LITERAL_CSTRING("top="); 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) \ 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) 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 }