393e434479
This CL unifies the custom events by creating classes specialised based on the event type. Multiple entry selection causes panels to emit 'showentries' event. Single entry selection causes panels to emit 'showentrydetail' event. The events are received by the controller App class and updates the view of the panels and state of the app. Bug: v8:10644 Change-Id: Ibe26223459ba605c6d6d3f0025bf3a556dfb0578 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2335188 Commit-Queue: Zeynep Cankara <zcankara@google.com> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Cr-Commit-Position: refs/heads/master@{#69286}
125 lines
3.9 KiB
JavaScript
125 lines
3.9 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 {V8CustomElement, defineCustomElement} from './helper.mjs';
|
|
import {SelectionEvent} from './events.mjs';
|
|
|
|
defineCustomElement('stats-panel', (templateText) =>
|
|
class StatsPanel extends V8CustomElement {
|
|
#timeline;
|
|
#transitions;
|
|
constructor() {
|
|
super(templateText);
|
|
}
|
|
|
|
get stats() {
|
|
return this.$('#stats');
|
|
}
|
|
|
|
set timeline(value){
|
|
//TODO(zcankara) Trigger update
|
|
this.#timeline = value;
|
|
}
|
|
|
|
get timeline(){
|
|
return this.#timeline;
|
|
}
|
|
|
|
set transitions(value){
|
|
this.#transitions = value;
|
|
}
|
|
|
|
get transitions(){
|
|
return this.#transitions;
|
|
}
|
|
|
|
filterUniqueTransitions(filter) {
|
|
// Returns a list of Maps whose parent is not in the list.
|
|
return this.timeline.filter(map => {
|
|
if (filter(map) === false) return false;
|
|
let parent = map.parent();
|
|
if (parent === undefined) return true;
|
|
return filter(parent) === false;
|
|
});
|
|
}
|
|
|
|
update() {
|
|
this.removeAllChildren(this.stats);
|
|
this.updateGeneralStats();
|
|
this.updateNamedTransitionsStats();
|
|
}
|
|
|
|
updateGeneralStats() {
|
|
console.assert(this.#timeline !== undefined, "Timeline not set yet!");
|
|
let pairs = [
|
|
['Total', null, e => true],
|
|
['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()],
|
|
];
|
|
|
|
let text = '';
|
|
let tableNode = this.table('transitionType');
|
|
tableNode.innerHTML =
|
|
'<thead><tr><td>Color</td><td>Type</td><td>Count</td><td>Percent</td></tr></thead>';
|
|
let name, filter;
|
|
let total = this.timeline.size();
|
|
pairs.forEach(([name, color, filter]) => {
|
|
let row = this.tr();
|
|
if (color !== null) {
|
|
row.appendChild(this.td(this.div(['colorbox', color])));
|
|
} else {
|
|
row.appendChild(this.td(''));
|
|
}
|
|
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(this.td(name));
|
|
let count = this.timeline.count(filter);
|
|
row.appendChild(this.td(count));
|
|
let percent = Math.round(count / total * 1000) / 10;
|
|
row.appendChild(this.td(percent.toFixed(1) + '%'));
|
|
tableNode.appendChild(row);
|
|
});
|
|
this.stats.appendChild(tableNode);
|
|
}
|
|
|
|
updateNamedTransitionsStats() {
|
|
let tableNode = this.table('transitionTable');
|
|
let nameMapPairs = Array.from(this.transitions.entries());
|
|
tableNode.innerHTML =
|
|
'<thead><tr><td>Propery Name</td><td>#</td></tr></thead>';
|
|
nameMapPairs.sort((a, b) => b[1].length - a[1].length).forEach(([
|
|
name, maps
|
|
]) => {
|
|
let row = this.tr();
|
|
row.maps = maps;
|
|
row.addEventListener(
|
|
'click',
|
|
e => this.dispatchEvent(
|
|
new SelectionEvent(e.target.parentNode.maps.map(map => map.to))));
|
|
row.appendChild(this.td(name));
|
|
row.appendChild(this.td(maps.length));
|
|
tableNode.appendChild(row);
|
|
});
|
|
this.stats.appendChild(tableNode);
|
|
}
|
|
});
|