--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -39,17 +39,17 @@
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
const gVerbose = location.href === "about:memory?verbose";
-var gAddedObserver = false;
+let gAddedObserver = false;
const KIND_NONHEAP = Ci.nsIMemoryReporter.KIND_NONHEAP;
const KIND_HEAP = Ci.nsIMemoryReporter.KIND_HEAP;
const KIND_OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
const UNITS_BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
const UNITS_COUNT = Ci.nsIMemoryReporter.UNITS_COUNT;
const UNITS_COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
const UNITS_PERCENTAGE = Ci.nsIMemoryReporter.UNITS_PERCENTAGE;
@@ -121,89 +121,89 @@ const kTreeNames = {
'other': 'Other Measurements'
};
const kMapTreePaths =
['smaps/resident', 'smaps/pss', 'smaps/vsize', 'smaps/swap'];
function onLoad()
{
- var os = Cc["@mozilla.org/observer-service;1"].
+ let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.notifyObservers(null, "child-memory-reporter-request", null);
os.addObserver(ChildMemoryListener, "child-memory-reporter-update", false);
gAddedObserver = true;
update();
}
function onUnload()
{
// We need to check if the observer has been added before removing; in some
// circumstances (eg. reloading the page quickly) it might not have because
// onLoad might not fire.
if (gAddedObserver) {
- var os = Cc["@mozilla.org/observer-service;1"].
+ let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.removeObserver(ChildMemoryListener, "child-memory-reporter-update");
}
}
function ChildMemoryListener(aSubject, aTopic, aData)
{
update();
}
function doGlobalGC()
{
Cu.forceGC();
- var os = Cc["@mozilla.org/observer-service;1"]
+ let os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "child-gc-request", null);
update();
}
function doCC()
{
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.cycleCollect();
- var os = Cc["@mozilla.org/observer-service;1"]
+ let os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "child-cc-request", null);
update();
}
// For maximum effect, this returns to the event loop between each
// notification. See bug 610166 comment 12 for an explanation.
// Ideally a single notification would be enough.
function sendHeapMinNotifications()
{
function runSoon(f)
{
- var tm = Cc["@mozilla.org/thread-manager;1"]
+ let tm = Cc["@mozilla.org/thread-manager;1"]
.getService(Ci.nsIThreadManager);
tm.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL);
}
function sendHeapMinNotificationsInner()
{
- var os = Cc["@mozilla.org/observer-service;1"]
+ let os = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
os.notifyObservers(null, "memory-pressure", "heap-minimize");
if (++j < 3)
runSoon(sendHeapMinNotificationsInner);
else
runSoon(update);
}
- var j = 0;
+ let j = 0;
sendHeapMinNotificationsInner();
}
function Reporter(aUnsafePath, aKind, aUnits, aAmount, aUnsafeDesc)
{
this._unsafePath = aUnsafePath;
this._kind = aKind;
this._units = aUnits;
@@ -242,53 +242,53 @@ function getReportersByProcess(aMgr)
// is a Reporter object. After this point we never use the original memory
// reporter again.
//
// - Note that copying rOrig.amount (which calls a C++ function under the
// IDL covers) to r._amount for every reporter now means that the
// results as consistent as possible -- measurements are made all at
// once before most of the memory required to generate this page is
// allocated.
- var reportersByProcess = {};
+ let reportersByProcess = {};
function addReporter(aProcess, aUnsafePath, aKind, aUnits, aAmount,
aUnsafeDesc)
{
- var process = aProcess === "" ? "Main" : aProcess;
- var r = new Reporter(aUnsafePath, aKind, aUnits, aAmount, aUnsafeDesc);
+ let process = aProcess === "" ? "Main" : aProcess;
+ let r = new Reporter(aUnsafePath, aKind, aUnits, aAmount, aUnsafeDesc);
if (!reportersByProcess[process]) {
reportersByProcess[process] = {};
}
- var reporters = reportersByProcess[process];
- var reporter = reporters[r._unsafePath];
+ let reporters = reportersByProcess[process];
+ let reporter = reporters[r._unsafePath];
if (reporter) {
// Already an entry; must be a duplicated reporter. This can happen
// legitimately. Merge them.
reporter.merge(r);
} else {
reporters[r._unsafePath] = r;
}
}
// Process vanilla reporters first, then multi-reporters.
- var e = aMgr.enumerateReporters();
+ let e = aMgr.enumerateReporters();
while (e.hasMoreElements()) {
- var rOrig = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
+ let rOrig = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
try {
addReporter(rOrig.process, rOrig.path, rOrig.kind, rOrig.units,
rOrig.amount, rOrig.description);
}
catch(e) {
debug("An error occurred when collecting results from the memory reporter " +
rOrig.path + ": " + e);
}
}
- var e = aMgr.enumerateMultiReporters();
+ let e = aMgr.enumerateMultiReporters();
while (e.hasMoreElements()) {
- var mrOrig = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
+ let mrOrig = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
// Ignore the "smaps" reporters in non-verbose mode.
if (!gVerbose && mrOrig.name === "smaps") {
continue;
}
try {
mrOrig.collectReports(addReporter, null);
}
@@ -297,60 +297,60 @@ function getReportersByProcess(aMgr)
}
}
return reportersByProcess;
}
function appendTextNode(aP, aText)
{
- var e = document.createTextNode(aText);
+ let e = document.createTextNode(aText);
aP.appendChild(e);
return e;
}
function appendElement(aP, aTagName, aClassName)
{
- var e = document.createElement(aTagName);
+ let e = document.createElement(aTagName);
if (aClassName) {
e.className = aClassName;
}
aP.appendChild(e);
return e;
}
function appendElementWithText(aP, aTagName, aClassName, aText)
{
- var e = appendElement(aP, aTagName, aClassName);
+ let e = appendElement(aP, aTagName, aClassName);
appendTextNode(e, aText);
return e;
}
/**
* Top-level function that does the work of generating the page.
*/
function update()
{
// First, clear the page contents. Necessary because update() might be
// called more than once due to ChildMemoryListener.
- var oldContent = document.getElementById("content");
- var content = oldContent.cloneNode(false);
+ let oldContent = document.getElementById("content");
+ let content = oldContent.cloneNode(false);
oldContent.parentNode.replaceChild(content, oldContent);
content.classList.add(gVerbose ? 'verbose' : 'non-verbose');
- var mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
+ let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager);
// Generate output for one process at a time. Always start with the
// Main process.
- var reportersByProcess = getReportersByProcess(mgr);
- var hasMozMallocUsableSize = mgr.hasMozMallocUsableSize;
+ let reportersByProcess = getReportersByProcess(mgr);
+ let hasMozMallocUsableSize = mgr.hasMozMallocUsableSize;
appendProcessElements(content, "Main", reportersByProcess["Main"],
hasMozMallocUsableSize);
- for (var process in reportersByProcess) {
+ for (let process in reportersByProcess) {
if (process !== "Main") {
appendProcessElements(content, process, reportersByProcess[process],
hasMozMallocUsableSize);
}
}
appendElement(content, "hr");
@@ -361,47 +361,47 @@ function update()
const MPDesc = "Send three \"heap-minimize\" notifications in a " +
"row. Each notification triggers a global garbage " +
"collection followed by a cycle collection, and causes the " +
"process to reduce memory usage in other ways, e.g. by " +
"flushing various caches.";
function appendButton(aTitle, aOnClick, aText, aId)
{
- var b = appendElementWithText(content, "button", "", aText);
+ let b = appendElementWithText(content, "button", "", aText);
b.title = aTitle;
b.onclick = aOnClick
if (aId) {
b.id = aId;
}
}
// The "Update" button has an id so it can be clicked in a test.
appendButton(UpDesc, update, "Update", "updateButton");
appendButton(GCDesc, doGlobalGC, "GC");
appendButton(CCDesc, doCC, "CC");
appendButton(MPDesc, sendHeapMinNotifications, "Minimize memory usage");
- var div1 = appendElement(content, "div");
- var a;
+ let div1 = appendElement(content, "div");
if (gVerbose) {
- var a = appendElementWithText(div1, "a", "option", "Less verbose");
+ let a = appendElementWithText(div1, "a", "option", "Less verbose");
a.href = "about:memory";
} else {
- var a = appendElementWithText(div1, "a", "option", "More verbose");
+ let a = appendElementWithText(div1, "a", "option", "More verbose");
a.href = "about:memory?verbose";
}
- var div2 = appendElement(content, "div");
- a = appendElementWithText(div2, "a", "option", "Troubleshooting information");
+ let div2 = appendElement(content, "div");
+ let a = appendElementWithText(div2, "a", "option",
+ "Troubleshooting information");
a.href = "about:support";
- var legendText1 = "Click on a non-leaf node in a tree to expand ('++') " +
+ let legendText1 = "Click on a non-leaf node in a tree to expand ('++') " +
"or collapse ('--') its children.";
- var legendText2 = "Hover the pointer over the name of a memory reporter " +
+ let legendText2 = "Hover the pointer over the name of a memory reporter " +
"to see a description of what it measures.";
appendElementWithText(content, "div", "legend", legendText1);
appendElementWithText(content, "div", "legend", legendText2);
}
// There are two kinds of TreeNode.
// - Leaf TreeNodes correspond to Reporters and have more properties.
@@ -422,17 +422,17 @@ function TreeNode(aUnsafeName)
// Non-leaf TreeNodes have these properties added later:
// - _amount (which is never |kUnknown|)
// - _unsafeDescription
// - _hideKids (only defined if true)
}
TreeNode.prototype = {
findKid: function(aUnsafeName) {
- for (var i = 0; i < this._kids.length; i++) {
+ for (let i = 0; i < this._kids.length; i++) {
if (this._kids[i]._unsafeName === aUnsafeName) {
return this._kids[i];
}
}
return undefined;
},
toString: function() {
@@ -458,45 +458,45 @@ function buildTree(aReporters, aTreeName
{
// We want to process all reporters that begin with |aTreeName|. First we
// build the tree but only fill the properties that we can with a top-down
// traversal.
// There should always be at least one matching reporter when |aTreeName| is
// "explicit". But there may be zero for "smaps" trees; if that happens,
// bail.
- var foundReporter = false;
- for (var unsafePath in aReporters) {
+ let foundReporter = false;
+ for (let unsafePath in aReporters) {
if (aReporters[unsafePath].treeNameMatches(aTreeName)) {
foundReporter = true;
break;
}
}
if (!foundReporter) {
assert(aTreeName !== 'explicit');
return null;
}
- var t = new TreeNode("falseRoot");
- for (var unsafePath in aReporters) {
+ let t = new TreeNode("falseRoot");
+ for (let unsafePath in aReporters) {
// Add any missing nodes in the tree implied by the unsafePath.
- var r = aReporters[unsafePath];
+ let r = aReporters[unsafePath];
if (r.treeNameMatches(aTreeName)) {
assert(r._kind === KIND_HEAP || r._kind === KIND_NONHEAP,
"reporters in the tree must have KIND_HEAP or KIND_NONHEAP");
assert(r._units === UNITS_BYTES, "r._units === UNITS_BYTES");
- var unsafeNames = r._unsafePath.split('/');
- var u = t;
- for (var i = 0; i < unsafeNames.length; i++) {
- var unsafeName = unsafeNames[i];
- var uMatch = u.findKid(unsafeName);
+ let unsafeNames = r._unsafePath.split('/');
+ let u = t;
+ for (let i = 0; i < unsafeNames.length; i++) {
+ let unsafeName = unsafeNames[i];
+ let uMatch = u.findKid(unsafeName);
if (uMatch) {
u = uMatch;
} else {
- var v = new TreeNode(unsafeName);
+ let v = new TreeNode(unsafeName);
u._kids.push(v);
u = v;
}
}
// Fill in extra details in the leaf node from the Reporter.
if (r._amount !== kUnknown) {
u._amount = r._amount;
} else {
@@ -522,34 +522,34 @@ function buildTree(aReporters, aTreeName
{
if (aT._kids.length === 0) {
// Leaf node. Has already been filled in.
assert(aT._kind !== undefined, "aT._kind is undefined for leaf node");
} else {
// Non-leaf node. Derive its _amount and _unsafeDescription entirely
// from its children.
assert(aT._kind === undefined, "aT._kind is defined for non-leaf node");
- var childrenBytes = 0;
- for (var i = 0; i < aT._kids.length; i++) {
+ let childrenBytes = 0;
+ for (let i = 0; i < aT._kids.length; i++) {
childrenBytes += fillInNonLeafNodes(aT._kids[i]);
}
aT._amount = childrenBytes;
aT._unsafeDescription =
"The sum of all entries below '" + aT._unsafeName + "'.";
}
assert(aT._amount !== kUnknown, "aT._amount !== kUnknown");
return aT._amount;
}
fillInNonLeafNodes(t);
// Reduce the depth of the tree by the number of occurrences of '/' in
// aTreeName. (Thus the tree named 'foo/bar/baz' will be rooted at 'baz'.)
- var slashCount = 0;
- for (var i = 0; i < aTreeName.length; i++) {
+ let slashCount = 0;
+ for (let i = 0; i < aTreeName.length; i++) {
if (aTreeName[i] == '/') {
assert(t._kids.length == 1, "Not expecting multiple kids here.");
t = t._kids[0];
}
}
// Set the (unsafe) description on the root node.
t._unsafeDescription = kTreeUnsafeDescriptions[t._unsafeName];
@@ -561,18 +561,18 @@ function buildTree(aReporters, aTreeName
* Ignore all the memory reports that belong to a "smaps" tree; this involves
* explicitly marking them as done.
*
* @param aReporters
* The table of Reporters, indexed by _unsafePath.
*/
function ignoreSmapsTrees(aReporters)
{
- for (var unsafePath in aReporters) {
- var r = aReporters[unsafePath];
+ for (let unsafePath in aReporters) {
+ let r = aReporters[unsafePath];
if (r.treeNameMatches("smaps")) {
r._done = true;
}
}
}
/**
* Do some work which only makes sense for the 'explicit' tree.
@@ -583,37 +583,37 @@ function ignoreSmapsTrees(aReporters)
* Table of Reporters for this process, indexed by _unsafePath.
* @return A boolean indicating if "heap-allocated" is known for the process.
*/
function fixUpExplicitTree(aT, aReporters)
{
// Determine how many bytes are reported by heap reporters.
function getKnownHeapUsedBytes(aT)
{
- var n = 0;
+ let n = 0;
if (aT._kids.length === 0) {
// Leaf node.
assert(aT._kind !== undefined, "aT._kind is undefined for leaf node");
n = aT._kind === KIND_HEAP ? aT._amount : 0;
} else {
- for (var i = 0; i < aT._kids.length; i++) {
+ for (let i = 0; i < aT._kids.length; i++) {
n += getKnownHeapUsedBytes(aT._kids[i]);
}
}
return n;
}
// A special case: compute the derived "heap-unclassified" value. Don't
// mark "heap-allocated" when we get its size because we want it to appear
// in the "Other Measurements" list.
- var heapAllocatedReporter = aReporters["heap-allocated"];
+ let heapAllocatedReporter = aReporters["heap-allocated"];
assert(heapAllocatedReporter, "no 'heap-allocated' reporter");
- var heapAllocatedBytes = heapAllocatedReporter._amount;
- var heapUnclassifiedT = new TreeNode("heap-unclassified");
- var hasKnownHeapAllocated = heapAllocatedBytes !== kUnknown;
+ let heapAllocatedBytes = heapAllocatedReporter._amount;
+ let heapUnclassifiedT = new TreeNode("heap-unclassified");
+ let hasKnownHeapAllocated = heapAllocatedBytes !== kUnknown;
if (hasKnownHeapAllocated) {
heapUnclassifiedT._amount =
heapAllocatedBytes - getKnownHeapUsedBytes(aT);
} else {
heapUnclassifiedT._amount = 0;
heapUnclassifiedT._isUnknown = true;
}
// This kindToString() ensures the "(Heap)" prefix is set without having to
@@ -656,32 +656,33 @@ function sortTreeAndInsertAggregateNodes
aT._kids.sort(TreeNode.compare);
// If the first child is insignificant, they all are, and there's no point
// creating an aggregate node that lacks siblings. Just set the parent's
// _hideKids property and process all children.
if (isInsignificant(aT._kids[0])) {
aT._hideKids = true;
- for (var i = 0; i < aT._kids.length; i++) {
+ for (let i = 0; i < aT._kids.length; i++) {
sortTreeAndInsertAggregateNodes(aTotalBytes, aT._kids[i]);
}
return;
}
// Look at all children except the last one.
- for (var i = 0; i < aT._kids.length - 1; i++) {
+ let i;
+ for (i = 0; i < aT._kids.length - 1; i++) {
if (isInsignificant(aT._kids[i])) {
// This child is below the significance threshold. If there are other
// (smaller) children remaining, move them under an aggregate node.
- var i0 = i;
- var nAgg = aT._kids.length - i0;
+ let i0 = i;
+ let nAgg = aT._kids.length - i0;
// Create an aggregate node.
- var aggT = new TreeNode("(" + nAgg + " tiny)");
- var aggBytes = 0;
+ let aggT = new TreeNode("(" + nAgg + " tiny)");
+ let aggBytes = 0;
for ( ; i < aT._kids.length; i++) {
aggBytes += aT._kids[i]._amount;
aggT._kids.push(aT._kids[i]);
}
aggT._hideKids = true;
aggT._amount = aggBytes;
aggT._unsafeDescription =
nAgg + " sub-trees that are below the " + kSignificanceThresholdPerc +
@@ -703,17 +704,17 @@ function sortTreeAndInsertAggregateNodes
// is significant; there's no point creating an aggregate node that only has
// one child. Just process it.
sortTreeAndInsertAggregateNodes(aTotalBytes, aT._kids[i]);
}
// Global variable indicating if we've seen any invalid values for this
// process; it holds the unsafePaths of any such reporters. It is reset for
// each new process.
-var gUnsafePathsWithInvalidValuesForThisProcess = [];
+let gUnsafePathsWithInvalidValuesForThisProcess = [];
function appendWarningElements(aP, aHasKnownHeapAllocated,
aHasMozMallocUsableSize)
{
if (!aHasKnownHeapAllocated && !aHasMozMallocUsableSize) {
appendElementWithText(aP, "p", "",
"WARNING: the 'heap-allocated' memory reporter and the " +
"moz_malloc_usable_size() function do not work for this platform " +
@@ -733,23 +734,23 @@ function appendWarningElements(aP, aHasK
"WARNING: the moz_malloc_usable_size() function does not work for " +
"this platform and/or configuration. This means that much of the " +
"heap-allocated memory is not measured by individual memory reporters " +
"and so will fall under 'heap-unclassified'.");
appendTextNode(aP, "\n\n");
}
if (gUnsafePathsWithInvalidValuesForThisProcess.length > 0) {
- var div = appendElement(aP, "div");
+ let div = appendElement(aP, "div");
appendElementWithText(div, "p", "",
"WARNING: the following values are negative or unreasonably large.");
appendTextNode(div, "\n");
- var ul = appendElement(div, "ul");
- for (var i = 0;
+ let ul = appendElement(div, "ul");
+ for (let i = 0;
i < gUnsafePathsWithInvalidValuesForThisProcess.length;
i++)
{
appendTextNode(ul, " ");
appendElementWithText(ul, "li", "",
makeSafe(gUnsafePathsWithInvalidValuesForThisProcess[i]));
appendTextNode(ul, "\n");
}
@@ -777,27 +778,27 @@ function appendWarningElements(aP, aHasK
*/
function appendProcessElements(aP, aProcess, aReporters,
aHasMozMallocUsableSize)
{
appendElementWithText(aP, "h1", "", aProcess + " Process");
appendTextNode(aP, "\n\n"); // gives nice spacing when we cut and paste
// We'll fill this in later.
- var warningsDiv = appendElement(aP, "div", "accuracyWarning");
+ let warningsDiv = appendElement(aP, "div", "accuracyWarning");
- var explicitTree = buildTree(aReporters, 'explicit');
- var hasKnownHeapAllocated = fixUpExplicitTree(explicitTree, aReporters);
+ let explicitTree = buildTree(aReporters, 'explicit');
+ let hasKnownHeapAllocated = fixUpExplicitTree(explicitTree, aReporters);
sortTreeAndInsertAggregateNodes(explicitTree._amount, explicitTree);
appendTreeElements(aP, explicitTree, aProcess);
// We only show these breakdown trees in verbose mode.
if (gVerbose) {
kMapTreePaths.forEach(function(t) {
- var tree = buildTree(aReporters, t);
+ let tree = buildTree(aReporters, t);
// |tree| will be null if we don't have any reporters for the given
// unsafePath.
if (tree) {
sortTreeAndInsertAggregateNodes(tree._amount, tree);
tree._hideKids = true; // smaps trees are always initially collapsed
appendTreeElements(aP, tree, aProcess);
}
@@ -846,24 +847,24 @@ function hasNegativeSign(aN)
* @return A human-readable string representing the int.
*
* Note: building an array of chars and converting that to a string with
* Array.join at the end is more memory efficient than using string
* concatenation. See bug 722972 for details.
*/
function formatInt(aN, aExtra)
{
- var neg = false;
+ let neg = false;
if (hasNegativeSign(aN)) {
neg = true;
aN = -aN;
}
- var s = [];
+ let s = [];
while (true) {
- var k = aN % 1000;
+ let k = aN % 1000;
aN = Math.floor(aN / 1000);
if (aN > 0) {
if (k < 10) {
s.unshift(",00", k);
} else if (k < 100) {
s.unshift(",0", k);
} else {
s.unshift(",", k);
@@ -886,24 +887,24 @@ function formatInt(aN, aExtra)
* Converts a byte count to an appropriate string representation.
*
* @param aBytes
* The byte count.
* @return The string representation.
*/
function formatBytes(aBytes)
{
- var unit = gVerbose ? " B" : " MB";
+ let unit = gVerbose ? " B" : " MB";
- var s;
+ let s;
if (gVerbose) {
s = formatInt(aBytes, unit);
} else {
- var mbytes = (aBytes / (1024 * 1024)).toFixed(2);
- var a = String(mbytes).split(".");
+ let mbytes = (aBytes / (1024 * 1024)).toFixed(2);
+ let a = String(mbytes).split(".");
// If the argument to formatInt() is -0, it will print the negative sign.
s = formatInt(Number(a[0])) + "." + a[1] + unit;
}
return s;
}
/**
* Converts a percentage to an appropriate string representation.
@@ -925,19 +926,19 @@ function formatPercentage(aPerc100x)
* @param aN
* The field width.
* @param aC
* The char used to pad.
* @return The string representation.
*/
function pad(aS, aN, aC)
{
- var padding = "";
- var n2 = aN - aS.length;
- for (var i = 0; i < n2; i++) {
+ let padding = "";
+ let n2 = aN - aS.length;
+ for (let i = 0; i < n2; i++) {
padding += aC;
}
return padding + aS;
}
// There's a subset of the Unicode "light" box-drawing chars that are widely
// implemented in terminals, and this code sticks to that subset to maximize
// the chance that cutting and pasting about:memory output to a terminal will
@@ -968,111 +969,111 @@ function kindToString(aKind)
// Possible states for kids.
const kNoKids = 0;
const kHideKids = 1;
const kShowKids = 2;
function appendMrNameSpan(aP, aKind, aKidsState, aUnsafeDesc, aUnsafeName,
aIsUnknown, aIsInvalid, aNMerged)
{
- var text = "";
+ let text = "";
if (aKidsState === kNoKids) {
appendElementWithText(aP, "span", "mrSep", kDoubleHorizontalSep);
} else if (aKidsState === kHideKids) {
appendElementWithText(aP, "span", "mrSep", " ++ ");
appendElementWithText(aP, "span", "mrSep hidden", " -- ");
} else if (aKidsState === kShowKids) {
appendElementWithText(aP, "span", "mrSep hidden", " ++ ");
appendElementWithText(aP, "span", "mrSep", " -- ");
} else {
assert(false, "bad aKidsState");
}
- var nameSpan = appendElementWithText(aP, "span", "mrName",
+ let nameSpan = appendElementWithText(aP, "span", "mrName",
makeSafe(aUnsafeName));
nameSpan.title = kindToString(aKind) + makeSafe(aUnsafeDesc);
if (aIsUnknown) {
- var noteSpan = appendElementWithText(aP, "span", "mrNote", " [*]");
+ let noteSpan = appendElementWithText(aP, "span", "mrNote", " [*]");
noteSpan.title =
"Warning: this memory reporter was unable to compute a useful value. ";
}
if (aIsInvalid) {
- var noteSpan = appendElementWithText(aP, "span", "mrNote", " [?!]");
+ let noteSpan = appendElementWithText(aP, "span", "mrNote", " [?!]");
noteSpan.title =
"Warning: this value is invalid and indicates a bug in one or more " +
"memory reporters. ";
}
if (aNMerged) {
- var noteSpan = appendElementWithText(aP, "span", "mrNote",
+ let noteSpan = appendElementWithText(aP, "span", "mrNote",
" [" + aNMerged + "]");
noteSpan.title =
"This value is the sum of " + aNMerged +
" memory reporters that all have the same path.";
}
}
// This is used to record the (safe) IDs of which sub-trees have been toggled,
// so the collapsed/expanded state can be replicated when the page is
// regenerated. It can end up holding IDs of nodes that no longer exist, e.g.
// for compartments that have been closed. This doesn't seem like a big deal,
// because the number is limited by the number of entries the user has changed
// from their original state.
-var gTogglesBySafeTreeId = {};
+let gTogglesBySafeTreeId = {};
function assertClassListContains(e, className) {
assert(e, "undefined " + className);
assert(e.classList.contains(className), "classname isn't " + className);
}
function toggle(aEvent)
{
// This relies on each line being a span that contains at least five spans:
// mrValue, mrPerc, mrSep ('++'), mrSep ('--'), mrName, and then zero or more
// mrNotes. All whitespace must be within one of these spans for this
// function to find the right nodes. And the span containing the children of
// this line must immediately follow. Assertions check this.
// |aEvent.target| will be one of the five spans. Get the outer span.
- var outerSpan = aEvent.target.parentNode;
+ let outerSpan = aEvent.target.parentNode;
assertClassListContains(outerSpan, "hasKids");
// Toggle visibility of the '++' and '--' separators.
- var plusSpan = outerSpan.childNodes[2];
- var minusSpan = outerSpan.childNodes[3];
+ let plusSpan = outerSpan.childNodes[2];
+ let minusSpan = outerSpan.childNodes[3];
assertClassListContains(plusSpan, "mrSep");
assertClassListContains(minusSpan, "mrSep");
plusSpan .classList.toggle("hidden");
minusSpan.classList.toggle("hidden");
// Toggle visibility of the span containing this node's children.
- var subTreeSpan = outerSpan.nextSibling;
+ let subTreeSpan = outerSpan.nextSibling;
assertClassListContains(subTreeSpan, "kids");
subTreeSpan.classList.toggle("hidden");
// Record/unrecord that this sub-tree was toggled.
- var safeTreeId = outerSpan.id;
+ let safeTreeId = outerSpan.id;
if (gTogglesBySafeTreeId[safeTreeId]) {
delete gTogglesBySafeTreeId[safeTreeId];
} else {
gTogglesBySafeTreeId[safeTreeId] = true;
}
}
function expandPathToThisElement(aElement)
{
if (aElement.classList.contains("kids")) {
// Unhide the kids.
aElement.classList.remove("hidden");
expandPathToThisElement(aElement.previousSibling); // hasKids
} else if (aElement.classList.contains("hasKids")) {
// Unhide the '--' separator and hide the '++' separator.
- var plusSpan = aElement.childNodes[2];
- var minusSpan = aElement.childNodes[3];
+ let plusSpan = aElement.childNodes[2];
+ let minusSpan = aElement.childNodes[3];
assertClassListContains(plusSpan, "mrSep");
assertClassListContains(minusSpan, "mrSep");
plusSpan.classList.add("hidden");
minusSpan.classList.remove("hidden");
expandPathToThisElement(aElement.parentNode); // kids or pre.tree
} else {
assertClassListContains(aElement, "tree");
@@ -1087,19 +1088,19 @@ function expandPathToThisElement(aElemen
* @param aT
* The tree.
* @param aProcess
* The process the tree corresponds to.
* @return The generated text.
*/
function appendTreeElements(aPOuter, aT, aProcess)
{
- var treeBytes = aT._amount;
- var rootStringLength = aT.toString().length;
- var isExplicitTree = aT._unsafeName == 'explicit';
+ let treeBytes = aT._amount;
+ let rootStringLength = aT.toString().length;
+ let isExplicitTree = aT._unsafeName == 'explicit';
/**
* Appends the elements for a particular tree, without a heading.
*
* @param aP
* The parent DOM node.
* @param aUnsafePrePath
* The partial unsafePath leading up to this node.
@@ -1117,62 +1118,63 @@ function appendTreeElements(aPOuter, aT,
* The length of the formatted byte count of the top node in the tree.
* @return The generated text.
*/
function appendTreeElements2(aP, aUnsafePrePath, aT, aIndentGuide,
aBaseIndentText, aParentStringLength)
{
function repeatStr(aA, aC, aN)
{
- for (var i = 0; i < aN; i++) {
+ for (let i = 0; i < aN; i++) {
aA.push(aC);
}
}
- var unsafePath = aUnsafePrePath + aT._unsafeName;
+ let unsafePath = aUnsafePrePath + aT._unsafeName;
// Indent more if this entry is narrower than its parent, and update
// aIndentGuide accordingly.
- var tString = aT.toString();
- var extraIndentArray = [];
- var extraIndentLength = Math.max(aParentStringLength - tString.length, 0);
+ let tString = aT.toString();
+ let extraIndentArray = [];
+ let extraIndentLength = Math.max(aParentStringLength - tString.length, 0);
if (extraIndentLength > 0) {
repeatStr(extraIndentArray, kHorizontal, extraIndentLength);
aIndentGuide[aIndentGuide.length - 1]._depth += extraIndentLength;
}
- var indentText = aBaseIndentText + extraIndentArray.join("");
+ let indentText = aBaseIndentText + extraIndentArray.join("");
appendElementWithText(aP, "span", "treeLine", indentText);
// Generate the percentage; detect and record invalid values at the same
// time.
- var percText = "";
- var tIsInvalid = false;
+ let percText = "";
+ let tIsInvalid = false;
if (aT._amount === treeBytes) {
percText = "100.0";
} else {
- var perc = (100 * aT._amount / treeBytes);
+ let perc = (100 * aT._amount / treeBytes);
if (!(0 <= perc && perc <= 100)) {
tIsInvalid = true;
gUnsafePathsWithInvalidValuesForThisProcess.push(unsafePath);
}
percText = (100 * aT._amount / treeBytes).toFixed(2);
percText = pad(percText, 5, '0');
}
percText = " (" + percText + "%)";
// For non-leaf nodes, the entire sub-tree is put within a span so it can
// be collapsed if the node is clicked on.
- var d;
- var hasKids = aT._kids.length > 0;
- var kidsState;
+ let d;
+ let hasKids = aT._kids.length > 0;
+ let kidsState;
+ let showSubtrees;
if (hasKids) {
// Determine if we should show the sub-tree below this entry; this
// involves reinstating any previous toggling of the sub-tree.
- var safeTreeId = makeSafe(aProcess + ":" + unsafePath);
- var showSubtrees = !aT._hideKids;
+ let safeTreeId = makeSafe(aProcess + ":" + unsafePath);
+ showSubtrees = !aT._hideKids;
if (gTogglesBySafeTreeId[safeTreeId]) {
showSubtrees = !showSubtrees;
}
d = appendElement(aP, "span", "hasKids");
d.id = safeTreeId;
d.onclick = toggle;
kidsState = showSubtrees ? kShowKids : kHideKids;
} else {
@@ -1181,58 +1183,59 @@ function appendTreeElements(aPOuter, aT,
d = aP;
}
appendMrValueSpan(d, tString, tIsInvalid);
appendElementWithText(d, "span", "mrPerc", percText);
// We don't want to show '(nonheap)' on a tree like 'map/vsize', since the
// whole tree is non-heap.
- var kind = isExplicitTree ? aT._kind : undefined;
+ let kind = isExplicitTree ? aT._kind : undefined;
appendMrNameSpan(d, kind, kidsState, aT._unsafeDescription, aT._unsafeName,
aT._isUnknown, tIsInvalid, aT._nMerged);
appendTextNode(d, "\n");
// In non-verbose mode, invalid nodes can be hidden in collapsed sub-trees.
// But it's good to always see them, so force this.
if (!gVerbose && tIsInvalid) {
expandPathToThisElement(d);
}
if (hasKids) {
// The 'kids' class is just used for sanity checking in toggle().
d = appendElement(aP, "span", showSubtrees ? "kids" : "kids hidden");
- for (var i = 0; i < aT._kids.length; i++) {
+ for (let i = 0; i < aT._kids.length; i++) {
// 3 is the standard depth, the callee adjusts it if necessary.
aIndentGuide.push({ _isLastKid: (i === aT._kids.length - 1), _depth: 3 });
// Generate the base indent.
- var baseIndentArray = [];
+ let baseIndentArray = [];
if (aIndentGuide.length > 0) {
- for (var j = 0; j < aIndentGuide.length - 1; j++) {
+ let j;
+ for (j = 0; j < aIndentGuide.length - 1; j++) {
baseIndentArray.push(aIndentGuide[j]._isLastKid ? " " : kVertical);
repeatStr(baseIndentArray, " ", aIndentGuide[j]._depth - 1);
}
baseIndentArray.push(aIndentGuide[j]._isLastKid ?
kUpAndRight : kVerticalAndRight);
repeatStr(baseIndentArray, kHorizontal, aIndentGuide[j]._depth - 1);
}
- var baseIndentText = baseIndentArray.join("");
+ let baseIndentText = baseIndentArray.join("");
appendTreeElements2(d, unsafePath + "/", aT._kids[i], aIndentGuide,
baseIndentText, tString.length);
aIndentGuide.pop();
}
}
}
appendSectionHeader(aPOuter, kTreeNames[aT._unsafeName]);
- var pre = appendElement(aPOuter, "pre", "tree");
+ let pre = appendElement(aPOuter, "pre", "tree");
appendTreeElements2(pre, /* prePath = */"", aT, [], "", rootStringLength);
appendTextNode(aPOuter, "\n"); // gives nice spacing when we cut and paste
}
function OtherReporter(aUnsafePath, aUnits, aAmount, aUnsafeDesc, aNMerged)
{
// Nb: _kind is not needed, it's always KIND_OTHER.
this._unsafePath = aUnsafePath;
@@ -1255,17 +1258,17 @@ OtherReporter.prototype = {
case UNITS_COUNT_CUMULATIVE: return formatInt(this._amount);
case UNITS_PERCENTAGE: return formatPercentage(this._amount);
default:
assert(false, "bad units in OtherReporter.toString");
}
},
isInvalid: function() {
- var n = this._amount;
+ let n = this._amount;
switch (this._units) {
case UNITS_BYTES:
case UNITS_COUNT:
case UNITS_COUNT_CUMULATIVE: return (n !== kUnknown && n < 0);
case UNITS_PERCENTAGE: return (n !== kUnknown &&
!(0 <= n && n <= 10000));
default:
assert(false, "bad units in OtherReporter.isInvalid");
@@ -1289,44 +1292,44 @@ OtherReporter.compare = function(a, b) {
* @param aProcess
* The process these reporters correspond to.
* @return The generated text.
*/
function appendOtherElements(aP, aReportersByProcess)
{
appendSectionHeader(aP, kTreeNames['other']);
- var pre = appendElement(aP, "pre", "tree");
+ let pre = appendElement(aP, "pre", "tree");
// Generate an array of Reporter-like elements, stripping out all the
// Reporters that have already been handled. Also find the width of the
// widest element, so we can format things nicely.
- var maxStringLength = 0;
- var otherReporters = [];
- for (var unsafePath in aReportersByProcess) {
- var r = aReportersByProcess[unsafePath];
+ let maxStringLength = 0;
+ let otherReporters = [];
+ for (let unsafePath in aReportersByProcess) {
+ let r = aReportersByProcess[unsafePath];
if (!r._done) {
assert(r._kind === KIND_OTHER,
"_kind !== KIND_OTHER for " + makeSafe(r._unsafePath));
assert(r._nMerged === undefined); // we don't allow dup'd OTHER reporters
- var o = new OtherReporter(r._unsafePath, r._units, r._amount,
+ let o = new OtherReporter(r._unsafePath, r._units, r._amount,
r._unsafeDescription);
otherReporters.push(o);
if (o._asString.length > maxStringLength) {
maxStringLength = o._asString.length;
}
}
}
otherReporters.sort(OtherReporter.compare);
// Generate text for the not-yet-printed values.
- var text = "";
- for (var i = 0; i < otherReporters.length; i++) {
- var o = otherReporters[i];
- var oIsInvalid = o.isInvalid();
+ let text = "";
+ for (let i = 0; i < otherReporters.length; i++) {
+ let o = otherReporters[i];
+ let oIsInvalid = o.isInvalid();
if (oIsInvalid) {
gUnsafePathsWithInvalidValuesForThisProcess.push(o._unsafePath);
}
appendMrValueSpan(pre, pad(o._asString, maxStringLength, ' '), oIsInvalid);
appendMrNameSpan(pre, KIND_OTHER, kNoKids, o._unsafeDescription,
o._unsafePath, o._isUnknown, oIsInvalid);
appendTextNode(pre, "\n");
}
@@ -1344,11 +1347,11 @@ function assert(aCond, aMsg)
{
if (!aCond) {
throw("assertion failed: " + aMsg);
}
}
function debug(x)
{
- var content = document.getElementById("content");
+ let content = document.getElementById("content");
appendElementWithText(content, "div", "legend", JSON.stringify(x));
}
--- a/toolkit/components/aboutmemory/tests/test_aboutmemory.xul
+++ b/toolkit/components/aboutmemory/tests/test_aboutmemory.xul
@@ -9,42 +9,42 @@
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml"></body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;
- var mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
+ let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
getService(Ci.nsIMemoryReporterManager);
// Access mgr.explicit and mgr.resident just to make sure they don't crash.
// We can't check their actual values because they're non-deterministic.
- var dummy = mgr.explicit;
+ let dummy = mgr.explicit;
dummy = mgr.resident;
// Remove all the real reporters and multi-reporters; save them to
// restore at the end.
- var e = mgr.enumerateReporters();
- var realReporters = [];
+ let e = mgr.enumerateReporters();
+ let realReporters = [];
dummy = 0;
while (e.hasMoreElements()) {
- var r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
+ let r = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
// Get the |amount| field, even though we don't use it, just to test
// that the reporter doesn't crash or anything.
dummy += r.amount;
mgr.unregisterReporter(r);
realReporters.push(r);
}
e = mgr.enumerateMultiReporters();
- var realMultiReporters = [];
- var dummy = 0;
+ let realMultiReporters = [];
+ let dummy = 0;
while (e.hasMoreElements()) {
- var r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
+ let r = e.getNext().QueryInterface(Ci.nsIMemoryMultiReporter);
// Call collectReports, even though we don't use its results, just to
// test that the multi-reporter doesn't crash or anything. And likewise
// for the |explicitNonHeap| field.
r.collectReports(function(){}, null);
dummy += r.explicitNonHeap;
mgr.unregisterMultiReporter(r);
realMultiReporters.push(r);
}
@@ -72,31 +72,31 @@
amount: aAmount
};
}
function f(aProcess, aPath, aKind, aAmount) {
return f2(aProcess, aPath, aKind, BYTES, aAmount);
}
- var fakeReporters = [
+ let fakeReporters = [
f("", "heap-allocated", OTHER, 500 * MB),
f("", "heap-unallocated", OTHER, 100 * MB),
f("", "explicit/a", HEAP, 222 * MB),
f("", "explicit/b/a", HEAP, 85 * MB),
f("", "explicit/b/b", HEAP, 75 * MB),
f("", "explicit/b/c/a", HEAP, 70 * MB),
f("", "explicit/b/c/b", HEAP, 2 * MB), // omitted
f("", "explicit/g/a", HEAP, 6 * MB),
f("", "explicit/g/b", HEAP, 5 * MB),
f("", "explicit/g/other", HEAP, 4 * MB),
f("", "other1", OTHER, 111 * MB),
f2("", "other4", OTHER, COUNT_CUMULATIVE, 888)
];
- var fakeMultiReporters = [
+ let fakeMultiReporters = [
{ name: "fake1",
collectReports: function(cbObj, closure) {
function f(p, k, u, a) { cbObj.callback("", p, k, u, a, "(desc)", closure); }
f("explicit/c/d", NONHEAP, BYTES, 13 * MB),
f("explicit/c/d", NONHEAP, BYTES, 10 * MB), // dup
f("explicit/c/other", NONHEAP, BYTES, 77 * MB),
f("explicit/cc", NONHEAP, BYTES, 13 * MB);
f("explicit/cc", NONHEAP, BYTES, 10 * MB); // dup
@@ -126,31 +126,31 @@
f("smaps/vsize/a", 19);
f("smaps/swap/b/c", 10);
f("smaps/resident/a", 42);
f("smaps/pss/a", 43);
},
explicitNonHeap: 0
}
];
- for (var i = 0; i < fakeReporters.length; i++) {
+ for (let i = 0; i < fakeReporters.length; i++) {
mgr.registerReporter(fakeReporters[i]);
}
- for (var i = 0; i < fakeMultiReporters.length; i++) {
+ for (let i = 0; i < fakeMultiReporters.length; i++) {
mgr.registerMultiReporter(fakeMultiReporters[i]);
}
// mgr.explicit sums "heap-allocated" and all the appropriate NONHEAP ones:
// - "explicit/c", "explicit/cc" x 2, "explicit/d", "explicit/e"
// - but *not* "explicit/c/d" x 2
// Check explicit now before we add the fake reporters for the fake 2nd
// and subsequent processes.
is(mgr.explicit, 500*MB + (100 + 13 + 10)*MB + 599*KB, "mgr.explicit");
- var fakeReporters2 = [
+ let fakeReporters2 = [
f("2nd", "heap-allocated", OTHER, 1000 * MB),
f("2nd", "heap-unallocated",OTHER, 100 * MB),
f("2nd", "explicit/a/b/c", HEAP, 497 * MB),
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
f("2nd", "explicit/a/b/c", HEAP, 1 * MB), // dup: merge
f("2nd", "explicit/flip\\the\\backslashes",
HEAP, 200 * MB),
f("2nd", "explicit/compartment(compartment-url)",
@@ -200,47 +200,47 @@
f("5th", "explicit/a/pos", HEAP, 40 * KB),
f("5th", "explicit/a/neg1", NONHEAP, -20 * KB),
f("5th", "explicit/a/neg2", NONHEAP, -10 * KB),
f("5th", "explicit/b/c/d/e", NONHEAP, 20 * KB),
f("5th", "explicit/b/c/d/f", NONHEAP, -60 * KB),
f("5th", "explicit/b/c/g/h", NONHEAP, 10 * KB),
f("5th", "explicit/b/c/i/j", NONHEAP, 5 * KB)
];
- var fakeMultiReporters2 = [
+ let fakeMultiReporters2 = [
// Because this multi-reporter is in a child process, the fact that we
// skip the "smaps" multi-reporter in the parent process won't cause
// these to be skipped; the fall-back skipping will be hit instead.
{ name: "smaps",
collectReports: function(cbObj, closure) {
// The amounts are given in pages, so multiply here by 4kb.
function f(p, a) { cbObj.callback("2nd", p, NONHEAP, BYTES, a * 4 * KB, "(desc)", closure); }
f("smaps/vsize/a", 24);
f("smaps/vsize/b", 24);
},
explicitNonHeap: 0
}
];
- for (var i = 0; i < fakeReporters2.length; i++) {
+ for (let i = 0; i < fakeReporters2.length; i++) {
mgr.registerReporter(fakeReporters2[i]);
}
- for (var i = 0; i < fakeMultiReporters2.length; i++) {
+ for (let i = 0; i < fakeMultiReporters2.length; i++) {
mgr.registerMultiReporter(fakeMultiReporters2[i]);
}
fakeReporters = fakeReporters.concat(fakeReporters2);
fakeMultiReporters = fakeMultiReporters.concat(fakeMultiReporters2);
]]>
</script>
<iframe id="amFrame" height="400" src="about:memory"></iframe>
<iframe id="amvFrame" height="400" src="about:memory?verbose"></iframe>
<script type="application/javascript">
<![CDATA[
- var amExpectedText =
+ let amExpectedText =
"\
Main Process\n\
\n\
Explicit Allocations\n\
623.58 MB (100.0%) -- explicit\n\
├──232.00 MB (37.20%) -- b\n\
│ ├───85.00 MB (13.63%) ── a\n\
│ ├───75.00 MB (12.03%) ── b\n\
@@ -370,17 +370,17 @@ 99.95 MB (100.0%) -- explicit\n\
├───0.02 MB (00.02%) ── e\n\
└──-0.06 MB (-0.06%) ── f [?!]\n\
\n\
Other Measurements\n\
100.00 MB ── heap-allocated\n\
\n\
";
- var amvExpectedText =
+ let amvExpectedText =
"\
Main Process\n\
\n\
Explicit Allocations\n\
653,876,224 B (100.0%) -- explicit\n\
├──243,269,632 B (37.20%) -- b\n\
│ ├───89,128,960 B (13.63%) ── a\n\
│ ├───78,643,200 B (12.03%) ── b\n\
@@ -534,32 +534,32 @@ 104,857,600 B ── heap-allocated\n\
\n\
"
function finish()
{
// Unregister fake reporters and multi-reporters, re-register the real
// reporters and multi-reporters, just in case subsequent tests rely on
// them.
- for (var i = 0; i < fakeReporters.length; i++) {
+ for (let i = 0; i < fakeReporters.length; i++) {
mgr.unregisterReporter(fakeReporters[i]);
}
- for (var i = 0; i < fakeMultiReporters.length; i++) {
+ for (let i = 0; i < fakeMultiReporters.length; i++) {
mgr.unregisterMultiReporter(fakeMultiReporters[i]);
}
- for (var i = 0; i < realReporters.length; i++) {
+ for (let i = 0; i < realReporters.length; i++) {
mgr.registerReporter(realReporters[i]);
}
- for (var i = 0; i < realMultiReporters.length; i++) {
+ for (let i = 0; i < realMultiReporters.length; i++) {
mgr.registerMultiReporter(realMultiReporters[i]);
}
SimpleTest.finish();
}
- var gHaveDumped = false;
+ let gHaveDumped = false;
function checkClipboard(actual, expected) {
if (actual != expected) {
if (!gHaveDumped) {
dump("******EXPECTED******\n");
dump(expected);
dump("*******ACTUAL*******\n");
dump(actual);