Bug 1217158 - Aggregate total counts/bytes in CensusTreeNode; r=jsantell

This commit is contained in:
Nick Fitzgerald 2015-10-21 12:53:00 -04:00
parent 5ec0fb8ccd
commit 95a7386f6e
7 changed files with 265 additions and 125 deletions

View File

@ -46,14 +46,14 @@ window.onload = function() {
};
const EXPECTED_ROWS = [
{ level: 0, name: "scripts", bytes: 20, count: 2, },
{ level: 0, name: "strings", bytes: 10, count: 1, },
{ level: 0, name: "objects" },
{ level: 1, name: "Array", bytes: 20, count: 2, },
{ level: 1, name: "Function", bytes: 10, count: 1, },
{ level: 0, name: "other" },
{ level: 0, name: "other", bytes: 0, count: 0 },
{ level: 1, name: "js::Shape2", bytes: 40, count: 4, },
{ level: 1, name: "js::Shape", bytes: 30, count: 3, },
{ level: 0, name: "objects", bytes: 0, count: 0 },
{ level: 1, name: "Array", bytes: 20, count: 2, },
{ level: 1, name: "Function", bytes: 10, count: 1, },
{ level: 0, name: "scripts", bytes: 20, count: 2, },
{ level: 0, name: "strings", bytes: 10, count: 1, },
];
var censusTreeNode = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
@ -84,14 +84,14 @@ window.onload = function() {
is(bytesEl.innerHTML, String(expected.bytes),
`correct bytes "${expected.bytes}" in heap tree`);
} else {
ok(!bytesEl, "no bytes correctly displayed for ${expected.name}");
ok(!bytesEl, `no bytes correctly displayed for ${expected.name}`);
}
if ("count" in expected) {
is(countEl.innerHTML, String(expected.count),
`correct count "${expected.count}" in heap tree`);
} else {
ok(!countEl, "no count correctly displayed for ${expected.name}");
ok(!countEl, `no count correctly displayed for ${expected.name}`);
}
}

View File

