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

@ -1,8 +1,8 @@
SHELL := /bin/bash SHELL := /bin/bash
all: all:
NODE_PATH="../../../../node_modules/" babel --presets babel-preset-react-native -d out src NODE_PATH="../../../../node_modules/" babel --presets babel-preset-react-native --source-maps inline -d out src
for f in out/*.js; do echo "// @generated" >> $$f; done for f in out/*.js; do echo -e "\n// @generated" >> $$f; done
watch: watch:
NODE_PATH="../../../../node_modules/" babel --watch --presets babel-preset-react-native -d out src NODE_PATH="../../../../node_modules/" babel --watch --presets babel-preset-react-native -d out src

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

View File

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

View File

@ -109,7 +109,7 @@ function symbolicateHeapCaptureFunctions(capture, onFailure, onSuccess) {
if (original.name) { if (original.name) {
ref.value.name = original.name; ref.value.name = original.name;
} else if (!ref.value.name) { } else if (!ref.value.name) {
ref.value.name = path.posix.basename(original.source) + ':' + original.line; ref.value.name = path.posix.basename(original.source || '') + ':' + original.line;
} }
ref.value.url = original.source; ref.value.url = original.source;
ref.value.line = original.line; ref.value.line = original.line;