2020-07-10 10:02:08 +00:00
|
|
|
// 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.
|
2020-07-16 14:46:13 +00:00
|
|
|
import {V8CustomElement, defineCustomElement} from './helper.mjs';
|
2020-07-10 10:02:08 +00:00
|
|
|
|
|
|
|
defineCustomElement('stats-panel', (templateText) =>
|
2020-07-16 14:46:13 +00:00
|
|
|
class StatsPanel extends V8CustomElement {
|
2020-07-10 10:02:08 +00:00
|
|
|
constructor() {
|
2020-07-16 14:46:13 +00:00
|
|
|
super(templateText);
|
2020-07-10 10:02:08 +00:00
|
|
|
this.timeline_ = undefined;
|
|
|
|
}
|
|
|
|
|
2020-07-15 04:51:13 +00:00
|
|
|
get stats() {
|
2020-07-10 10:02:08 +00:00
|
|
|
return this.$('#stats');
|
|
|
|
}
|
|
|
|
|
|
|
|
set timeline(value){
|
|
|
|
this.timeline_ = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
get timeline(){
|
|
|
|
return this.timeline_;
|
|
|
|
}
|
2020-07-24 13:51:36 +00:00
|
|
|
//TODO(zcankare) Depreciate 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;
|
|
|
|
});
|
|
|
|
}
|
2020-07-10 10:02:08 +00:00
|
|
|
|
|
|
|
update() {
|
2020-07-15 04:51:13 +00:00
|
|
|
this.removeAllChildren(this.stats);
|
2020-07-10 10:02:08 +00:00
|
|
|
this.updateGeneralStats();
|
|
|
|
this.updateNamedTransitionsStats();
|
|
|
|
}
|
|
|
|
|
|
|
|
updateGeneralStats() {
|
|
|
|
console.assert(this.timeline_ !== undefined, "Timeline not set yet!");
|
|
|
|
let pairs = [
|
|
|
|
['Total', null, e => true],
|
2020-07-28 09:02:26 +00:00
|
|
|
['Transitions', 'primary', e => e.edge && e.edge.isTransition()],
|
2020-07-10 10:02:08 +00:00
|
|
|
['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 = '';
|
2020-07-16 14:46:13 +00:00
|
|
|
let tableNode = this.table('transitionType');
|
2020-07-10 10:02:08 +00:00
|
|
|
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]) => {
|
2020-07-16 14:46:13 +00:00
|
|
|
let row = this.tr();
|
2020-07-10 10:02:08 +00:00
|
|
|
if (color !== null) {
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(this.div(['colorbox', color])));
|
2020-07-10 10:02:08 +00:00
|
|
|
} else {
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(''));
|
2020-07-10 10:02:08 +00:00
|
|
|
}
|
|
|
|
row.onclick = (e) => {
|
|
|
|
// lazily compute the stats
|
|
|
|
let node = e.target.parentNode;
|
|
|
|
if (node.maps == undefined) {
|
2020-07-24 13:51:36 +00:00
|
|
|
node.maps = this.filterUniqueTransitions(filter);
|
2020-07-10 10:02:08 +00:00
|
|
|
}
|
|
|
|
this.dispatchEvent(new CustomEvent(
|
|
|
|
'change', {bubbles: true, composed: true, detail: node.maps}));
|
|
|
|
};
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(name));
|
2020-07-10 10:02:08 +00:00
|
|
|
let count = this.timeline.count(filter);
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(count));
|
2020-07-10 10:02:08 +00:00
|
|
|
let percent = Math.round(count / total * 1000) / 10;
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(percent.toFixed(1) + '%'));
|
2020-07-10 10:02:08 +00:00
|
|
|
tableNode.appendChild(row);
|
|
|
|
});
|
2020-07-15 04:51:13 +00:00
|
|
|
this.stats.appendChild(tableNode);
|
2020-07-10 10:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updateNamedTransitionsStats() {
|
2020-07-16 14:46:13 +00:00
|
|
|
let tableNode = this.table('transitionTable');
|
2020-07-24 13:51:36 +00:00
|
|
|
let nameMapPairs = Array.from(this.transitions.entries());
|
2020-07-10 10:02:08 +00:00
|
|
|
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
|
|
|
|
]) => {
|
2020-07-16 14:46:13 +00:00
|
|
|
let row = this.tr();
|
2020-07-10 10:02:08 +00:00
|
|
|
row.maps = maps;
|
|
|
|
row.addEventListener(
|
|
|
|
'click',
|
|
|
|
e => this.dispatchEvent(new CustomEvent(
|
2020-07-24 13:51:36 +00:00
|
|
|
'change', {bubbles: true, composed: true,
|
|
|
|
detail: e.target.parentNode.maps.map(map => map.to)})));
|
2020-07-16 14:46:13 +00:00
|
|
|
row.appendChild(this.td(name));
|
|
|
|
row.appendChild(this.td(maps.length));
|
2020-07-10 10:02:08 +00:00
|
|
|
tableNode.appendChild(row);
|
|
|
|
});
|
2020-07-15 04:51:13 +00:00
|
|
|
this.stats.appendChild(tableNode);
|
2020-07-10 10:02:08 +00:00
|
|
|
}
|
|
|
|
});
|