[turbolizer] Wasm integration
This CL allows selection/highlighting of wasm source when a graph node is clicked. Bug: v8:7327 Change-Id: I4a3347a83c8a38804feabffefaefd761596005c3 Reviewed-on: https://chromium-review.googlesource.com/1092712 Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#53636}
This commit is contained in:
parent
43fb4c4a77
commit
3f8607bfc8
@ -14,7 +14,6 @@ class CodeView extends View {
|
||||
source: Source;
|
||||
sourceResolver: SourceResolver;
|
||||
codeMode: CodeMode;
|
||||
lineToSourcePositions: Map<string, Array<SourcePosition>>;
|
||||
sourcePositionToHtmlElement: Map<string, HTMLElement>;
|
||||
showAdditionalInliningPosition: boolean;
|
||||
selectionHandler: SelectionHandler;
|
||||
@ -34,7 +33,6 @@ class CodeView extends View {
|
||||
view.sourceResolver = sourceResolver;
|
||||
view.source = sourceFunction;
|
||||
view.codeMode = codeMode;
|
||||
this.lineToSourcePositions = new Map();
|
||||
this.sourcePositionToHtmlElement = new Map();
|
||||
this.showAdditionalInliningPosition = false;
|
||||
|
||||
@ -75,14 +73,6 @@ class CodeView extends View {
|
||||
this.initializeCode();
|
||||
}
|
||||
|
||||
addSourcePositionToLine(lineNumber, sourcePosition) {
|
||||
const lineNumberString = anyToString(lineNumber);
|
||||
if (!this.lineToSourcePositions.has(lineNumberString)) {
|
||||
this.lineToSourcePositions.set(lineNumberString, []);
|
||||
}
|
||||
this.lineToSourcePositions.get(lineNumberString).push(sourcePosition);
|
||||
}
|
||||
|
||||
addHtmlElementToSourcePosition(sourcePosition, element) {
|
||||
const key = sourcePositionToStringKey(sourcePosition);
|
||||
if (this.sourcePositionToHtmlElement.has(key)) {
|
||||
@ -122,13 +112,15 @@ class CodeView extends View {
|
||||
return ordereList.childNodes as NodeListOf<HTMLElement>;
|
||||
}
|
||||
|
||||
onSelectLine(lineNumber, doClear) {
|
||||
const sourcePositions = this.lineToSourcePositions.get(anyToString(lineNumber));
|
||||
onSelectLine(lineNumber:number, doClear:boolean) {
|
||||
const key = anyToString(lineNumber);
|
||||
if (doClear) {
|
||||
this.selectionHandler.clear();
|
||||
}
|
||||
if (!sourcePositions) return;
|
||||
this.selectionHandler.select(sourcePositions, undefined);
|
||||
const positions = this.sourceResolver.linetoSourcePositions(lineNumber - 1);
|
||||
if (positions !== undefined) {
|
||||
this.selectionHandler.select(positions, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
onSelectSourcePosition(sourcePosition, doClear) {
|
||||
@ -225,7 +217,7 @@ class CodeView extends View {
|
||||
const view = this;
|
||||
const sps = this.sourceResolver.sourcePositionsInRange(this.source.sourceId, pos - adjust, end);
|
||||
for (const sourcePosition of sps) {
|
||||
view.addSourcePositionToLine(lineNumber, sourcePosition);
|
||||
this.sourceResolver.addAnyPositionToLine(lineNumber, sourcePosition);
|
||||
const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.firstChild : currentSpan;
|
||||
const replacementNode = textnode.splitText(Math.max(0, sourcePosition.scriptOffset - pos));
|
||||
const span = document.createElement('span');
|
||||
@ -255,12 +247,18 @@ class CodeView extends View {
|
||||
const view = this;
|
||||
const lineNumberElement = document.createElement("div");
|
||||
lineNumberElement.classList.add("line-number");
|
||||
lineNumberElement.dataset.lineNumber = lineNumber;
|
||||
lineNumberElement.innerText = lineNumber;
|
||||
lineNumberElement.onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
view.onSelectLine(lineNumber, !e.shiftKey);
|
||||
}
|
||||
lineElement.insertBefore(lineNumberElement, lineElement.firstChild)
|
||||
// Don't add lines to source positions of not in backwardsCompatibility mode.
|
||||
if (typeof this.source['backwardsCompatibility'] === undefined) return;
|
||||
for (const sourcePosition of this.sourceResolver.linetoSourcePositions(lineNumber - 1)) {
|
||||
view.addHtmlElementToSourcePosition(sourcePosition, lineElement);
|
||||
}
|
||||
}
|
||||
|
||||
deleteContent() { }
|
||||
|
@ -91,6 +91,9 @@ class GraphView extends View implements PhaseView {
|
||||
if (node.sourcePosition) {
|
||||
locations.push(node.sourcePosition);
|
||||
}
|
||||
if (node.origin && node.origin.bytecodePosition) {
|
||||
locations.push({bytecodePosition: node.origin.bytecodePosition});
|
||||
}
|
||||
}
|
||||
graph.state.selection.select(nodes, selected);
|
||||
broker.broadcastSourcePositionSelect(this, locations, selected);
|
||||
|
@ -12,6 +12,16 @@ function isNodeInitiallyVisible(node) {
|
||||
return node.cfg;
|
||||
}
|
||||
|
||||
function formatOrigin(origin) {
|
||||
if (origin.nodeId) {
|
||||
return `#${origin.nodeId} in phase ${origin.phase}/${origin.reducer}`;
|
||||
}
|
||||
if (origin.bytecodePosition) {
|
||||
return `Bytecode line ${origin.bytecodePosition} in phase ${origin.phase}/${origin.reducer}`;
|
||||
}
|
||||
return "unknown origin";
|
||||
}
|
||||
|
||||
class GNode {
|
||||
control: boolean;
|
||||
opcode: string;
|
||||
@ -79,7 +89,7 @@ class GNode {
|
||||
}
|
||||
let title = this.title + "\n" + propsString + "\n" + this.opinfo;
|
||||
if (this.origin) {
|
||||
title += `\nOrigin: #${this.origin.nodeId} in phase ${this.origin.phase}/${this.origin.reducer}`;
|
||||
title += `\nOrigin: ${formatOrigin(this.origin)}`;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
@ -30,8 +30,7 @@ class SelectionBroker {
|
||||
broadcastSourcePositionSelect(from, sourcePositions, selected) {
|
||||
let broker = this;
|
||||
sourcePositions = sourcePositions.filter((l) => {
|
||||
if (typeof l.scriptOffset == 'undefined'
|
||||
|| typeof l.inliningId == 'undefined') {
|
||||
if (!sourcePositionValid(l)) {
|
||||
console.log("Warning: invalid source position");
|
||||
return false;
|
||||
}
|
||||
|
@ -14,9 +14,18 @@ function sourcePositionEq(a, b) {
|
||||
a.scriptOffset == b.scriptOffset;
|
||||
}
|
||||
|
||||
function sourcePositionToStringKey(sourcePosition) {
|
||||
function sourcePositionToStringKey(sourcePosition): string {
|
||||
if (!sourcePosition) return "undefined";
|
||||
return "" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset;
|
||||
if (sourcePosition.inliningId && sourcePosition.scriptOffset)
|
||||
return "SP:" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset;
|
||||
if (sourcePosition.bytecodePosition)
|
||||
return "BCP:" + sourcePosition.bytecodePosition;
|
||||
return "undefined";
|
||||
}
|
||||
|
||||
function sourcePositionValid(l) {
|
||||
return (typeof l.scriptOffset !== undefined
|
||||
&& typeof l.inliningId !== undefined) || typeof l.bytecodePosition != undefined;
|
||||
}
|
||||
|
||||
interface SourcePosition {
|
||||
@ -24,6 +33,25 @@ interface SourcePosition {
|
||||
inliningId: number;
|
||||
}
|
||||
|
||||
interface TurboFanOrigin {
|
||||
phase: string;
|
||||
reducer: string;
|
||||
}
|
||||
|
||||
interface NodeOrigin {
|
||||
nodeId: number;
|
||||
}
|
||||
|
||||
interface BytecodePosition {
|
||||
bytecodePosition: number;
|
||||
}
|
||||
|
||||
type Origin = NodeOrigin | BytecodePosition;
|
||||
type TurboFanNodeOrigin = NodeOrigin & TurboFanOrigin;
|
||||
type TurboFanBytecodeOrigin = BytecodePosition & TurboFanOrigin;
|
||||
|
||||
type AnyPosition = SourcePosition | BytecodePosition;
|
||||
|
||||
interface Source {
|
||||
sourcePositions: Array<SourcePosition>;
|
||||
sourceName: string;
|
||||
@ -46,14 +74,8 @@ interface Schedule {
|
||||
nodes: Array<any>;
|
||||
}
|
||||
|
||||
interface NodeOrigin {
|
||||
nodeId: number;
|
||||
phase: string;
|
||||
reducer: string;
|
||||
}
|
||||
|
||||
class SourceResolver {
|
||||
nodePositionMap: Array<SourcePosition>;
|
||||
nodePositionMap: Array<AnyPosition>;
|
||||
sources: Array<Source>;
|
||||
inlinings: Array<Inlining>;
|
||||
inliningsMap: Map<string, Inlining>;
|
||||
@ -61,6 +83,8 @@ class SourceResolver {
|
||||
phases: Array<Phase>;
|
||||
phaseNames: Map<string, number>;
|
||||
disassemblyPhase: Phase;
|
||||
lineToSourcePositions: Map<string, Array<AnyPosition>>;
|
||||
|
||||
|
||||
constructor() {
|
||||
// Maps node ids to source positions.
|
||||
@ -79,6 +103,8 @@ class SourceResolver {
|
||||
this.phaseNames = new Map();
|
||||
// The disassembly phase is stored separately.
|
||||
this.disassemblyPhase = undefined;
|
||||
// Maps line numbers to source positions
|
||||
this.lineToSourcePositions = new Map();
|
||||
}
|
||||
|
||||
setSources(sources, mainBackup) {
|
||||
@ -153,7 +179,7 @@ class SourceResolver {
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
nodeIdsToSourcePositions(nodeIds) {
|
||||
nodeIdsToSourcePositions(nodeIds): Array<AnyPosition> {
|
||||
const sourcePositions = new Map();
|
||||
for (const nodeId of nodeIds) {
|
||||
let sp = this.nodePositionMap[nodeId];
|
||||
@ -255,6 +281,23 @@ class SourceResolver {
|
||||
return inliningStack;
|
||||
}
|
||||
|
||||
recordOrigins(phase) {
|
||||
if (phase.type != "graph") return;
|
||||
for (const node of phase.data.nodes) {
|
||||
if (node.origin != undefined &&
|
||||
node.origin.bytecodePosition != undefined) {
|
||||
const position = {bytecodePosition: node.origin.bytecodePosition};
|
||||
this.nodePositionMap[node.id] = position;
|
||||
let key = sourcePositionToStringKey(position);
|
||||
if (!this.positionToNodes.has(key)) {
|
||||
this.positionToNodes.set(key, []);
|
||||
}
|
||||
const A = this.positionToNodes.get(key);
|
||||
if (!A.includes(node.id)) A.push("" + node.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parsePhases(phases) {
|
||||
for (const [phaseId, phase] of Object.entries<Phase>(phases)) {
|
||||
if (phase.type == 'disassembly') {
|
||||
@ -264,6 +307,7 @@ class SourceResolver {
|
||||
this.phaseNames.set(phase.name, this.phases.length);
|
||||
} else {
|
||||
this.phases.push(phase);
|
||||
this.recordOrigins(phase);
|
||||
this.phaseNames.set(phase.name, this.phases.length);
|
||||
}
|
||||
}
|
||||
@ -285,6 +329,28 @@ class SourceResolver {
|
||||
this.phases.forEach(f);
|
||||
}
|
||||
|
||||
addAnyPositionToLine(lineNumber:number|String, sourcePosition:AnyPosition) {
|
||||
const lineNumberString = anyToString(lineNumber);
|
||||
if (!this.lineToSourcePositions.has(lineNumberString)) {
|
||||
this.lineToSourcePositions.set(lineNumberString, []);
|
||||
}
|
||||
const A = this.lineToSourcePositions.get(lineNumberString);
|
||||
if (!A.includes(sourcePosition)) A.push(sourcePosition);
|
||||
}
|
||||
|
||||
setSourceLineToBytecodePosition(sourceLineToBytecodePosition:Array<number>|undefined) {
|
||||
if (!sourceLineToBytecodePosition) return;
|
||||
sourceLineToBytecodePosition.forEach((pos, i) => {
|
||||
this.addAnyPositionToLine(i, {bytecodePosition: pos});
|
||||
});
|
||||
}
|
||||
|
||||
linetoSourcePositions(lineNumber:number|String) {
|
||||
const positions = this.lineToSourcePositions.get(anyToString(lineNumber));
|
||||
if (positions === undefined) return [];
|
||||
return positions;
|
||||
}
|
||||
|
||||
parseSchedule(phase) {
|
||||
function createNode(state, match) {
|
||||
let inputs = [];
|
||||
|
@ -226,11 +226,13 @@ window.onload = function () {
|
||||
sourceId: -1,
|
||||
startPosition: jsonObj.sourcePosition,
|
||||
endPosition: jsonObj.sourcePosition + jsonObj.source.length,
|
||||
sourceText: jsonObj.source
|
||||
sourceText: jsonObj.source,
|
||||
backwardsCompatibility: true
|
||||
};
|
||||
}
|
||||
|
||||
sourceResolver.setInlinings(jsonObj.inlinings);
|
||||
sourceResolver.setSourceLineToBytecodePosition(jsonObj.sourceLineToBytecodePosition);
|
||||
sourceResolver.setSources(jsonObj.sources, fnc)
|
||||
sourceResolver.setNodePositionMap(jsonObj.nodePositions);
|
||||
sourceResolver.parsePhases(jsonObj.phases);
|
||||
|
@ -45,7 +45,6 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.selected {
|
||||
background-color: #FFFF33;
|
||||
}
|
||||
@ -64,19 +63,29 @@ ol.linenums {
|
||||
display:inline-block;
|
||||
min-width: 3ex;
|
||||
text-align: right;
|
||||
color: gray;
|
||||
padding-right:1ex;
|
||||
font-size: 10px;
|
||||
color: #444444;
|
||||
margin-right: 0.5ex;
|
||||
padding-right: 0.5ex;
|
||||
background: #EEEEEE;
|
||||
/* font-size: 80%; */
|
||||
user-select: none;
|
||||
height: 120%;
|
||||
}
|
||||
|
||||
.line-number:hover {
|
||||
background-color: #CCCCCC;
|
||||
}
|
||||
|
||||
.prettyprint ol.linenums > li.selected {
|
||||
background-color: #FFFF33 !important;
|
||||
}
|
||||
|
||||
li.selected .line-number {
|
||||
background-color: #FFFF33;
|
||||
}
|
||||
|
||||
.prettyprint ol.linenums > li {
|
||||
list-style-type: decimal;
|
||||
padding-top: 3px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user