- Add ToolTip helper that tracks scrolling target elements - Auto hide if the target scrolls out of view - ToolTip position depends on target position - Add basic tooltips for maps in the transition view, entries in timeline tracks and the source panel Drive-by-fix: - Move events.mjs to view/ folder - Add basic toString methods on various log entries - Add requestAnimationFrame update support for V8CustomElement Bug: v8:10644 Change-Id: I1059733cd094a986b715547b3d5747eefbc54bc5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2551103 Commit-Queue: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#71434}
131 lines
4.2 KiB
JavaScript
131 lines
4.2 KiB
JavaScript
// Copyright 2020 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
import {SelectionEvent} from './events.mjs';
|
|
|
|
import {DOM, LazyTable, V8CustomElement} from './helper.mjs';
|
|
|
|
DOM.defineCustomElement(
|
|
'view/stats-panel',
|
|
(templateText) => class StatsPanel extends V8CustomElement {
|
|
_timeline;
|
|
_transitions;
|
|
_selectedLogEntries;
|
|
constructor() {
|
|
super(templateText);
|
|
}
|
|
|
|
get stats() {
|
|
return this.$('#stats');
|
|
}
|
|
|
|
set timeline(timeline) {
|
|
this._timeline = timeline;
|
|
this.selectedLogEntries = timeline.all
|
|
}
|
|
|
|
set selectedLogEntries(entries) {
|
|
this._selectedLogEntries = entries;
|
|
this.update();
|
|
}
|
|
|
|
set transitions(value) {
|
|
this._transitions = value;
|
|
}
|
|
|
|
_filterUniqueTransitions(filter) {
|
|
// Returns a list of Maps whose parent is not in the list.
|
|
return this._selectedLogEntries.filter((map) => {
|
|
if (filter(map) === false) return false;
|
|
let parent = map.parent();
|
|
if (parent === undefined) return true;
|
|
return filter(parent) === false;
|
|
});
|
|
}
|
|
|
|
_update() {
|
|
this._updateGeneralStats();
|
|
this._updateNamedTransitionsStats();
|
|
}
|
|
|
|
_updateGeneralStats() {
|
|
console.assert(this._timeline !== undefined, 'Timeline not set yet!');
|
|
let pairs = [
|
|
['Transitions', 'primary', (e) => e.edge && e.edge.isTransition()],
|
|
['Fast to Slow', 'violet', (e) => e.edge && e.edge.isFastToSlow()],
|
|
['Slow to Fast', 'orange', (e) => e.edge && e.edge.isSlowToFast()],
|
|
['Initial Map', 'yellow', (e) => e.edge && e.edge.isInitial()],
|
|
[
|
|
'Replace Descriptors',
|
|
'red',
|
|
(e) => e.edge && e.edge.isReplaceDescriptors(),
|
|
],
|
|
[
|
|
'Copy as Prototype',
|
|
'red',
|
|
(e) => e.edge && e.edge.isCopyAsPrototype(),
|
|
],
|
|
[
|
|
'Optimize as Prototype',
|
|
null,
|
|
(e) => e.edge && e.edge.isOptimizeAsPrototype(),
|
|
],
|
|
['Deprecated', null, (e) => e.isDeprecated()],
|
|
['Bootstrapped', 'green', (e) => e.isBootstrapped()],
|
|
['Total', null, (e) => true],
|
|
];
|
|
|
|
let tbody = document.createElement('tbody');
|
|
let total = this._selectedLogEntries.length;
|
|
pairs.forEach(([name, color, filter]) => {
|
|
let row = DOM.tr();
|
|
if (color !== null) {
|
|
row.appendChild(DOM.td(DOM.div(['colorbox', color])));
|
|
} else {
|
|
row.appendChild(DOM.td(''));
|
|
}
|
|
row.classList.add('clickable');
|
|
row.onclick = (e) => {
|
|
// lazily compute the stats
|
|
let node = e.target.parentNode;
|
|
if (node.maps == undefined) {
|
|
node.maps = this._filterUniqueTransitions(filter);
|
|
}
|
|
this.dispatchEvent(new SelectionEvent(node.maps));
|
|
};
|
|
row.appendChild(DOM.td(name));
|
|
let count = this._count(filter);
|
|
row.appendChild(DOM.td(count));
|
|
let percent = Math.round((count / total) * 1000) / 10;
|
|
row.appendChild(DOM.td(percent.toFixed(1) + '%'));
|
|
tbody.appendChild(row);
|
|
});
|
|
this.$('#typeTable').replaceChild(tbody, this.$('#typeTable tbody'));
|
|
}
|
|
|
|
_count(filter) {
|
|
let count = 0;
|
|
for (const map of this._selectedLogEntries) {
|
|
if (filter(map)) count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
_updateNamedTransitionsStats() {
|
|
let rowData = Array.from(this._transitions.entries());
|
|
rowData.sort((a, b) => b[1].length - a[1].length);
|
|
new LazyTable(this.$('#nameTable'), rowData, ([name, maps]) => {
|
|
let row = DOM.tr();
|
|
row.maps = maps;
|
|
row.classList.add('clickable');
|
|
row.addEventListener(
|
|
'click',
|
|
(e) => this.dispatchEvent(new SelectionEvent(
|
|
e.target.parentNode.maps.map((map) => map.to))));
|
|
row.appendChild(DOM.td(maps.length));
|
|
row.appendChild(DOM.td(name));
|
|
return row;
|
|
});
|
|
}
|
|
});
|