[tools] System-analyzer: color source panel marks by event type

Change the background of source position markers based on the events
they link to.

Bug: v8:10644
Change-Id: I108d9f5670acdaf5835905c2b44648c0eaf6dbd0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2604708
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71970}
This commit is contained in:
Camillo Bruni 2021-01-08 10:37:22 +01:00 committed by Commit Bot
parent 060a31a00c
commit 876218e45b
5 changed files with 54 additions and 19 deletions

View File

@ -52,6 +52,13 @@ class App {
this._startupPromise = this.runAsyncInitialize(); this._startupPromise = this.runAsyncInitialize();
} }
static get allEventTypes() {
return new Set([
SourcePosition, MapLogEntry, IcLogEntry, ApiLogEntry, CodeLogEntry,
DeoptLogEntry
]);
}
async runAsyncInitialize() { async runAsyncInitialize() {
await Promise.all([ await Promise.all([
import('./view/list-panel.mjs'), import('./view/list-panel.mjs'),
@ -118,10 +125,7 @@ class App {
} }
selectEntries(entries) { selectEntries(entries) {
const missingTypes = new Set([ const missingTypes = App.allEventTypes;
SourcePosition, MapLogEntry, IcLogEntry, ApiLogEntry, CodeLogEntry,
DeoptLogEntry
]);
groupBy(entries, each => each.constructor, true).forEach(group => { groupBy(entries, each => each.constructor, true).forEach(group => {
this.selectEntriesOfSingleType(group.entries); this.selectEntriesOfSingleType(group.entries);
missingTypes.delete(group.key); missingTypes.delete(group.key);

View File

@ -233,6 +233,10 @@ class Chunk {
return this.items.length; return this.items.length;
} }
get length() {
return this.items.length;
}
yOffset(event) { yOffset(event) {
// items[0] == oldest event, displayed at the top of the chunk // items[0] == oldest event, displayed at the top of the chunk
// items[n-1] == youngest event, displayed at the bottom of the chunk // items[n-1] == youngest event, displayed at the bottom of the chunk

View File

@ -287,6 +287,23 @@ class LazyTable {
} }
} }
export function gradientStopsFromGroups(
totalLength, maxHeight, groups, colorFn) {
const kMaxHeight = maxHeight === '%' ? 100 : maxHeight;
const kUnit = maxHeight === '%' ? '%' : 'px';
let increment = 0;
let lastHeight = 0.0;
const stops = [];
for (let group of groups) {
const color = colorFn(group.key);
increment += group.count;
let height = (increment / totalLength * kMaxHeight) | 0;
stops.push(`${color} ${lastHeight}${kUnit} ${height}${kUnit}`)
lastHeight = height;
}
return stops;
}
export * from '../helper.mjs'; export * from '../helper.mjs';
export { export {
DOM, DOM,

View File

@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {groupBy} from '../helper.mjs'; import {groupBy} from '../helper.mjs';
import {App} from '../index.mjs'
import {SelectRelatedEvent, ToolTipEvent} from './events.mjs'; import {SelectRelatedEvent, ToolTipEvent} from './events.mjs';
import {delay, DOM, formatBytes, V8CustomElement} from './helper.mjs'; import {CSSColor, delay, DOM, formatBytes, gradientStopsFromGroups, V8CustomElement} from './helper.mjs';
DOM.defineCustomElement('view/script-panel', DOM.defineCustomElement('view/script-panel',
(templateText) => (templateText) =>
@ -193,6 +194,18 @@ function* lineIterator(source) {
} }
class LineBuilder { class LineBuilder {
static _colorMap = (function() {
const map = new Map();
let i = 0;
for (let type of App.allEventTypes) {
map.set(type, CSSColor.at(i++));
}
return map;
})();
static get colorMap() {
return this._colorMap;
}
_script; _script;
_clickHandler; _clickHandler;
_mouseoverHandler; _mouseoverHandler;
@ -248,6 +261,13 @@ class LineBuilder {
marker.sourcePosition = sourcePosition; marker.sourcePosition = sourcePosition;
marker.onclick = this._clickHandler; marker.onclick = this._clickHandler;
marker.onmouseover = this._mouseoverHandler; marker.onmouseover = this._mouseoverHandler;
const entries = sourcePosition.entries;
const stops = gradientStopsFromGroups(
entries.length, '%', groupBy(entries, entry => entry.constructor),
type => LineBuilder.colorMap.get(type));
marker.style.backgroundImage = `linear-gradient(0deg,${stops.join(',')})`
return marker; return marker;
} }
} }

View File

@ -5,7 +5,7 @@
import {kChunkHeight, kChunkWidth} from '../../log/map.mjs'; import {kChunkHeight, kChunkWidth} from '../../log/map.mjs';
import {MapLogEntry} from '../../log/map.mjs'; import {MapLogEntry} from '../../log/map.mjs';
import {FocusEvent, SelectionEvent, SelectTimeEvent, SynchronizeSelectionEvent, ToolTipEvent,} from '../events.mjs'; import {FocusEvent, SelectionEvent, SelectTimeEvent, SynchronizeSelectionEvent, ToolTipEvent,} from '../events.mjs';
import {CSSColor, DOM, V8CustomElement} from '../helper.mjs'; import {CSSColor, DOM, gradientStopsFromGroups, V8CustomElement} from '../helper.mjs';
DOM.defineCustomElement('view/timeline/timeline-track', DOM.defineCustomElement('view/timeline/timeline-track',
(templateText) => (templateText) =>
@ -147,19 +147,9 @@ DOM.defineCustomElement('view/timeline/timeline-track',
} }
_createBackgroundImage(chunk) { _createBackgroundImage(chunk) {
// Render the types of transitions as bar charts const stops = gradientStopsFromGroups(
const kHeight = chunk.height; chunk.length, chunk.height, chunk.getBreakdown(event => event.type),
const total = chunk.size(); type => this._legend.colorForType(type));
let increment = 0;
let lastHeight = 0.0;
const stops = [];
for (let group of chunk.getBreakdown(map => map.type)) {
const color = this._legend.colorForType(group.key);
increment += group.count;
let height = (increment / total * kHeight) | 0;
stops.push(`${color} ${lastHeight}px ${height}px`)
lastHeight = height;
}
return `linear-gradient(0deg,${stops.join(',')})`; return `linear-gradient(0deg,${stops.join(',')})`;
} }