mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 738624 - Add ghost windows to about:compartments. r=njn
--HG-- extra : rebase_source : c16cdfc4c06b363f54f1d0f37bb006cf977b079a
This commit is contained in:
parent
91e6fee1e8
commit
c7747cbafe
@ -58,16 +58,23 @@ NS_IMPL_ISUPPORTS3(nsWindowMemoryReporter, nsIMemoryMultiReporter, nsIObserver,
|
||||
void
|
||||
nsWindowMemoryReporter::Init()
|
||||
{
|
||||
// The memory reporter manager is going to own this object.
|
||||
nsWindowMemoryReporter *reporter = new nsWindowMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(reporter);
|
||||
// The memory reporter manager will own this object.
|
||||
nsWindowMemoryReporter *windowReporter = new nsWindowMemoryReporter();
|
||||
NS_RegisterMemoryMultiReporter(windowReporter);
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
// DOM_WINDOW_DESTROYED_TOPIC announces what we call window "detachment",
|
||||
// when a window's docshell is set to NULL.
|
||||
os->AddObserver(reporter, DOM_WINDOW_DESTROYED_TOPIC, /* weakRef = */ true);
|
||||
os->AddObserver(windowReporter, DOM_WINDOW_DESTROYED_TOPIC,
|
||||
/* weakRef = */ true);
|
||||
os->AddObserver(windowReporter, "after-minimize-memory-usage",
|
||||
/* weakRef = */ true);
|
||||
}
|
||||
|
||||
nsGhostWindowMemoryReporter *ghostReporter =
|
||||
new nsGhostWindowMemoryReporter(windowReporter);
|
||||
NS_RegisterMemoryMultiReporter(ghostReporter);
|
||||
}
|
||||
|
||||
static already_AddRefed<nsIURI>
|
||||
@ -296,17 +303,29 @@ nsWindowMemoryReporter::GetExplicitNonHeap(PRInt64* aAmount)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsWindowMemoryReporter::GetGhostTimeout()
|
||||
{
|
||||
return Preferences::GetUint("memory.ghost_window_timeout_seconds", 60);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
// A window was detached. Insert it into mDetachedWindows and run
|
||||
// CheckForGhostWindows sometime soon.
|
||||
if (!strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC)) {
|
||||
ObserveDOMWindowDetached(aSubject);
|
||||
} else if (!strcmp(aTopic, "after-minimize-memory-usage")) {
|
||||
ObserveAfterMinimizeMemoryUsage();
|
||||
} else {
|
||||
MOZ_ASSERT(false);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowMemoryReporter::ObserveDOMWindowDetached(nsISupports *aWindow)
|
||||
nsWindowMemoryReporter::ObserveDOMWindowDetached(nsISupports* aWindow)
|
||||
{
|
||||
nsWeakPtr weakWindow = do_GetWeakReference(aWindow);
|
||||
if (!weakWindow) {
|
||||
@ -323,8 +342,35 @@ nsWindowMemoryReporter::ObserveDOMWindowDetached(nsISupports *aWindow)
|
||||
NS_DispatchToCurrentThread(runnable);
|
||||
mCheckForGhostWindowsCallbackPending = true;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
static PLDHashOperator
|
||||
BackdateTimeStampsEnumerator(nsISupports *aKey, TimeStamp &aTimeStamp,
|
||||
void* aClosure)
|
||||
{
|
||||
TimeStamp *minTimeStamp = static_cast<TimeStamp*>(aClosure);
|
||||
|
||||
if (!aTimeStamp.IsNull() && aTimeStamp > *minTimeStamp) {
|
||||
aTimeStamp = *minTimeStamp;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowMemoryReporter::ObserveAfterMinimizeMemoryUsage()
|
||||
{
|
||||
// Someone claims they've done enough GC/CCs so that all eligible windows
|
||||
// have been free'd. So we deem that any windows which satisfy ghost
|
||||
// criteria (1) and (2) now satisfy criterion (3) as well.
|
||||
//
|
||||
// To effect this change, we'll backdate some of our timestamps.
|
||||
|
||||
TimeStamp minTimeStamp = TimeStamp::Now() -
|
||||
TimeDuration::FromSeconds(GetGhostTimeout());
|
||||
|
||||
mDetachedWindows.Enumerate(BackdateTimeStampsEnumerator,
|
||||
&minTimeStamp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -480,14 +526,103 @@ nsWindowMemoryReporter::CheckForGhostWindows(
|
||||
windowsById->EnumerateRead(GetNonDetachedWindowDomainsEnumerator,
|
||||
&nonDetachedEnumData);
|
||||
|
||||
PRUint32 ghostTimeout =
|
||||
Preferences::GetUint("memory.ghost_window_timeout_seconds", 60);
|
||||
|
||||
// Update mDetachedWindows and write the ghost window IDs into aOutGhostIDs,
|
||||
// if it's not null.
|
||||
CheckForGhostWindowsEnumeratorData ghostEnumData =
|
||||
{ &nonDetachedWindowDomains, aOutGhostIDs, tldService,
|
||||
ghostTimeout, TimeStamp::Now() };
|
||||
GetGhostTimeout(), TimeStamp::Now() };
|
||||
mDetachedWindows.Enumerate(CheckForGhostWindowsEnumerator,
|
||||
&ghostEnumData);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsWindowMemoryReporter::nsGhostWindowMemoryReporter,
|
||||
nsIMemoryMultiReporter)
|
||||
|
||||
nsWindowMemoryReporter::
|
||||
nsGhostWindowMemoryReporter::nsGhostWindowMemoryReporter(
|
||||
nsWindowMemoryReporter* aWindowReporter)
|
||||
: mWindowReporter(aWindowReporter)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
nsGhostWindowMemoryReporter::GetName(nsACString& aName)
|
||||
{
|
||||
aName.AssignLiteral("ghost-windows");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
nsGhostWindowMemoryReporter::GetExplicitNonHeap(PRInt64* aOut)
|
||||
{
|
||||
*aOut = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct ReportGhostWindowsEnumeratorData
|
||||
{
|
||||
nsIMemoryMultiReporterCallback* callback;
|
||||
nsISupports* closure;
|
||||
nsresult rv;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
ReportGhostWindowsEnumerator(nsUint64HashKey* aIDHashKey, void* aClosure)
|
||||
{
|
||||
ReportGhostWindowsEnumeratorData *data =
|
||||
static_cast<ReportGhostWindowsEnumeratorData*>(aClosure);
|
||||
|
||||
nsGlobalWindow::WindowByIdTable* windowsById =
|
||||
nsGlobalWindow::GetWindowsTable();
|
||||
if (!windowsById) {
|
||||
NS_WARNING("Couldn't get window-by-id hashtable?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsGlobalWindow* window = windowsById->Get(aIDHashKey->GetKey());
|
||||
if (!window) {
|
||||
NS_WARNING("Could not look up window?");
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsCAutoString path;
|
||||
path.AppendLiteral("ghost-windows/");
|
||||
AppendWindowURI(window, path);
|
||||
|
||||
nsresult rv = data->callback->Callback(
|
||||
/* process = */ EmptyCString(),
|
||||
path,
|
||||
nsIMemoryReporter::KIND_SUMMARY,
|
||||
nsIMemoryReporter::UNITS_COUNT,
|
||||
/* amount = */ 1,
|
||||
/* desc = */ EmptyCString(),
|
||||
data->closure);
|
||||
|
||||
if (NS_FAILED(rv) && NS_SUCCEEDED(data->rv)) {
|
||||
data->rv = rv;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowMemoryReporter::
|
||||
nsGhostWindowMemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
// Get the IDs of all the ghost windows in existance.
|
||||
nsTHashtable<nsUint64HashKey> ghostWindows;
|
||||
ghostWindows.Init();
|
||||
mWindowReporter->CheckForGhostWindows(&ghostWindows);
|
||||
|
||||
ReportGhostWindowsEnumeratorData reportGhostWindowsEnumData =
|
||||
{ aCb, aClosure, NS_OK };
|
||||
|
||||
// Call aCb->Callback() for each ghost window.
|
||||
ghostWindows.EnumerateEntries(ReportGhostWindowsEnumerator,
|
||||
&reportGhostWindowsEnumData);
|
||||
|
||||
return reportGhostWindowsEnumData.rv;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
// This should be used for any nsINode sub-class that has fields of its own
|
||||
@ -139,6 +140,23 @@ public:
|
||||
static void Init();
|
||||
|
||||
private:
|
||||
/**
|
||||
* nsGhostWindowMemoryReporter generates the "ghost-windows" memory report.
|
||||
* If you're only interested in the list of ghost windows, running this
|
||||
* report is faster than running nsWindowMemoryReporter.
|
||||
*/
|
||||
class nsGhostWindowMemoryReporter: public nsIMemoryMultiReporter
|
||||
{
|
||||
public:
|
||||
nsGhostWindowMemoryReporter(nsWindowMemoryReporter* aWindowReporter);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
|
||||
private:
|
||||
nsRefPtr<nsWindowMemoryReporter> mWindowReporter;
|
||||
};
|
||||
|
||||
// Protect ctor, use Init() instead.
|
||||
nsWindowMemoryReporter();
|
||||
|
||||
|
@ -1694,7 +1694,7 @@ class JSCompartmentsMultiReporter : public nsIMemoryMultiReporter
|
||||
for (size_t i = 0; i < paths.length(); i++)
|
||||
// These ones don't need a description, hence the "".
|
||||
REPORT(nsCString(paths[i]),
|
||||
nsIMemoryReporter::KIND_OTHER,
|
||||
nsIMemoryReporter::KIND_SUMMARY,
|
||||
nsIMemoryReporter::UNITS_COUNT,
|
||||
1, "");
|
||||
|
||||
|
@ -51,6 +51,7 @@ const Cu = Components.utils;
|
||||
const KIND_NONHEAP = Ci.nsIMemoryReporter.KIND_NONHEAP;
|
||||
const KIND_HEAP = Ci.nsIMemoryReporter.KIND_HEAP;
|
||||
const KIND_OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||
const KIND_SUMMARY = Ci.nsIMemoryReporter.KIND_SUMMARY;
|
||||
const UNITS_BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||
const UNITS_COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
|
||||
const UNITS_COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
|
||||
@ -163,10 +164,12 @@ function minimizeMemoryUsage3x(fAfter)
|
||||
.getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "memory-pressure", "heap-minimize");
|
||||
|
||||
if (++i < 3)
|
||||
if (++i < 3) {
|
||||
runSoon(sendHeapMinNotificationsInner);
|
||||
else
|
||||
} else {
|
||||
os.notifyObservers(null, "after-minimize-memory-usage", "about:memory");
|
||||
runSoon(fAfter);
|
||||
}
|
||||
}
|
||||
|
||||
sendHeapMinNotificationsInner();
|
||||
@ -275,11 +278,10 @@ function checkReport(aUnsafePath, aKind, aUnits, aAmount, aDescription)
|
||||
assert(aUnits === UNITS_BYTES, "bad smaps units");
|
||||
assert(aDescription !== "", "empty smaps description");
|
||||
|
||||
} else if (aUnsafePath.startsWith("compartments/")) {
|
||||
assert(aKind === KIND_OTHER, "bad compartments kind");
|
||||
assert(aUnits === UNITS_COUNT, "bad compartments units");
|
||||
assert(aAmount === 1, "bad amount");
|
||||
assert(aDescription === "", "bad description");
|
||||
} else if (aKind === KIND_SUMMARY) {
|
||||
assert(!aUnsafePath.startsWith("explicit/") &&
|
||||
!aUnsafePath.startsWith("smaps/"),
|
||||
"bad SUMMARY path");
|
||||
|
||||
} else {
|
||||
assert(aUnsafePath.indexOf("/") === -1, "'other' path contains '/'");
|
||||
@ -537,20 +539,22 @@ Report.prototype = {
|
||||
function getReportsByProcess(aMgr)
|
||||
{
|
||||
// Ignore the "smaps" multi-reporter in non-verbose mode, and the
|
||||
// "compartments" multi-reporter all the time. (Note that reports from these
|
||||
// multi-reporters can reach here as single reports if they were in the child
|
||||
// process.)
|
||||
// "compartments" and "ghost-windows" multi-reporters all the time. (Note
|
||||
// that reports from these multi-reporters can reach here as single reports
|
||||
// if they were in the child process.)
|
||||
|
||||
function ignoreSingle(aPath)
|
||||
{
|
||||
return (aPath.startsWith("smaps/") && !gVerbose) ||
|
||||
(aPath.startsWith("compartments/"))
|
||||
aPath.startsWith("compartments/") ||
|
||||
aPath.startsWith("ghost-windows/");
|
||||
}
|
||||
|
||||
function ignoreMulti(aName)
|
||||
{
|
||||
return ((aName === "smaps" && !gVerbose) ||
|
||||
(aName === "compartments"));
|
||||
return (aName === "smaps" && !gVerbose) ||
|
||||
aName === "compartments" ||
|
||||
aName === "ghost-windows";
|
||||
}
|
||||
|
||||
let reportsByProcess = {};
|
||||
@ -1552,15 +1556,21 @@ function updateAboutCompartments()
|
||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
let compartmentsByProcess = getCompartmentsByProcess(mgr);
|
||||
let ghostWindowsByProcess = getGhostWindowsByProcess(mgr);
|
||||
|
||||
function handleProcess(aProcess) {
|
||||
appendProcessAboutCompartmentsElements(body, aProcess,
|
||||
compartmentsByProcess[aProcess],
|
||||
ghostWindowsByProcess[aProcess]);
|
||||
}
|
||||
|
||||
// Generate output for one process at a time. Always start with the
|
||||
// Main process.
|
||||
let compartmentsByProcess = getCompartmentsByProcess(mgr);
|
||||
appendProcessCompartmentsElements(body, "Main",
|
||||
compartmentsByProcess["Main"]);
|
||||
handleProcess('Main');
|
||||
for (let process in compartmentsByProcess) {
|
||||
if (process !== "Main") {
|
||||
appendProcessCompartmentsElements(body, process,
|
||||
compartmentsByProcess[process]);
|
||||
handleProcess(process);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1656,30 +1666,89 @@ function getCompartmentsByProcess(aMgr)
|
||||
return compartmentsByProcess;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
function appendProcessCompartmentsElementsHelper(aP, aCompartments, aKindString)
|
||||
function GhostWindow(aUnsafeURL)
|
||||
{
|
||||
appendElementWithText(aP, "h2", "", aKindString + " Compartments\n");
|
||||
// Call it _unsafeName rather than _unsafeURL for symmetry with the
|
||||
// Compartment object.
|
||||
this._unsafeName = aUnsafeURL;
|
||||
|
||||
let compartmentTextArray = [];
|
||||
let uPre = appendElement(aP, "pre", "entries");
|
||||
for (let name in aCompartments) {
|
||||
let c = aCompartments[name];
|
||||
let isSystemKind = aKindString === "System";
|
||||
if (c._isSystemCompartment === isSystemKind) {
|
||||
let text = flipBackslashes(c._unsafeName);
|
||||
if (c._nMerged) {
|
||||
text += " [" + c._nMerged + "]";
|
||||
}
|
||||
text += "\n";
|
||||
compartmentTextArray.push(text);
|
||||
// this._nMerged is only defined if > 1
|
||||
}
|
||||
|
||||
GhostWindow.prototype = {
|
||||
merge: function(r) {
|
||||
this._nMerged = this._nMerged ? this._nMerged + 1 : 2;
|
||||
}
|
||||
};
|
||||
|
||||
function getGhostWindowsByProcess(aMgr)
|
||||
{
|
||||
function ignoreSingle(aPath)
|
||||
{
|
||||
return !aPath.startsWith('ghost-windows/')
|
||||
}
|
||||
|
||||
function ignoreMulti(aName)
|
||||
{
|
||||
return aName !== "ghost-windows";
|
||||
}
|
||||
|
||||
let ghostWindowsByProcess = {};
|
||||
|
||||
function handleReport(aProcess, aUnsafePath, aKind, aUnits, aAmount,
|
||||
aDescription)
|
||||
{
|
||||
let unsafeSplit = aUnsafePath.split('/');
|
||||
assert(unsafeSplit[0] == 'ghost-windows/',
|
||||
'Unexpected path in getGhostWindowsByProcess: ' + aUnsafePath);
|
||||
|
||||
let unsafeURL = unsafeSplit[1];
|
||||
let ghostWindow = new GhostWindow(unsafeURL);
|
||||
|
||||
let process = aProcess === "" ? "Main" : aProcess;
|
||||
if (!ghostWindowsByProcess[process]) {
|
||||
ghostWindowsByProcess[process] = {};
|
||||
}
|
||||
|
||||
if (ghostWindowsByProcess[process][unsafeURL]) {
|
||||
ghostWindowsByProcess[process][unsafeURL].merge(ghostWindow);
|
||||
}
|
||||
else {
|
||||
ghostWindowsByProcess[process][unsafeURL] = ghostWindow;
|
||||
}
|
||||
}
|
||||
compartmentTextArray.sort();
|
||||
|
||||
for (let i = 0; i < compartmentTextArray.length; i++) {
|
||||
appendElementWithText(uPre, "span", "", compartmentTextArray[i]);
|
||||
processMemoryReporters(aMgr, ignoreSingle, ignoreMulti, handleReport);
|
||||
|
||||
return ghostWindowsByProcess;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
function appendProcessAboutCompartmentsElementsHelper(aP, aEntries, aKindString)
|
||||
{
|
||||
// aEntries might be null or undefined, e.g. if there are no ghost windows
|
||||
// for this process.
|
||||
aEntries = aEntries ? aEntries : {};
|
||||
|
||||
appendElementWithText(aP, "h2", "", aKindString + "\n");
|
||||
|
||||
let uPre = appendElement(aP, "pre", "entries");
|
||||
|
||||
let lines = [];
|
||||
for (let name in aEntries) {
|
||||
let e = aEntries[name];
|
||||
let line = flipBackslashes(e._unsafeName);
|
||||
if (e._nMerged) {
|
||||
line += ' [' + e._nMerged + ']';
|
||||
}
|
||||
line += '\n';
|
||||
lines.push(line);
|
||||
}
|
||||
lines.sort();
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
appendElementWithText(uPre, "span", "", lines[i]);
|
||||
}
|
||||
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we cut and paste
|
||||
@ -1694,14 +1763,30 @@ function appendProcessCompartmentsElementsHelper(aP, aCompartments, aKindString)
|
||||
* The name of the process.
|
||||
* @param aCompartments
|
||||
* Table of Compartments for this process, indexed by _unsafeName.
|
||||
* @param aGhostWindows
|
||||
* Array of window URLs of ghost windows.
|
||||
*
|
||||
* @return The generated text.
|
||||
*/
|
||||
function appendProcessCompartmentsElements(aP, aProcess, aCompartments)
|
||||
function appendProcessAboutCompartmentsElements(aP, aProcess, aCompartments, aGhostWindows)
|
||||
{
|
||||
appendElementWithText(aP, "h1", "", aProcess + " Process");
|
||||
appendTextNode(aP, "\n\n"); // gives nice spacing when we cut and paste
|
||||
|
||||
let userCompartments = {};
|
||||
let systemCompartments = {};
|
||||
for (let name in aCompartments) {
|
||||
let c = aCompartments[name];
|
||||
if (c._isSystemCompartment) {
|
||||
systemCompartments[name] = c;
|
||||
}
|
||||
else {
|
||||
userCompartments[name] = c;
|
||||
}
|
||||
}
|
||||
|
||||
appendProcessCompartmentsElementsHelper(aP, aCompartments, "User");
|
||||
appendProcessCompartmentsElementsHelper(aP, aCompartments, "System");
|
||||
appendProcessAboutCompartmentsElementsHelper(aP, userCompartments, "User Compartments");
|
||||
appendProcessAboutCompartmentsElementsHelper(aP, systemCompartments, "System Compartments");
|
||||
appendProcessAboutCompartmentsElementsHelper(aP, aGhostWindows, "Ghost Windows");
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
const NONHEAP = Ci.nsIMemoryReporter.KIND_NONHEAP;
|
||||
const HEAP = Ci.nsIMemoryReporter.KIND_HEAP;
|
||||
const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
|
||||
const SUMMARY = Ci.nsIMemoryReporter.KIND_SUMMARY;
|
||||
|
||||
const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
|
||||
const COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
|
||||
@ -71,8 +72,8 @@
|
||||
f("", "other2", OTHER, COUNT, 888),
|
||||
|
||||
f("2nd", "explicit/c", HEAP, BYTES, 333 * MB),
|
||||
f("2nd", "compartments/user/child-user-compartment", OTHER, COUNT, 1),
|
||||
f("2nd", "compartments/system/child-system-compartment", OTHER, COUNT, 1)
|
||||
f("2nd", "compartments/user/child-user-compartment", SUMMARY, COUNT, 1),
|
||||
f("2nd", "compartments/system/child-system-compartment", SUMMARY, COUNT, 1)
|
||||
];
|
||||
|
||||
var fakeMultiReporters = [
|
||||
@ -90,7 +91,7 @@
|
||||
{ name: "compartments",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP) {
|
||||
aCbObj.callback("", aP, OTHER, COUNT, 1, "", aClosure);
|
||||
aCbObj.callback("", aP, SUMMARY, COUNT, 1, "", aClosure);
|
||||
}
|
||||
f("compartments/user/http:\\\\foo.com\\");
|
||||
f("compartments/user/https:\\\\bar.com\\bar?baz");
|
||||
@ -106,6 +107,16 @@
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
},
|
||||
{ name: "ghost-windows",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
function f(aP) {
|
||||
aCbObj.callback("", aP, SUMMARY, COUNT, 1, "", aClosure);
|
||||
}
|
||||
f("ghost-windows/https:\\\\very-long-url.com\\very-long\\oh-so-long\\really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789");
|
||||
f("ghost-windows/http:\\\\foobar.com\\foo?bar#baz");
|
||||
},
|
||||
explicitNonHeap: 0
|
||||
},
|
||||
// These shouldn't show up.
|
||||
{ name: "smaps",
|
||||
collectReports: function(aCbObj, aClosure) {
|
||||
@ -149,6 +160,10 @@ System Compartments\n\
|
||||
atoms\n\
|
||||
moz-nullprincipal:{7ddefdaf-34f1-473f-9b03-50a4568ccb06}\n\
|
||||
\n\
|
||||
Ghost Windows\n\
|
||||
http://foobar.com/foo?bar#baz\n\
|
||||
https://very-long-url.com/very-long/oh-so-long/really-quite-long.html?a=2&b=3&c=4&d=5&e=abcdefghijklmnopqrstuvwxyz&f=123456789123456789123456789\n\
|
||||
\n\
|
||||
2nd Process\n\
|
||||
\n\
|
||||
User Compartments\n\
|
||||
@ -157,6 +172,8 @@ child-user-compartment\n\
|
||||
System Compartments\n\
|
||||
child-system-compartment\n\
|
||||
\n\
|
||||
Ghost Windows\n\
|
||||
\n\
|
||||
";
|
||||
|
||||
// Verbose mode output is the same when you cut and paste.
|
||||
|
@ -117,10 +117,8 @@ interface nsIMemoryReporter : nsISupports
|
||||
* Reporters in this category must have kind NONHEAP, units BYTES, and
|
||||
* a non-empty description.
|
||||
*
|
||||
* - Paths starting with "compartments/" represent the names of JS
|
||||
* compartments. Reporters in this category must paths of the form
|
||||
* "compartments/user/<name>" or "compartments/system/<name>", amount 1,
|
||||
* kind OTHER, units COUNT, and an empty description.
|
||||
* - Reporters with kind SUMMARY may have any path which doesn't start with
|
||||
* "explicit/" or "smaps/".
|
||||
*
|
||||
* - All other paths represent cross-cutting values and may overlap with any
|
||||
* other reporter. Reporters in this category must have paths that do not
|
||||
@ -146,10 +144,22 @@ interface nsIMemoryReporter : nsISupports
|
||||
* - OTHER: reporters which don't fit into either of these categories. Such
|
||||
* reporters must have a path that does not start with "explicit/" or
|
||||
* "smaps/" and may have any units.
|
||||
*
|
||||
* - SUMMARY: reporters which report data that's available in a more
|
||||
* detailed form via other reporters. These reporters are sometimes
|
||||
* useful for efficiency purposes -- for example, a KIND_SUMMARY reporter
|
||||
* might list all the JS compartments without the overhead of the full JS
|
||||
* memory reporter, which walks the JS heap.
|
||||
*
|
||||
* Unlike other reporters, SUMMARY reporters may have empty descriptions.
|
||||
*
|
||||
* SUMMARY reporters must not have a path starting with "explicit/" or
|
||||
* "smaps/".
|
||||
*/
|
||||
const PRInt32 KIND_NONHEAP = 0;
|
||||
const PRInt32 KIND_HEAP = 1;
|
||||
const PRInt32 KIND_OTHER = 2;
|
||||
const PRInt32 KIND_SUMMARY = 3;
|
||||
|
||||
/*
|
||||
* KIND_MAPPED is a deprecated synonym for KIND_NONHEAP. We keep it around
|
||||
|
Loading…
Reference in New Issue
Block a user