From 45df4caf6747bd228ad232f889260b9bfd86d79c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 27 May 2012 18:15:00 -0700 Subject: [PATCH] Bug 757299 (part 7) - Remove TreeNode._kind in aboutMemory.js. r=jlebar. --HG-- extra : rebase_source : fc6bcb81d9e14a6e311ef3dedff738b69d5d9d11 --- .../aboutmemory/content/aboutMemory.js | 90 +++++++++---------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/toolkit/components/aboutmemory/content/aboutMemory.js b/toolkit/components/aboutmemory/content/aboutMemory.js index 2aaf8cbbbd66..01213dd97273 100644 --- a/toolkit/components/aboutmemory/content/aboutMemory.js +++ b/toolkit/components/aboutmemory/content/aboutMemory.js @@ -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; - u._description = aDescription; - u._kind = aKind; + 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; + } + } + + 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