Commit 32224e4a authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbolizer] Improve page-load performance for >10MB json files

Notry: true
Change-Id: Iacc8aadc62956cf5fab13c60a9eaa52318519d62
Bug: v8:7327
Reviewed-on: https://chromium-review.googlesource.com/c/1317813
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarStephan Herhut <herhut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57267}
parent 9f3d2d55
...@@ -39,9 +39,6 @@ ...@@ -39,9 +39,6 @@
<input id="upload" type="image" title="load graph" class="button-input" <input id="upload" type="image" title="load graph" class="button-input"
src="upload-icon.png" alt="upload graph"> src="upload-icon.png" alt="upload graph">
</div> </div>
<div id='text-placeholder' width="0px" height="0px" style="position: absolute; top:100000px;" ><svg><text text-anchor="right">
<tspan white-space="inherit" id="text-measure"/>
</text></svg></div>
</div> </div>
<div class="resizer-right"></div> <div class="resizer-right"></div>
<div id="right" class="viewpane scrollable"></div> <div id="right" class="viewpane scrollable"></div>
...@@ -57,6 +54,13 @@ ...@@ -57,6 +54,13 @@
<input id="disassembly-shrink" type="image" title="hide disassembly" <input id="disassembly-shrink" type="image" title="hide disassembly"
src="right-arrow.png" class="button-input"> src="right-arrow.png" class="button-input">
</div> </div>
<div id='text-placeholder' width="0px" height="0px" style="position: absolute; top:100000px;">
<svg>
<text text-anchor="right">
<tspan white-space="inherit" id="text-measure" />
</text>
</svg>
</div>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
<script src="build/turbolizer.js"></script> <script src="build/turbolizer.js"></script>
</body> </body>
......
...@@ -31,7 +31,7 @@ export class DisassemblyView extends TextView { ...@@ -31,7 +31,7 @@ export class DisassemblyView extends TextView {
let ADDRESS_STYLE = { let ADDRESS_STYLE = {
css: 'tag', css: 'tag',
linkHandler: function (text, fragment) { linkHandler: function (text, fragment) {
const matches = text.match(/0x[0-9a-f]{8,16}\s*(?<offset>[0-9a-f]+)/); const matches = text.match(/0?x?[0-9a-fA-F]{8,16}\s*(?<offset>[0-9a-f]+)/);
const offset = Number.parseInt(matches.groups["offset"], 16); const offset = Number.parseInt(matches.groups["offset"], 16);
if (!Number.isNaN(offset)) { if (!Number.isNaN(offset)) {
const [nodes, blockId] = sourceResolver.nodesForPCOffset(offset) const [nodes, blockId] = sourceResolver.nodesForPCOffset(offset)
...@@ -99,7 +99,7 @@ export class DisassemblyView extends TextView { ...@@ -99,7 +99,7 @@ export class DisassemblyView extends TextView {
view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/; view.SOURCE_POSITION_HEADER_REGEX = /^\s*--[^<]*<.*(not inlined|inlined\((\d+)\)):(\d+)>\s*--/;
let patterns = [ let patterns = [
[ [
[/^0x[0-9a-f]{8,16}\s*[0-9a-f]+\ /, ADDRESS_STYLE, 1], [/^0?x?[0-9a-fA-F]{8,16}\s*[0-9a-f]+\ /, ADDRESS_STYLE, 1],
[view.SOURCE_POSITION_HEADER_REGEX, SOURCE_POSITION_HEADER_STYLE, -1], [view.SOURCE_POSITION_HEADER_REGEX, SOURCE_POSITION_HEADER_STYLE, -1],
[/^\s+-- B\d+ start.*/, BLOCK_HEADER_STYLE, -1], [/^\s+-- B\d+ start.*/, BLOCK_HEADER_STYLE, -1],
[/^.*/, UNCLASSIFIED_STYLE, -1] [/^.*/, UNCLASSIFIED_STYLE, -1]
......
...@@ -271,6 +271,11 @@ export class GraphView extends View implements PhaseView { ...@@ -271,6 +271,11 @@ export class GraphView extends View implements PhaseView {
} }
} }
show(data, rememberedSelection): void {
this.container.appendChild(this.divNode);
this.initializeContent(data, rememberedSelection);
}
deleteContent() { deleteContent() {
if (this.visibleNodes) { if (this.visibleNodes) {
this.nodes = []; this.nodes = [];
...@@ -342,7 +347,6 @@ export class GraphView extends View implements PhaseView { ...@@ -342,7 +347,6 @@ export class GraphView extends View implements PhaseView {
g.updateGraphVisibility(); g.updateGraphVisibility();
g.layoutGraph(); g.layoutGraph();
g.updateGraphVisibility(); g.updateGraphVisibility();
g.viewWholeGraph();
} }
connectVisibleSelectedNodes() { connectVisibleSelectedNodes() {
......
...@@ -52,13 +52,9 @@ export class ScheduleView extends TextView implements PhaseView { ...@@ -52,13 +52,9 @@ export class ScheduleView extends TextView implements PhaseView {
elementForBlock(block) { elementForBlock(block) {
const view = this; const view = this;
function createElement(tag: string, cls: string | Array<string>, content?: string) { function createElement(tag: string, cls: string, content?: string) {
const el = document.createElement(tag); const el = document.createElement(tag);
if (isIterable(cls)) { el.className = cls
for (const c of cls) el.classList.add(c);
} else {
el.classList.add(cls);
}
if (content != undefined) el.innerHTML = content; if (content != undefined) el.innerHTML = content;
return el; return el;
} }
...@@ -92,22 +88,22 @@ export class ScheduleView extends TextView implements PhaseView { ...@@ -92,22 +88,22 @@ export class ScheduleView extends TextView implements PhaseView {
const [start, end] = view.sourceResolver.getInstruction(node.id); const [start, end] = view.sourceResolver.getInstruction(node.id);
const [marker, tooltip] = getMarker(start, end); const [marker, tooltip] = getMarker(start, end);
const instrMarker = createElement("div", ["instr-marker", "com"], marker); const instrMarker = createElement("div", "instr-marker com", marker);
instrMarker.setAttribute("title", tooltip); instrMarker.setAttribute("title", tooltip);
instrMarker.onclick = mkNodeLinkHandler(node.id); instrMarker.onclick = mkNodeLinkHandler(node.id);
nodeEl.appendChild(instrMarker); nodeEl.appendChild(instrMarker);
const node_id = createElement("div", ["node-id", "tag", "clickable"], node.id); const node_id = createElement("div", "node-id tag clickable", node.id);
node_id.onclick = mkNodeLinkHandler(node.id); node_id.onclick = mkNodeLinkHandler(node.id);
view.addHtmlElementForNodeId(node.id, node_id); view.addHtmlElementForNodeId(node.id, node_id);
nodeEl.appendChild(node_id); nodeEl.appendChild(node_id);
const node_label = createElement("div", "node-label", node.label); const node_label = createElement("div", "node-label", node.label);
nodeEl.appendChild(node_label); nodeEl.appendChild(node_label);
if (node.inputs.length > 0) { if (node.inputs.length > 0) {
const node_parameters = createElement("div", ["parameter-list", "comma-sep-list"]); const node_parameters = createElement("div", "parameter-list comma-sep-list");
for (const param of node.inputs) { for (const param of node.inputs) {
const paramEl = createElement("div", ["parameter", "tag", "clickable"], param); const paramEl = createElement("div", "parameter tag clickable", param);
node_parameters.appendChild(paramEl); node_parameters.appendChild(paramEl);
paramEl.onclick = mkNodeLinkHandler(param); paramEl.onclick = mkNodeLinkHandler(param);
view.addHtmlElementForNodeId(param, paramEl); view.addHtmlElementForNodeId(param, paramEl);
...@@ -131,17 +127,17 @@ export class ScheduleView extends TextView implements PhaseView { ...@@ -131,17 +127,17 @@ export class ScheduleView extends TextView implements PhaseView {
const schedule_block = createElement("div", "schedule-block"); const schedule_block = createElement("div", "schedule-block");
const [start, end] = view.sourceResolver.getInstructionRangeForBlock(block.id); const [start, end] = view.sourceResolver.getInstructionRangeForBlock(block.id);
const instrMarker = createElement("div", ["instr-marker", "com"], "&#8857;"); const instrMarker = createElement("div", "instr-marker com", "&#8857;");
instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`) instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`)
instrMarker.onclick = mkBlockLinkHandler(block.id); instrMarker.onclick = mkBlockLinkHandler(block.id);
schedule_block.appendChild(instrMarker); schedule_block.appendChild(instrMarker);
const block_id = createElement("div", ["block-id", "com", "clickable"], block.id); const block_id = createElement("div", "block-id com clickable", block.id);
block_id.onclick = mkBlockLinkHandler(block.id); block_id.onclick = mkBlockLinkHandler(block.id);
schedule_block.appendChild(block_id); schedule_block.appendChild(block_id);
const block_pred = createElement("div", ["predecessor-list", "block-list", "comma-sep-list"]); const block_pred = createElement("div", "predecessor-list block-list comma-sep-list");
for (const pred of block.pred) { for (const pred of block.pred) {
const predEl = createElement("div", ["block-id", "com", "clickable"], pred); const predEl = createElement("div", "block-id com clickable", pred);
predEl.onclick = mkBlockLinkHandler(pred); predEl.onclick = mkBlockLinkHandler(pred);
block_pred.appendChild(predEl); block_pred.appendChild(predEl);
} }
...@@ -151,9 +147,9 @@ export class ScheduleView extends TextView implements PhaseView { ...@@ -151,9 +147,9 @@ export class ScheduleView extends TextView implements PhaseView {
nodes.appendChild(createElementForNode(node)); nodes.appendChild(createElementForNode(node));
} }
schedule_block.appendChild(nodes); schedule_block.appendChild(nodes);
const block_succ = createElement("div", ["successor-list", "block-list", "comma-sep-list"]); const block_succ = createElement("div", "successor-list block-list comma-sep-list");
for (const succ of block.succ) { for (const succ of block.succ) {
const succEl = createElement("div", ["block-id", "com", "clickable"], succ); const succEl = createElement("div", "block-id com clickable", succ);
succEl.onclick = mkBlockLinkHandler(succ); succEl.onclick = mkBlockLinkHandler(succ);
block_succ.appendChild(succEl); block_succ.appendChild(succEl);
} }
......
...@@ -94,6 +94,7 @@ export class SourceResolver { ...@@ -94,6 +94,7 @@ export class SourceResolver {
blockIdToInstructionRange: Array<[number, number]>; blockIdToInstructionRange: Array<[number, number]>;
instructionToPCOffset: Array<number>; instructionToPCOffset: Array<number>;
pcOffsetToInstructions: Map<number, Array<number>>; pcOffsetToInstructions: Map<number, Array<number>>;
pcOffsets: Array<number>;
constructor() { constructor() {
...@@ -123,6 +124,7 @@ export class SourceResolver { ...@@ -123,6 +124,7 @@ export class SourceResolver {
this.instructionToPCOffset = []; this.instructionToPCOffset = [];
// Maps PC offsets to instructions. // Maps PC offsets to instructions.
this.pcOffsetToInstructions = new Map(); this.pcOffsetToInstructions = new Map();
this.pcOffsets = [];
} }
setSources(sources, mainBackup) { setSources(sources, mainBackup) {
...@@ -349,7 +351,7 @@ export class SourceResolver { ...@@ -349,7 +351,7 @@ export class SourceResolver {
} }
this.pcOffsetToInstructions.get(offset).push(instruction); this.pcOffsetToInstructions.get(offset).push(instruction);
} }
console.log(this.pcOffsetToInstructions); this.pcOffsets = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a);
} }
hasPCOffsets() { hasPCOffsets() {
...@@ -358,9 +360,8 @@ export class SourceResolver { ...@@ -358,9 +360,8 @@ export class SourceResolver {
nodesForPCOffset(offset): [Array<String>, Array<String>] { nodesForPCOffset(offset): [Array<String>, Array<String>] {
const keys = Array.from(this.pcOffsetToInstructions.keys()).sort((a, b) => b - a); if (this.pcOffsets.length === 0) return [[],[]];
if (keys.length === 0) return [[],[]]; for (const key of this.pcOffsets) {
for (const key of keys) {
if (key <= offset) { if (key <= offset) {
const instrs = this.pcOffsetToInstructions.get(key); const instrs = this.pcOffsetToInstructions.get(key);
const nodes = []; const nodes = [];
......
...@@ -20,13 +20,13 @@ export abstract class View { ...@@ -20,13 +20,13 @@ export abstract class View {
} }
show(data, rememberedSelection): void { show(data, rememberedSelection): void {
this.container.appendChild(this.divNode);
this.initializeContent(data, rememberedSelection); this.initializeContent(data, rememberedSelection);
this.container.appendChild(this.divNode);
} }
hide(): void { hide(): void {
this.deleteContent();
this.container.removeChild(this.divNode); this.container.removeChild(this.divNode);
this.deleteContent();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment