remove dependency between aggrow and stackRegistry

Reviewed By: bnham

Differential Revision: D3876267

fbshipit-source-id: 2ad7e70445f3f4641cde554e94de000403368233
This commit is contained in:
Charles Dick
2016-10-06 07:52:35 -07:00
committed by Facebook Github Bot
parent 1502e66c31
commit 217a4449d4
7 changed files with 108 additions and 82 deletions

View File

@@ -46,17 +46,16 @@ function stackData(stackIdMap, maxDepth) { // eslint-disable-line no-unused-vars
};
}
function stackRegistry(interner) { // eslint-disable-line no-unused-vars
function stackRegistry() { // eslint-disable-line no-unused-vars
return {
root: { id: 0 },
nodeCount: 1,
insert: function insertNode(parent, label) {
const labelId = interner.intern(label);
let node = parent[labelId];
insert: function insertNode(parent, frameId) {
let node = parent[frameId];
if (node === undefined) {
node = { id: this.nodeCount };
this.nodeCount++;
parent[labelId] = node;
parent[frameId] = node;
}
return node;
},
@@ -116,7 +115,7 @@ function stackRegistry(interner) { // eslint-disable-line no-unused-vars
};
}
function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-vars
function aggrow(numRows) { // eslint-disable-line no-unused-vars
// expander ID definitions
const FIELD_EXPANDER_ID_MIN = 0x0000;
const FIELD_EXPANDER_ID_MAX = 0x7fff;
@@ -142,17 +141,17 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
const NODE_REPOSITION_BIT = 0x0008; // children need position
const NODE_INDENT_SHIFT = 16;
function calleeFrameGetter(stack, depth) {
function calleeFrameIdGetter(stack, depth) {
return stack[depth];
}
function callerFrameGetter(stack, depth) {
function callerFrameIdGetter(stack, depth) {
return stack[stack.length - depth - 1];
}
function createStackComparers(stackGetter, frameGetter) {
const comparers = new Array(stacks.maxDepth);
for (let depth = 0; depth < stacks.maxDepth; depth++) {
function createStackComparers(stackGetter, frameIdGetter, maxStackDepth) {
const comparers = new Array(maxStackDepth);
for (let depth = 0; depth < maxStackDepth; depth++) {
const captureDepth = depth; // NB: to capture depth per loop iteration
comparers[depth] = function calleeStackComparer(rowA, rowB) {
const a = stackGetter(rowA);
@@ -166,7 +165,7 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
} else if (b.length <= captureDepth) {
return 1;
}
return frameGetter(a, captureDepth) - frameGetter(b, captureDepth);
return frameIdGetter(a, captureDepth) - frameIdGetter(b, captureDepth);
};
}
return comparers;
@@ -325,6 +324,7 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
function addChildrenWithStackExpander(row, expander, activeIndex, depth, nextActiveIndex) {
const rowIndices = row.indices;
const stackGetter = expander.stackGetter;
const frameIdGetter = expander.frameIdGetter;
const frameGetter = expander.frameGetter;
const comparer = expander.comparers[depth];
const expandNextFrame = activeIndex | ((depth + 1) << ACTIVE_EXPANDER_FRAME_SHIFT);
@@ -357,10 +357,10 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
let end = begin + 1;
while (end < rowIndices.length) {
const endStack = stackGetter(rowIndices[end]);
if (frameGetter(beginStack, depth) !== frameGetter(endStack, depth)) {
if (frameIdGetter(beginStack, depth) !== frameIdGetter(endStack, depth)) {
row.children.push(createTreeNode(
row,
columnName + strings.get(frameGetter(beginStack, depth)),
columnName + frameGetter(frameIdGetter(beginStack, depth)),
rowIndices.subarray(begin, end),
expandNextFrame));
begin = end;
@@ -370,7 +370,7 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
}
row.children.push(createTreeNode(
row,
columnName + strings.get(frameGetter(beginStack, depth)),
columnName + frameGetter(frameIdGetter(beginStack, depth)),
rowIndices.subarray(begin, end),
expandNextFrame));
}
@@ -418,27 +418,29 @@ function aggrow(strings, stacks, numRows) { // eslint-disable-line no-unused-var
});
return FIELD_EXPANDER_ID_MIN + state.fieldExpanders.length - 1;
},
addCalleeStackExpander: function addCalleeStackExpander(name, stackGetter) {
addCalleeStackExpander: function addCalleeStackExpander(name, maxStackDepth, stackGetter, frameGetter) {
if (STACK_EXPANDER_ID_MIN + state.fieldExpanders.length >= STACK_EXPANDER_ID_MAX) {
throw 'too many stack expanders!';
}
state.stackExpanders.push({
name: name, // name for column
stackGetter: stackGetter, // row index -> stack array
comparers: createStackComparers(stackGetter, calleeFrameGetter), // depth -> comparer
frameGetter: calleeFrameGetter, // (stack, depth) -> string id
comparers: createStackComparers(stackGetter, calleeFrameIdGetter, maxStackDepth), // depth -> comparer
frameIdGetter: calleeFrameIdGetter, // (stack, depth) -> string id
frameGetter: frameGetter,
});
return STACK_EXPANDER_ID_MIN + state.stackExpanders.length - 1;
},
addCallerStackExpander: function addCallerStackExpander(name, stackGetter) {
addCallerStackExpander: function addCallerStackExpander(name, maxStackDepth, stackGetter, frameGetter) {
if (STACK_EXPANDER_ID_MIN + state.fieldExpanders.length >= STACK_EXPANDER_ID_MAX) {
throw 'too many stack expanders!';
}
state.stackExpanders.push({
name: name,
stackGetter: stackGetter,
comparers: createStackComparers(stackGetter, callerFrameGetter),
frameGetter: callerFrameGetter,
comparers: createStackComparers(stackGetter, callerFrameIdGetter, maxStackDepth),
frameIdGetter: callerFrameIdGetter,
frameGetter: frameGetter,
});
return STACK_EXPANDER_ID_MIN + state.stackExpanders.length - 1;
},

View File

@@ -145,28 +145,28 @@ function getInternalInstanceName(visitor) {
return '#unknown';
}
function buildReactComponentTree(visitor, registry) {
function buildReactComponentTree(visitor, registry, strings) {
const ref = visitor.getRef();
if (ref.reactTree || ref.reactParent === undefined) {
return; // has one or doesn't need one
}
const parentVisitor = ref.reactParent;
if (parentVisitor === null) {
ref.reactTree = registry.insert(registry.root, getInternalInstanceName(visitor));
ref.reactTree = registry.insert(registry.root, strings.intern(getInternalInstanceName(visitor)));
} else if (parentVisitor) {
const parentRef = parentVisitor.getRef();
buildReactComponentTree(parentVisitor, registry);
buildReactComponentTree(parentVisitor, registry, strings);
let relativeName = getInternalInstanceName(visitor);
if (ref.reactKey) {
relativeName = ref.reactKey + ': ' + relativeName;
}
ref.reactTree = registry.insert(parentRef.reactTree, relativeName);
ref.reactTree = registry.insert(parentRef.reactTree, strings.intern(relativeName));
} else {
throw 'non react instance parent of react instance';
}
}
function markReactComponentTree(refs, registry) {
function markReactComponentTree(refs, registry, strings) {
// annotate all refs that are react internal instances with their parent and name
// ref.reactParent = visitor that points to parent instance,
// null if we know it's an instance, but don't have a parent yet
@@ -201,7 +201,7 @@ function markReactComponentTree(refs, registry) {
// build tree of react internal instances (since that's what has the structure)
// fill in ref.reactTree = path registry node
forEachRef(refs, (visitor) => {
buildReactComponentTree(visitor, registry);
buildReactComponentTree(visitor, registry, strings);
});
// hook in components by looking at their _reactInternalInstance fields
forEachRef(refs, (visitor) => {
@@ -253,14 +253,14 @@ function markModules(refs) {
});
}
function registerPathToRoot(refs, registry) {
markReactComponentTree(refs, registry);
function registerPathToRoot(refs, registry, strings) {
markReactComponentTree(refs, registry, strings);
markModules(refs);
let breadth = [];
forEachRef(refs, (visitor) => {
const ref = visitor.getRef();
if (ref.type === 'CallbackGlobalObject') {
ref.rootPath = registry.insert(registry.root, ref.type);
ref.rootPath = registry.insert(registry.root, strings.intern(ref.type));
breadth.push(visitor.clone());
}
});
@@ -276,7 +276,7 @@ function registerPathToRoot(refs, registry) {
if (edgeName) {
pathName = edgeName + ': ' + pathName;
}
edgeRef.rootPath = registry.insert(ref.rootPath, pathName);
edgeRef.rootPath = registry.insert(ref.rootPath, strings.intern(pathName));
nextBreadth.push(edgeVisitor.clone());
// copy module and react tree forward
if (edgeRef.module === undefined) {
@@ -330,10 +330,10 @@ function captureRegistry() {
let dataOffset = this.data.length;
this.data = null;
registerPathToRoot(capture.refs, this.stacks);
registerPathToRoot(capture.refs, this.stacks, this.strings);
const internedCaptureId = this.strings.intern(captureId);
const noneString = this.strings.intern('#none');
const noneStack = this.stacks.insert(this.stacks.root, '#none');
const noneStack = this.stacks.insert(this.stacks.root, noneString);
forEachRef(capture.refs, (visitor) => {
const ref = visitor.getRef();
const id = visitor.id;
@@ -382,7 +382,7 @@ function captureRegistry() {
const agStacks = this.stacks.flatten();
const agData = this.data;
const agNumRows = agData.length / numFields;
const ag = new aggrow(agStrings, agStacks, agNumRows);
const ag = new aggrow(agNumRows);
ag.addFieldExpander('Id',
function getId(row) {
@@ -414,11 +414,19 @@ function captureRegistry() {
return agData[rowA * numFields + traceField] - agData[rowB * numFields + traceField];
});
const pathExpander = ag.addCalleeStackExpander('Path',
function getStack(row) { return agStacks.get(agData[row * numFields + pathField]); });
const pathExpander = ag.addCalleeStackExpander(
'Path',
agStacks.maxDepth,
function getStack(row) { return agStacks.get(agData[row * numFields + pathField]); },
function getFrame(id) { return agStrings.get(id); },
);
const reactExpander = ag.addCalleeStackExpander('React Tree',
function getStack(row) { return agStacks.get(agData[row * numFields + reactField]); });
const reactExpander = ag.addCalleeStackExpander(
'React Tree',
agStacks.maxDepth,
function getStack(row) { return agStacks.get(agData[row * numFields + reactField]); },
function getFrame(id) { return agStrings.get(id); },
);
const valueExpander = ag.addFieldExpander('Value',
function getValue(row) { return agStrings.get(agData[row * numFields + valueField]); },