@ -264,32 +264,35 @@ function values(cache) {
* @overrides Visitor.prototype.exit
*/
CensusTreeNodeVisitor.prototype.exit = function (breakdown, report, edge) {
// Ensure all children are sorted and have their counts/bytes aggregated. We
// only need to consider cache children here, because other children
// correspond to other sub-reports and we already fixed them up in an earlier
// invocation of `exit`.
function dfs(node, childrenCache) {
if (childrenCache) {
const childValues = values(childrenCache);
for (let i = 0, length = childValues.length; i < length; i++) {
dfs(childValues[i].node, childValues[i].children);
}
}
node.totalCount = node.count;
node.totalBytes = node.bytes;
if (node.children) {
node.children.sort(compareByTotalBytes);
for (let i = 0, length = node.children.length; i < length; i++) {
node.totalCount += node.children[i].totalCount;
node.totalBytes += node.children[i].totalBytes;
}
}
}
const top = this._nodeStack.pop();
if (top.children) {
top.children.sort(compareByBytes);
}
const cache = this._frameCacheStack.pop();
const toSort = values(cache);
while (toSort.length) {
const { node, children } = toSort.pop();
if (!node.children) {
continue;
}
if (node !== top) {
node.children.sort(compareByBytes);
}
if (!children) {
continue;
}
const newlyNeedSorting = values(children);
for (let i = 0, length = newlyNeedSorting.length; i < length; i++) {
toSort.push(newlyNeedSorting[i]);
}
}
dfs(top, cache);
};
/**
@ -331,15 +334,18 @@ CensusTreeNodeVisitor.prototype.root = function () {
*/
function CensusTreeNode (name) {
this.name = name;
this.bytes = undefined;
this.count = undefined;
this.bytes = 0;
this.totalBytes = 0;
this.count = 0;
this.totalCount = 0;
this.children = undefined;
}
CensusTreeNode.prototype = null;
/**
* Compare the given nodes by their `bytes` properties.
* Compare the given nodes by their `totalBytes` properties, and breaking ties
* with the `bytes`, `totalCount`, and `count` properties (in that order).
*
* @param {CensusTreeNode} node1
* @param {CensusTreeNode} node2
@ -347,8 +353,11 @@ CensusTreeNode.prototype = null;
* @returns {Number}
* A number suitable for using with Array.prototype.sort.
*/
function compareByBytes (node1, node2) {
return (node2.bytes || 0) - (node1.bytes || 0);
function compareByTotalBytes (node1, node2) {
return node2.totalBytes - node1.totalBytes
|| node2.bytes - node1.bytes
|| node2.totalCount - node1.totalCount
|| node2.count - node1.count;
}
/**

View File

@ -27,12 +27,35 @@ const REPORT = {
const EXPECTED = {
name: null,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 600,
count: 0,
totalCount: 60,
children: [
{ name: "js::Shape", bytes: 500, count: 50, children: undefined },
{ name: "JSObject", bytes: 100, count: 10, children: undefined },
{ name: "JSString", bytes: 0, count: 0, children: undefined },
{
name: "js::Shape",
bytes: 500,
totalBytes: 500,
count: 50,
totalCount: 50,
children: undefined
},
{
name: "JSObject",
bytes: 100,
totalBytes: 100,
count: 10,
totalCount: 10,
children: undefined
},
{
name: "JSString",
bytes: 0,
totalBytes: 0,
count: 0,
totalCount: 0,
children: undefined
},
],
};

View File

@ -30,39 +30,77 @@ const REPORT = {
const EXPECTED = {
name: null,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 111,
count: 0,
totalCount: 12,
children: [
{
name: "other",
count: 0,
totalCount: 7,
bytes: 0,
totalBytes: 70,
children: [
{
name: "js::Shape2",
bytes: 40,
totalBytes: 40,
count: 4,
totalCount: 4,
children: undefined
},
{
name: "js::Shape",
bytes: 30,
totalBytes: 30,
count: 3,
totalCount: 3,
children: undefined
},
]
},
{
name: "objects",
count: 0,
totalCount: 3,
bytes: 0,
totalBytes: 30,
children: [
{
name: "Array",
bytes: 20,
totalBytes: 20,
count: 2,
totalCount: 2,
children: undefined
},
{
name: "Function",
bytes: 10,
totalBytes: 10,
count: 1,
totalCount: 1,
children: undefined
},
]
},
{
name: "strings",
count: 1,
totalCount: 1,
bytes: 10,
totalBytes: 10,
children: undefined
},
{
name: "scripts",
count: 1,
totalCount: 1,
bytes: 1,
totalBytes: 1,
children: undefined
},
{
name: "objects",
count: undefined,
bytes: undefined,
children: [
{ name: "Array", bytes: 20, count: 2, children: undefined },
{ name: "Function", bytes: 10, count: 1, children: undefined },
]
},
{
name: "other",
count: undefined,
bytes: undefined,
children: [
{ name: "js::Shape2", bytes: 40, count: 4, children: undefined },
{ name: "js::Shape", bytes: 30, count: 3, children: undefined },
]
},
]
};

View File

@ -24,20 +24,52 @@ const REPORT = {
const EXPECTED = {
name: null,
count: undefined,
bytes: undefined,
count: 0,
totalCount: 17,
bytes: 0,
totalBytes: 170,
children: [
{ name: "Array", bytes: 100, count: 1, children: undefined },
{ name: "Function", bytes: 10, count: 10, children: undefined },
{
name: "Array",
bytes: 100,
totalBytes: 100,
count: 1,
totalCount: 1,
children: undefined
},
{
name: "other",
count: undefined,
bytes: undefined,
count: 0,
totalCount: 6,
bytes: 0,
totalBytes: 60,
children: [
{ name: "JIT::CODE::LATER!!!", bytes: 40, count: 4, children: undefined },
{ name: "JIT::CODE::NOW!!!", bytes: 20, count: 2, children: undefined },
{
name: "JIT::CODE::LATER!!!",
bytes: 40,
totalBytes: 40,
count: 4,
totalCount: 4,
children: undefined
},
{
name: "JIT::CODE::NOW!!!",
bytes: 20,
totalBytes: 20,
count: 2,
totalCount: 2,
children: undefined
},
]
}
},
{
name: "Function",
bytes: 10,
totalBytes: 10,
count: 10,
totalCount: 10,
children: undefined
},
]
};

View File

@ -42,66 +42,86 @@ function run_test() {
const EXPECTED = {
name: null,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 210,
count: 0,
totalCount: 21,
children: [
{
name: "noStack",
bytes: 60,
count: 6,
children: undefined
},
{
name: stack5,
bytes: 50,
count: 5,
children: undefined
},
{
name: stack4.parent,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 100,
count: 0,
totalCount: 10,
children: [
{
name: stack4,
bytes: 40,
count: 4,
children: undefined
},
{
name: stack1.parent,
bytes: undefined,
count: undefined,
children: [
{
name: stack1,
bytes: 10,
count: 1,
children: undefined
},
]
},
{
name: stack3.parent,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 50,
count: 0,
totalCount: 5,
children: [
{
name: stack3,
bytes: 30,
totalBytes: 30,
count: 3,
totalCount: 3,
children: undefined
},
{
name: stack2,
bytes: 20,
totalBytes: 20,
count: 2,
totalCount: 2,
children: undefined
}
]
}
},
{
name: stack4,
bytes: 40,
totalBytes: 40,
count: 4,
totalCount: 4,
children: undefined
},
{
name: stack1.parent,
bytes: 0,
totalBytes: 10,
count: 0,
totalCount: 1,
children: [
{
name: stack1,
bytes: 10,
totalBytes: 10,
count: 1,
totalCount: 1,
children: undefined
},
]
},
]
}
},
{
name: "noStack",
bytes: 60,
totalBytes: 60,
count: 6,
totalCount: 6,
children: undefined
},
{
name: stack5,
bytes: 50,
totalBytes: 50,
count: 5,
totalCount: 5,
children: undefined
},
]
};

View File

@ -39,52 +39,62 @@ function run_test() {
const EXPECTED = {
name: null,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 150,
count: 0,
totalCount: 15,
children: [
{
name: "noStack",
bytes: 50,
count: 5,
children: undefined
},
{
name: stack.parent.parent,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 100,
count: 0,
totalCount: 10,
children: [
{
name: stack.parent,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 100,
count: 0,
totalCount: 10,
children: [
{
name: stack,
bytes: undefined,
count: undefined,
bytes: 0,
totalBytes: 100,
count: 0,
totalCount: 10,
children: [
{
name: "other",
bytes: 40,
totalBytes: 40,
count: 4,
totalCount: 4,
children: undefined
},
{
name: "Baz",
bytes: 30,
totalBytes: 30,
count: 3,
totalCount: 3,
children: undefined
},
{
name: "Bar",
bytes: 20,
totalBytes: 20,
count: 2,
totalCount: 2,
children: undefined
},
{
name: "Foo",
bytes: 10,
totalBytes: 10,
count: 1,
totalCount: 1,
children: undefined
},
]
@ -92,7 +102,15 @@ function run_test() {
]
}
]
}
},
{
name: "noStack",
bytes: 50,
totalBytes: 50,
count: 5,
totalCount: 5,
children: undefined
},
]
};