Commit 959dd7d5 authored by Danylo Boiko's avatar Danylo Boiko Committed by V8 LUCI CQ

[turbolizer] Shortcuts for bidirectional phase switching.

Bidirectional phase switching by shortcuts "n", "b".
Improved selection of nodes when they are splitting or raising to a common ancestor.
Fixed minor inconsistencies in some variable names with the project style.
Added name and email to the AUTHORS file for first-time contribution.

Change-Id: I0c903dbf81c3d1d75503004ce412a81aace06a61
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3537008Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79636}
parent 8b663818
......@@ -91,6 +91,7 @@ Daniel Bevenius <daniel.bevenius@gmail.com>
Daniel Dromboski <dandromb@gmail.com>
Daniel James <dnljms@gmail.com>
Daniel Shelton <d1.shelton@samsung.com>
Danylo Boiko <danielboyko02@gmail.com>
Darshan Sen <raisinten@gmail.com>
David Carlier <devnexen@gmail.com>
David Manouchehri <david@davidmanouchehri.com>
......
......@@ -22,6 +22,14 @@
<td>r</td>
<td>Relayout graph</td>
</tr>
<tr>
<td>n</td>
<td>Show graph with selected nodes for next phase</td>
</tr>
<tr>
<td>b</td>
<td>Show graph with selected nodes for previous phase</td>
</tr>
<tr>
<td>a</td>
<td>Select all nodes</td>
......
......@@ -19,6 +19,13 @@ function nodeToStringKey(n: GNode) {
return "" + n.id;
}
function nodeOriginToStringKey(n: GNode): string | undefined {
if (n.nodeLabel && n.nodeLabel.origin) {
return "" + n.nodeLabel.origin.nodeId;
}
return undefined;
}
interface GraphState {
showTypes: boolean;
selection: MySelection;
......@@ -132,7 +139,7 @@ export class GraphView extends PhaseView {
}
};
view.state.selection = new MySelection(nodeToStringKey);
view.state.selection = new MySelection(nodeToStringKey, nodeOriginToStringKey);
const defs = svg.append('svg:defs');
defs.append('svg:marker')
......@@ -254,12 +261,14 @@ export class GraphView extends PhaseView {
this.toolbox.appendChild(createImgInput("toggle-types", "toggle types",
partial(this.toggleTypesAction, this)));
const adaptedSelection = this.adaptSelectionToCurrentPhase(data.data, rememberedSelection);
this.phaseName = data.name;
this.createGraph(data.data, rememberedSelection);
this.createGraph(data.data, adaptedSelection);
this.broker.addNodeHandler(this.selectionHandler);
if (rememberedSelection != null && rememberedSelection.size > 0) {
this.attachSelection(rememberedSelection);
if (adaptedSelection != null && adaptedSelection.size > 0) {
this.attachSelection(adaptedSelection);
this.connectVisibleSelectedNodes();
this.viewSelection();
} else {
......@@ -286,14 +295,14 @@ export class GraphView extends PhaseView {
this.deleteContent();
}
createGraph(data, rememberedSelection) {
createGraph(data, selection) {
this.graph = new Graph(data);
this.showControlAction(this);
if (rememberedSelection != undefined) {
if (selection != undefined) {
for (const n of this.graph.nodes()) {
n.visible = n.visible || rememberedSelection.has(nodeToStringKey(n));
n.visible = n.visible || selection.has(nodeToStringKey(n));
}
}
......@@ -359,6 +368,33 @@ export class GraphView extends PhaseView {
});
}
adaptSelectionToCurrentPhase(data, selection) {
const updatedGraphSelection = new Set();
if (!data || !(selection instanceof Map)) return updatedGraphSelection;
// Adding survived nodes (with the same id)
for (const node of data.nodes) {
const stringKey = this.state.selection.stringKey(node);
if (selection.has(stringKey)) {
updatedGraphSelection.add(stringKey);
}
}
// Adding children of nodes
for (const node of data.nodes) {
const originStringKey = this.state.selection.originStringKey(node);
if (originStringKey && selection.has(originStringKey)) {
updatedGraphSelection.add(this.state.selection.stringKey(node));
}
}
// Adding ancestors of nodes
selection.forEach(selectedNode => {
const originStringKey = this.state.selection.originStringKey(selectedNode);
if (originStringKey) {
updatedGraphSelection.add(originStringKey);
}
});
return updatedGraphSelection;
}
attachSelection(s) {
if (!(s instanceof Set)) return;
this.selectionHandler.clear();
......
......@@ -8,6 +8,7 @@ import { SequenceView } from "../src/sequence-view";
import { SourceResolver } from "../src/source-resolver";
import { SelectionBroker } from "../src/selection-broker";
import { View, PhaseView } from "../src/view";
import { GNode } from "./node";
const multiviewID = "multiview";
......@@ -61,6 +62,10 @@ export class GraphMultiView extends View {
view.divNode.addEventListener("keyup", (e: KeyboardEvent) => {
if (e.keyCode == 191) { // keyCode == '/'
searchInput.focus();
} else if (e.keyCode == 78) { // keyCode == 'n'
view.displayNextGraphPhase();
} else if (e.keyCode == 66) { // keyCode == 'b'
view.displayPreviousGraphPhase();
}
});
searchInput.setAttribute("value", window.sessionStorage.getItem("lastSearch") || "");
......@@ -101,7 +106,7 @@ export class GraphMultiView extends View {
this.displayPhase(this.sourceResolver.getPhase(initialPhaseIndex));
}
displayPhase(phase, selection?: Set<any>) {
displayPhase(phase, selection?: Map<string, GNode>) {
if (phase.type == "graph") {
this.displayPhaseView(this.graph, phase, selection);
} else if (phase.type == "schedule") {
......@@ -111,18 +116,46 @@ export class GraphMultiView extends View {
}
}
displayPhaseView(view: PhaseView, data, selection?: Set<any>) {
displayPhaseView(view: PhaseView, data, selection?: Map<string, GNode>) {
const rememberedSelection = selection ? selection : this.hideCurrentPhase();
view.initializeContent(data, rememberedSelection);
this.currentPhaseView = view;
}
displayPhaseByName(phaseName, selection?: Set<any>) {
displayPhaseByName(phaseName, selection?: Map<string, GNode>) {
const phaseId = this.sourceResolver.getPhaseIdByName(phaseName);
this.selectMenu.selectedIndex = phaseId;
this.displayPhase(this.sourceResolver.getPhase(phaseId), selection);
}
displayNextGraphPhase() {
let nextPhaseIndex = this.selectMenu.selectedIndex + 1;
while (nextPhaseIndex < this.sourceResolver.phases.length) {
const nextPhase = this.sourceResolver.getPhase(nextPhaseIndex);
if (nextPhase.type == "graph") {
this.selectMenu.selectedIndex = nextPhaseIndex;
window.sessionStorage.setItem("lastSelectedPhase", nextPhaseIndex.toString());
this.displayPhase(nextPhase);
break;
}
nextPhaseIndex += 1;
}
}
displayPreviousGraphPhase() {
let previousPhaseIndex = this.selectMenu.selectedIndex - 1;
while (previousPhaseIndex >= 0) {
const previousPhase = this.sourceResolver.getPhase(previousPhaseIndex);
if (previousPhase.type == "graph") {
this.selectMenu.selectedIndex = previousPhaseIndex;
window.sessionStorage.setItem("lastSelectedPhase", previousPhaseIndex.toString());
this.displayPhase(previousPhase);
break;
}
previousPhaseIndex -= 1;
}
}
hideCurrentPhase() {
let rememberedSelection = null;
if (this.currentPhaseView != null) {
......
......@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { GNode } from "./node";
export class MySelection {
selection: any;
stringKey: (o: any) => string;
originStringKey: (node: GNode) => string;
constructor(stringKeyFnc) {
constructor(stringKeyFnc, originStringKeyFnc?) {
this.selection = new Map();
this.stringKey = stringKeyFnc;
this.originStringKey = originStringKeyFnc;
}
isEmpty(): boolean {
......@@ -50,7 +54,7 @@ export class MySelection {
}
detachSelection() {
const result = this.selectedKeys();
const result = this.selection;
this.clear();
return result;
}
......
......@@ -81,7 +81,7 @@ interface InstructionsPhase {
name: string;
data: any;
instructionOffsetToPCOffset?: any;
blockIdtoInstructionRange?: any;
blockIdToInstructionRange?: any;
nodeIdToInstructionRange?: any;
codeOffsetsInfo?: CodeOffsetsInfo;
}
......@@ -595,8 +595,8 @@ export class SourceResolver {
if (phase.nodeIdToInstructionRange) {
this.readNodeIdToInstructionRange(phase.nodeIdToInstructionRange);
}
if (phase.blockIdtoInstructionRange) {
this.readBlockIdToInstructionRange(phase.blockIdtoInstructionRange);
if (phase.blockIdToInstructionRange) {
this.readBlockIdToInstructionRange(phase.blockIdToInstructionRange);
}
if (phase.instructionOffsetToPCOffset) {
this.readInstructionOffsetToPCOffset(phase.instructionOffsetToPCOffset);
......
......@@ -20,7 +20,7 @@ export abstract class TextView extends PhaseView {
instructionIdToHtmlElementsMap: Map<string, Array<HTMLElement>>;
nodeIdToHtmlElementsMap: Map<string, Array<HTMLElement>>;
blockIdToHtmlElementsMap: Map<string, Array<HTMLElement>>;
blockIdtoNodeIds: Map<string, Array<string>>;
blockIdToNodeIds: Map<string, Array<string>>;
nodeIdToBlockId: Array<string>;
patterns: any;
sourceResolver: SourceResolver;
......@@ -34,7 +34,7 @@ export abstract class TextView extends PhaseView {
view.instructionIdToHtmlElementsMap = new Map();
view.nodeIdToHtmlElementsMap = new Map();
view.blockIdToHtmlElementsMap = new Map();
view.blockIdtoNodeIds = new Map();
view.blockIdToNodeIds = new Map();
view.nodeIdToBlockId = [];
view.selection = new MySelection(anyToString);
view.blockSelection = new MySelection(anyToString);
......@@ -147,10 +147,10 @@ export abstract class TextView extends PhaseView {
addNodeIdToBlockId(anyNodeId, anyBlockId) {
const blockId = anyToString(anyBlockId);
if (!this.blockIdtoNodeIds.has(blockId)) {
this.blockIdtoNodeIds.set(blockId, []);
if (!this.blockIdToNodeIds.has(blockId)) {
this.blockIdToNodeIds.set(blockId, []);
}
this.blockIdtoNodeIds.get(blockId).push(anyToString(anyNodeId));
this.blockIdToNodeIds.get(blockId).push(anyToString(anyNodeId));
this.nodeIdToBlockId[anyNodeId] = blockId;
}
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { GNode } from "./node";
export abstract class View {
protected container: HTMLElement;
protected divNode: HTMLElement;
......@@ -22,8 +24,8 @@ export abstract class View {
}
export abstract class PhaseView extends View {
public abstract initializeContent(data: any, rememberedSelection: Set<any>): void;
public abstract detachSelection(): Set<string>;
public abstract initializeContent(data: any, rememberedSelection: Map<string, GNode>): void;
public abstract detachSelection(): Map<string, GNode>;
public abstract onresize(): void;
public abstract searchInputAction(searchInput: HTMLInputElement, e: Event, onlyVisible: boolean): void;
......
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