Commit 4a64e949 authored by Alexander.Gilday2's avatar Alexander.Gilday2 Committed by Commit bot

[turbolizer] Improved display of perf profiling information.

All events recorded are shown in separate columns simulatneously, using
rectangles with heatmap-style colouring. Hovering over the shapes gives
the event name, count, and percentage.

BUG=

Review-Url: https://codereview.chromium.org/2228553004
Cr-Commit-Position: refs/heads/master@{#39408}
parent cce56a3f
......@@ -20,5 +20,11 @@ var DISASSEMBLY_COLLAPSE_ID = 'disassembly-shrink';
var DISASSEMBLY_EXPAND_ID = 'disassembly-expand';
var COLLAPSE_PANE_BUTTON_VISIBLE = 'button-input';
var COLLAPSE_PANE_BUTTON_INVISIBLE = 'button-input-invisible';
var PROF_HIGH = 5;
var PROF_MED = 0.5;
var UNICODE_BLOCK = '▋';
var PROF_COLS = [
{ perc: 0, col: { r: 255, g: 255, b: 255 } },
{ perc: 0.5, col: { r: 255, g: 255, b: 128 } },
{ perc: 5, col: { r: 255, g: 128, b: 0 } },
{ perc: 15, col: { r: 255, g: 0, b: 0 } },
{ perc: 100, col: { r: 0, g: 0, b: 0 } }
];
......@@ -159,6 +159,7 @@ class DisassemblyView extends TextView {
view.pos_start = -1;
view.addr_event_counts = null;
view.total_event_counts = null;
view.max_event_counts = null;
view.pos_lines = new Array();
// Comment lines for line 0 include sourcePosition already, only need to
// add sourcePosition for lines > 0.
......@@ -181,15 +182,18 @@ class DisassemblyView extends TextView {
view.addr_event_counts = eventCounts;
view.total_event_counts = {};
for (var ev_name in view.addr_event_counts) {
view.max_event_counts = {};
for (let ev_name in view.addr_event_counts) {
let keys = Object.keys(view.addr_event_counts[ev_name]);
let values = keys.map(key => view.addr_event_counts[ev_name][key]);
view.total_event_counts[ev_name] = values.reduce((a, b) => a + b);
view.max_event_counts[ev_name] = values.reduce((a, b) => Math.max(a, b));
}
}
else {
view.addr_event_counts = null;
view.total_event_counts = null;
view.max_event_counts = null;
}
}
......@@ -198,6 +202,11 @@ class DisassemblyView extends TextView {
return num.toFixed(3).replace(/\.?0+$/, "") + "%";
}
// Interpolate between the given start and end values by a fraction of val/max.
interpolate(val, max, start, end) {
return start + (end - start) * (val / max);
}
processLine(line) {
let view = this;
let func = function(match, p1, p2, p3) {
......@@ -214,30 +223,49 @@ class DisassemblyView extends TextView {
// Add profiling data per instruction if available.
if (view.total_event_counts) {
let event_selector = document.getElementById('event-selector');
if (event_selector.length !== 0) {
let event = event_selector.value;
let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line);
if (matches) {
let matches = /^(0x[0-9a-fA-F]+)\s+\d+\s+[0-9a-fA-F]+/.exec(line);
if (matches) {
let newFragments = [];
for (let event in view.addr_event_counts) {
let count = view.addr_event_counts[event][matches[1]];
let str = "";
let css_cls = undefined;
let str = " ";
let css_cls = "prof";
if(count !== undefined) {
let perc = count / view.total_event_counts[event] * 100;
str = "(" + view.humanize(perc) + ") ";
let col = { r: 255, g: 255, b: 255 };
for (let i = 0; i < PROF_COLS.length; i++) {
if (perc === PROF_COLS[i].perc) {
col = PROF_COLS[i].col;
break;
}
else if (perc > PROF_COLS[i].perc && perc < PROF_COLS[i + 1].perc) {
let col1 = PROF_COLS[i].col;
let col2 = PROF_COLS[i + 1].col;
let val = perc - PROF_COLS[i].perc;
let max = PROF_COLS[i + 1].perc - PROF_COLS[i].perc;
col.r = Math.round(view.interpolate(val, max, col1.r, col2.r));
col.g = Math.round(view.interpolate(val, max, col1.g, col2.g));
col.b = Math.round(view.interpolate(val, max, col1.b, col2.b));
break;
}
}
str = UNICODE_BLOCK;
let fragment = view.createFragment(str, css_cls);
fragment.title = event + ": " + view.humanize(perc) + " (" + count + ")";
fragment.style.color = "rgb(" + col.r + ", " + col.g + ", " + col.b + ")";
css_cls = "prof-low";
if(perc > PROF_HIGH)
css_cls = "prof-high";
else if(perc > PROF_MED)
css_cls = "prof-med";
newFragments.push(fragment);
}
// Pad extra spaces to keep alignment for all instructions.
str = (" ".repeat(10) + str).slice(-10);
else
newFragments.push(view.createFragment(str, css_cls));
fragments.splice(0, 0, view.createFragment(str, css_cls));
}
fragments = newFragments.concat(fragments);
}
}
return fragments;
......
......@@ -54,12 +54,9 @@
</text></svg></div>
</div>
<div id="right">
<span id="disassembly-toolbox">
<select id="event-selector"></select>
</span>
<div id='disassembly'>
<pre id='disassembly-text-pre' class='prettyprint prettyprinted'>
<ul id='disassembly-list' class='nolinenums noindent'>
<ul id='disassembly-list' class='nolinenums noindent'>
</ul>
</pre>
</div>
......
......@@ -120,7 +120,7 @@ class TextView extends View {
if (style != undefined) {
span.classList.add(style);
}
span.innerText = text;
span.innerHTML = text;
return span;
}
......
......@@ -326,16 +326,8 @@ span.linkable-text:hover {
display: none;
}
.prof-low {
color: #888;
}
.prof-med {
color: #080;
}
.prof-high {
color: #800;
.prof {
cursor: default;
}
tspan {
......
......@@ -188,13 +188,6 @@ document.onload = (function(d3){
}
}
var eventMenu = document.getElementById('event-selector');
eventMenu.innerHTML = '';
for (var event in jsonObj.eventCounts) {
var optionElement = document.createElement("option");
optionElement.text = event;
eventMenu.add(optionElement, null);
}
disassemblyView.initializePerfProfile(jsonObj.eventCounts);
disassemblyView.show(disassemblyPhase.data, null);
......@@ -216,10 +209,6 @@ document.onload = (function(d3){
displayPhase(jsonObj.phases[selectMenu.selectedIndex]);
}
eventMenu.onchange = function(item) {
disassemblyView.show(disassemblyView.data, null);
}
fitPanesToParents();
d3.select("#search-input").attr("value", window.sessionStorage.getItem("lastSearch") || "");
......
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