зеркало из https://github.com/mozilla/gecko-dev.git
Bug 757299 (part 7) - Remove TreeNode._kind in aboutMemory.js. r=jlebar.
--HG-- extra : rebase_source : fc6bcb81d9e14a6e311ef3dedff738b69d5d9d11
This commit is contained in:
Родитель
87b15e37b5
Коммит
45df4caf67
|
@ -411,19 +411,22 @@ function updateAboutMemory()
|
|||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||
getService(Ci.nsIMemoryReporterManager);
|
||||
|
||||
let treesByProcess = {}, othersByProcess = {};
|
||||
getTreesAndOthersByProcess(mgr, treesByProcess, othersByProcess);
|
||||
let treesByProcess = {}, othersByProcess = {}, heapTotalByProcess = {};
|
||||
getTreesAndOthersByProcess(mgr, treesByProcess, othersByProcess,
|
||||
heapTotalByProcess);
|
||||
|
||||
// Generate output for one process at a time. Always start with the
|
||||
// Main process.
|
||||
let hasMozMallocUsableSize = mgr.hasMozMallocUsableSize;
|
||||
appendProcessAboutMemoryElements(body, "Main", treesByProcess["Main"],
|
||||
othersByProcess["Main"],
|
||||
heapTotalByProcess["Main"],
|
||||
hasMozMallocUsableSize);
|
||||
for (let process in treesByProcess) {
|
||||
if (process !== "Main") {
|
||||
appendProcessAboutMemoryElements(body, process, treesByProcess[process],
|
||||
othersByProcess[process],
|
||||
heapTotalByProcess[process],
|
||||
hasMozMallocUsableSize);
|
||||
}
|
||||
}
|
||||
|
@ -493,8 +496,12 @@ function updateAboutMemory()
|
|||
* @param aOthersByProcess
|
||||
* Table of other lists, indexed by process, which this function appends
|
||||
* to.
|
||||
* @param aHeapTotalByProcess
|
||||
* Table of heap total counts, indexed by process, which this function
|
||||
* appends to.
|
||||
*/
|
||||
function getTreesAndOthersByProcess(aMgr, aTreesByProcess, aOthersByProcess)
|
||||
function getTreesAndOthersByProcess(aMgr, aTreesByProcess, aOthersByProcess,
|
||||
aHeapTotalByProcess)
|
||||
{
|
||||
// Ignore the "smaps" multi-reporter in non-verbose mode, and the
|
||||
// "compartments" and "ghost-windows" multi-reporters all the time. (Note
|
||||
|
@ -555,8 +562,20 @@ function getTreesAndOthersByProcess(aMgr, aTreesByProcess, aOthersByProcess)
|
|||
} else {
|
||||
// New leaf node. Fill in extra details node from the report.
|
||||
u._amount = aAmount;
|
||||
if (unsafeNames[0] === "explicit") {
|
||||
u._description = kindToString(aKind) + aDescription;
|
||||
} else {
|
||||
// We don't want to show '(Non-heap)' on an smaps tree because
|
||||
// the whole tree is non-heap.
|
||||
u._description = aDescription;
|
||||
u._kind = aKind;
|
||||
}
|
||||
}
|
||||
|
||||
if (unsafeNames[0] === "explicit" && aKind == KIND_HEAP) {
|
||||
if (!aHeapTotalByProcess[process]) {
|
||||
aHeapTotalByProcess[process] = 0;
|
||||
}
|
||||
aHeapTotalByProcess[process] += aAmount;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -590,7 +609,6 @@ function TreeNode(aUnsafeName)
|
|||
// Leaf TreeNodes have these properties added immediately after construction:
|
||||
// - _amount
|
||||
// - _description
|
||||
// - _kind
|
||||
// - _nMerged (only defined if > 1)
|
||||
//
|
||||
// Non-leaf TreeNodes have these properties added later:
|
||||
|
@ -649,12 +667,10 @@ function fillInTree(aTreeOfTrees, aTreePrefix)
|
|||
{
|
||||
if (!aT._kids) {
|
||||
// Leaf node. Has already been filled in.
|
||||
assert(aT._kind !== undefined, "aT._kind is undefined for leaf node");
|
||||
|
||||
} else if (aT._kids.length === 1 && !aCannotMerge) {
|
||||
// Non-leaf node with one child. Merge the child with the node to avoid
|
||||
// redundant entries.
|
||||
assert(aT._kind === undefined, "aT._kind is defined for non-leaf node");
|
||||
let kid = aT._kids[0];
|
||||
let kidBytes = fillInNonLeafNodes(kid);
|
||||
aT._unsafeName += '/' + kid._unsafeName;
|
||||
|
@ -665,9 +681,6 @@ function fillInTree(aTreeOfTrees, aTreePrefix)
|
|||
}
|
||||
aT._amount = kid._amount;
|
||||
aT._description = kid._description;
|
||||
if (kid._kind !== undefined) {
|
||||
aT._kind = kid._kind;
|
||||
}
|
||||
if (kid._nMerged !== undefined) {
|
||||
aT._nMerged = kid._nMerged
|
||||
}
|
||||
|
@ -676,7 +689,6 @@ function fillInTree(aTreeOfTrees, aTreePrefix)
|
|||
} else {
|
||||
// Non-leaf node with multiple children. Derive its _amount and
|
||||
// _description entirely from its children.
|
||||
assert(aT._kind === undefined, "aT._kind is defined for non-leaf node");
|
||||
let kidsBytes = 0;
|
||||
for (let i = 0; i < aT._kids.length; i++) {
|
||||
kidsBytes += fillInNonLeafNodes(aT._kids[i]);
|
||||
|
@ -697,47 +709,30 @@ function fillInTree(aTreeOfTrees, aTreePrefix)
|
|||
}
|
||||
|
||||
/**
|
||||
* Do some work which only makes sense for the 'explicit' tree.
|
||||
* Compute the "heap-unclassified" value and insert it into the "explicit"
|
||||
* tree.
|
||||
*
|
||||
* @param aT
|
||||
* The tree.
|
||||
* The "explicit" tree.
|
||||
* @param aOthers
|
||||
* "Other measurements" for this process, indexed by _unsafePath.
|
||||
* @param aHeapTotal
|
||||
* The sum of all explicit HEAP reporters for this process.
|
||||
* @return A boolean indicating if "heap-allocated" is known for the process.
|
||||
*/
|
||||
function fixUpExplicitTree(aT, aOthers)
|
||||
function addHeapUnclassifiedNode(aT, aOthers, aHeapTotal)
|
||||
{
|
||||
// Determine how many bytes are in heap reports.
|
||||
function getKnownHeapUsedBytes(aT)
|
||||
{
|
||||
let n = 0;
|
||||
if (!aT._kids) {
|
||||
// Leaf node.
|
||||
assert(aT._kind !== undefined, "aT._kind is undefined for leaf node");
|
||||
n = aT._kind === KIND_HEAP ? aT._amount : 0;
|
||||
} else {
|
||||
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.
|
||||
let heapAllocatedReport = aOthers["heap-allocated"];
|
||||
if (heapAllocatedReport === undefined)
|
||||
return false;
|
||||
|
||||
let heapAllocatedBytes = heapAllocatedReport._amount;
|
||||
let heapUnclassifiedT = new TreeNode("heap-unclassified");
|
||||
heapUnclassifiedT._amount = heapAllocatedBytes - getKnownHeapUsedBytes(aT);
|
||||
heapUnclassifiedT._description =
|
||||
heapUnclassifiedT._amount = heapAllocatedBytes - aHeapTotal;
|
||||
heapUnclassifiedT._description = kindToString(KIND_HEAP) +
|
||||
"Memory not classified by a more specific reporter. This includes " +
|
||||
"slop bytes due to internal fragmentation in the heap allocator " +
|
||||
"(caused when the allocator rounds up request sizes).";
|
||||
heapUnclassifiedT._kind = KIND_HEAP;
|
||||
aT._kids.push(heapUnclassifiedT);
|
||||
aT._amount += heapUnclassifiedT._amount;
|
||||
return true;
|
||||
|
@ -886,7 +881,7 @@ function appendWarningElements(aP, aHasKnownHeapAllocated,
|
|||
* @return The generated text.
|
||||
*/
|
||||
function appendProcessAboutMemoryElements(aP, aProcess, aTreeOfTrees, aOthers,
|
||||
aHasMozMallocUsableSize)
|
||||
aHeapTotal, aHasMozMallocUsableSize)
|
||||
{
|
||||
appendElementWithText(aP, "h1", "", aProcess + " Process\n\n");
|
||||
|
||||
|
@ -894,7 +889,8 @@ function appendProcessAboutMemoryElements(aP, aProcess, aTreeOfTrees, aOthers,
|
|||
let warningsDiv = appendElement(aP, "div", "accuracyWarning");
|
||||
|
||||
let explicitTree = fillInTree(aTreeOfTrees, "explicit/");
|
||||
let hasKnownHeapAllocated = fixUpExplicitTree(explicitTree, aOthers);
|
||||
let hasKnownHeapAllocated =
|
||||
addHeapUnclassifiedNode(explicitTree, aOthers, aHeapTotal);
|
||||
sortTreeAndInsertAggregateNodes(explicitTree._amount, explicitTree);
|
||||
appendTreeElements(aP, explicitTree, aProcess);
|
||||
|
||||
|
@ -1067,20 +1063,19 @@ function kindToString(aKind)
|
|||
case KIND_NONHEAP: return "(Non-heap) ";
|
||||
case KIND_HEAP: return "(Heap) ";
|
||||
case KIND_OTHER:
|
||||
case undefined: return "";
|
||||
case undefined:
|
||||
default: assert(false, "bad kind in kindToString");
|
||||
}
|
||||
}
|
||||
|
||||
function appendMrNameSpan(aP, aKind, aDescription, aUnsafeName,
|
||||
aIsInvalid, aNMerged)
|
||||
function appendMrNameSpan(aP, aDescription, aUnsafeName, aIsInvalid, aNMerged)
|
||||
{
|
||||
let safeName = flipBackslashes(aUnsafeName);
|
||||
if (!aIsInvalid && !aNMerged) {
|
||||
safeName += "\n";
|
||||
}
|
||||
let nameSpan = appendElementWithText(aP, "span", "mrName", safeName);
|
||||
nameSpan.title = kindToString(aKind) + aDescription;
|
||||
nameSpan.title = aDescription;
|
||||
|
||||
if (aIsInvalid) {
|
||||
let noteText = " [?!]";
|
||||
|
@ -1284,10 +1279,7 @@ function appendTreeElements(aPOuter, aT, aProcess)
|
|||
appendElementWithText(d, "span", "mrPerc", percText);
|
||||
appendElementWithText(d, "span", "mrSep", sep);
|
||||
|
||||
// We don't want to show '(nonheap)' on a tree like 'vsize/', since
|
||||
// the whole tree is non-heap.
|
||||
let kind = isExplicitTree ? aT._kind : undefined;
|
||||
appendMrNameSpan(d, kind, aT._description, aT._unsafeName,
|
||||
appendMrNameSpan(d, aT._description, aT._unsafeName,
|
||||
tIsInvalid, aT._nMerged);
|
||||
|
||||
// In non-verbose mode, invalid nodes can be hidden in collapsed sub-trees.
|
||||
|
@ -1338,7 +1330,6 @@ function appendTreeElements(aPOuter, aT, aProcess)
|
|||
|
||||
function OtherReport(aUnsafePath, aUnits, aAmount, aDescription, aNMerged)
|
||||
{
|
||||
// Nb: _kind is not needed, it's always KIND_OTHER.
|
||||
this._unsafePath = aUnsafePath;
|
||||
this._units = aUnits;
|
||||
this._amount = aAmount;
|
||||
|
@ -1416,8 +1407,7 @@ function appendOtherElements(aP, aOthers)
|
|||
}
|
||||
appendMrValueSpan(pre, pad(o._asString, maxStringLength, ' '), oIsInvalid);
|
||||
appendElementWithText(pre, "span", "mrSep", kNoKidsSep);
|
||||
appendMrNameSpan(pre, KIND_OTHER, o._description, o._unsafePath,
|
||||
oIsInvalid);
|
||||
appendMrNameSpan(pre, o._description, o._unsafePath, oIsInvalid);
|
||||
}
|
||||
|
||||
appendTextNode(aP, "\n"); // gives nice spacing when we cut and paste
|
||||
|
|
Загрузка…
Ссылка в новой задаче