| Index: tools/profview/profile-utils.js
|
| diff --git a/tools/profview/profile-utils.js b/tools/profview/profile-utils.js
|
| index 02e7483fb8f8ba9009fab61523ee94c03d601876..9309d1dced244814507b08083b2b1995f2e897ac 100644
|
| --- a/tools/profview/profile-utils.js
|
| +++ b/tools/profview/profile-utils.js
|
| @@ -111,6 +111,47 @@ function addFrameToFrameList(paths, pathIndex, depth) {
|
| }
|
| }
|
|
|
| +function findNextFrame(file, stack, stackPos, step, filter) {
|
| + let codeId = -1;
|
| + let code = null;
|
| + while (stackPos >= 0 && stackPos < stack.length) {
|
| + codeId = stack[stackPos];
|
| + code = codeId >= 0 ? file.code[codeId] : undefined;
|
| + if (filter) {
|
| + let type = code ? code.type : undefined;
|
| + let kind = code ? code.kind : undefined;
|
| + if (filter(type, kind)) return stackPos;
|
| + }
|
| + stackPos += step;
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +function addOrUpdateChildNode(parent, file, stackIndex, stackPos, ascending) {
|
| + let stack = file.ticks[stackIndex].s;
|
| + let codeId = stack[stackPos];
|
| + let code = codeId >= 0 ? file.code[codeId] : undefined;
|
| + if (stackPos === -1) {
|
| + // We reached the end without finding the next step.
|
| + // If we are doing top-down call tree, update own ticks.
|
| + if (!ascending) {
|
| + parent.ownTicks++;
|
| + }
|
| + } else {
|
| + console.assert(stackPos >= 0 && stackPos < stack.length);
|
| + // We found a child node.
|
| + let childId = childIdFromCode(codeId, code);
|
| + let child = parent.children[childId];
|
| + if (!child) {
|
| + child = createNodeFromStackEntry(code);
|
| + child.delayedExpansion = { frameList : [], ascending };
|
| + parent.children[childId] = child;
|
| + }
|
| + child.ticks++;
|
| + addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, stackPos);
|
| + }
|
| +}
|
| +
|
| // This expands a tree node (direct children only).
|
| function expandTreeNode(file, node, filter) {
|
| let { frameList, ascending } = node.delayedExpansion;
|
| @@ -118,80 +159,21 @@ function expandTreeNode(file, node, filter) {
|
| let step = ascending ? 2 : -2;
|
|
|
| for (let i = 0; i < frameList.length; i+= 3) {
|
| - let stackIndex = frameList[i];
|
| + let firstStackIndex = frameList[i];
|
| let depth = frameList[i + 1];
|
| let count = frameList[i + 2];
|
| for (let j = 0; j < count; j++) {
|
| - let tick = file.ticks[stackIndex + j];
|
| - let stack = tick.s;
|
| + let stackIndex = firstStackIndex + j;
|
| + let stack = file.ticks[stackIndex].s;
|
|
|
| // Get to the next frame that has not been filtered out.
|
| - let k = depth + step;
|
| - let codeId = -1;
|
| - let code = null;
|
| - while (k >= 0 && k < stack.length) {
|
| - codeId = stack[k];
|
| - code = codeId >= 0 ? file.code[codeId] : undefined;
|
| - if (filter) {
|
| - let type = code ? code.type : undefined;
|
| - let kind = code ? code.kind : undefined;
|
| - if (filter(type, kind)) break;
|
| - }
|
| - k += step;
|
| - }
|
| - if (k < 0 || k >= stack.length) {
|
| - // We reached the end without finding the next step.
|
| - // If we are doing top-down call tree, update own ticks.
|
| - if (!ascending) {
|
| - node.ownTicks++;
|
| - }
|
| - } else {
|
| - // We found a child node.
|
| - let childId = childIdFromCode(codeId, code);
|
| - let child = node.children[childId];
|
| - if (!child) {
|
| - child = createNodeFromStackEntry(code);
|
| - child.delayedExpansion = { frameList : [], ascending };
|
| - node.children[childId] = child;
|
| - }
|
| - child.ticks++;
|
| - addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, k);
|
| - }
|
| + let stackPos = findNextFrame(file, stack, depth + step, step, filter);
|
| + addOrUpdateChildNode(node, file, stackIndex, stackPos, ascending);
|
| }
|
| }
|
| node.delayedExpansion = null;
|
| }
|
|
|
| -function addStackToTree(file, stack, tree, filter, ascending, start) {
|
| - if (start === undefined) {
|
| - start = ascending ? 0 : stack.length - 2;
|
| - }
|
| - tree.ticks++;
|
| - for (let i = start;
|
| - ascending ? (i < stack.length) : (i >= 0);
|
| - i += ascending ? 2 : -2) {
|
| - let codeId = stack[i];
|
| - let code = codeId >= 0 ? file.code[codeId] : undefined;
|
| - if (filter) {
|
| - let type = code ? code.type : undefined;
|
| - let kind = code ? code.kind : undefined;
|
| - if (!filter(type, kind)) continue;
|
| - }
|
| -
|
| - // For JavaScript function, pretend there is one instance of optimized
|
| - // function and one instance of unoptimized function per SFI.
|
| - let childId = childIdFromCode(codeId, code);
|
| - let child = tree.children[childId];
|
| - if (!child) {
|
| - child = createNodeFromStackEntry(code);
|
| - tree.children[childId] = child;
|
| - }
|
| - child.ticks++;
|
| - tree = child;
|
| - }
|
| - tree.ownTicks++;
|
| -}
|
| -
|
| function createEmptyNode(name) {
|
| return {
|
| name : name,
|
| @@ -206,12 +188,19 @@ class PlainCallTreeProcessor {
|
| constructor(filter, isBottomUp) {
|
| this.filter = filter;
|
| this.tree = createEmptyNode("root");
|
| + this.tree.delayedExpansion = { frameList : [], ascending : isBottomUp };
|
| this.isBottomUp = isBottomUp;
|
| }
|
|
|
| addStack(file, tickIndex) {
|
| let stack = file.ticks[tickIndex].s;
|
| - addStackToTree(file, stack, this.tree, this.filter, this.isBottomUp);
|
| + let step = this.isBottomUp ? 2 : -2;
|
| + let start = this.isBottomUp ? 0 : stack.length - 2;
|
| +
|
| + let stackPos = findNextFrame(file, stack, start, step, this.filter);
|
| + addOrUpdateChildNode(this.tree, file, tickIndex, stackPos, this.isBottomUp);
|
| +
|
| + this.tree.ticks++;
|
| }
|
| }
|
|
|
| @@ -259,10 +248,13 @@ class CategorizedCallTreeProcessor {
|
| let node = this.categories[kind];
|
|
|
| this.tree.ticks++;
|
| + node.ticks++;
|
|
|
| - console.assert(node);
|
| + let step = this.isBottomUp ? 2 : -2;
|
| + let start = this.isBottomUp ? 0 : stack.length - 2;
|
|
|
| - addStackToTree(file, stack, node, this.filter, this.isBottomUp);
|
| + let stackPos = findNextFrame(file, stack, start, step, this.filter);
|
| + addOrUpdateChildNode(node, file, tickIndex, stackPos, this.isBottomUp);
|
| }
|
| }
|
|
|
|
|