[turbolizer] Selection broker explicit typing and speed up

Bug: v8:7327
Change-Id: I76317cd206d95584e77b6ece9860a551107154b3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3760456
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Danylo Boiko <danielboyko02@gmail.com>
Cr-Commit-Position: refs/heads/main@{#81822}
This commit is contained in:
Danylo Boiko 2022-07-18 21:46:59 +03:00 committed by V8 LUCI CQ
parent 81bd4a559b
commit eacdf120d9
9 changed files with 130 additions and 131 deletions

View File

@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { SourceResolver } from "../source-resolver";
import { GenericPosition, SourceResolver } from "../source-resolver";
import {
ClearableHandler,
SelectionHandler,
SourcePositionSelectionHandler,
NodeSelectionHandler,
BlockSelectionHandler,
InstructionSelectionHandler,
@ -15,27 +15,22 @@ import {
export class SelectionBroker {
sourceResolver: SourceResolver;
allHandlers: Array<ClearableHandler>;
sourcePositionHandlers: Array<SelectionHandler>;
nodeHandlers: Array<NodeSelectionHandler>;
blockHandlers: Array<BlockSelectionHandler>;
instructionHandlers: Array<InstructionSelectionHandler>;
sourcePositionHandlers: Array<SourcePositionSelectionHandler>;
registerAllocationHandlers: Array<RegisterAllocationSelectionHandler>;
constructor(sourceResolver: SourceResolver) {
this.sourceResolver = sourceResolver;
this.allHandlers = new Array<ClearableHandler>();
this.sourcePositionHandlers = new Array<SelectionHandler>();
this.nodeHandlers = new Array<NodeSelectionHandler>();
this.blockHandlers = new Array<BlockSelectionHandler>();
this.instructionHandlers = new Array<InstructionSelectionHandler>();
this.sourcePositionHandlers = new Array<SourcePositionSelectionHandler>();
this.registerAllocationHandlers = new Array<RegisterAllocationSelectionHandler>();
}
public addSourcePositionHandler(handler: SelectionHandler & ClearableHandler): void {
this.allHandlers.push(handler);
this.sourcePositionHandlers.push(handler);
}
public addNodeHandler(handler: NodeSelectionHandler & ClearableHandler): void {
this.allHandlers.push(handler);
this.nodeHandlers.push(handler);
@ -61,12 +56,19 @@ export class SelectionBroker {
this.instructionHandlers.push(handler);
}
public addSourcePositionHandler(handler: SourcePositionSelectionHandler & ClearableHandler):
void {
this.allHandlers.push(handler);
this.sourcePositionHandlers.push(handler);
}
public addRegisterAllocatorHandler(handler: RegisterAllocationSelectionHandler
& ClearableHandler): void {
this.allHandlers.push(handler);
this.registerAllocationHandlers.push(handler);
}
// TODO (danylo boiko) Add instructionOffsets type
public broadcastInstructionSelect(from, instructionOffsets, selected: boolean): void {
// Select the lines from the disassembly (right panel)
for (const handler of this.instructionHandlers) {
@ -84,11 +86,11 @@ export class SelectionBroker {
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
}
}
// The middle panel lines have already been selected so there's no need to reselect them.
}
public broadcastSourcePositionSelect(from, sourcePositions, selected: boolean): void {
public broadcastSourcePositionSelect(from, sourcePositions: Array<GenericPosition>,
selected: boolean): void {
sourcePositions = sourcePositions.filter(sourcePosition => {
if (!sourcePosition.isValid()) {
console.warn("Invalid source position");
@ -108,26 +110,10 @@ export class SelectionBroker {
if (handler != from) handler.brokeredNodeSelect(nodes, selected);
}
for (const node of nodes) {
const instructionOffsets = this.sourceResolver.instructionsPhase
.nodeIdToInstructionRange[node];
// Skip nodes which do not have an associated instruction range.
if (instructionOffsets == undefined) continue;
// Select the lines from the disassembly (right panel)
for (const handler of this.instructionHandlers) {
if (handler != from) handler.brokeredInstructionSelect(instructionOffsets, selected);
}
// Select the lines from the middle panel for the register allocation phase.
for (const handler of this.registerAllocationHandlers) {
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
}
}
this.selectInstructionsAndRegisterAllocations(from, nodes, selected);
}
public broadcastNodeSelect(from, nodes, selected: boolean): void {
public broadcastNodeSelect(from, nodes: Set<string>, selected: boolean): void {
// Select the nodes (middle panel)
for (const handler of this.nodeHandlers) {
if (handler != from) handler.brokeredNodeSelect(nodes, selected);
@ -139,33 +125,41 @@ export class SelectionBroker {
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
}
for (const node of nodes) {
const instructionOffsets = this.sourceResolver.instructionsPhase
.nodeIdToInstructionRange[node];
// Skip nodes which do not have an associated instruction range.
if (instructionOffsets == undefined) continue;
// Select the lines from the disassembly (right panel)
for (const handler of this.instructionHandlers) {
if (handler != from) handler.brokeredInstructionSelect(instructionOffsets, selected);
}
// Select the lines from the middle panel for the register allocation phase.
for (const handler of this.registerAllocationHandlers) {
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
}
}
this.selectInstructionsAndRegisterAllocations(from, nodes, selected);
}
public broadcastBlockSelect(from, blocks, selected: boolean): void {
public broadcastBlockSelect(from, blocksIds: Array<string>, selected: boolean): void {
for (const handler of this.blockHandlers) {
if (handler != from) handler.brokeredBlockSelect(blocks, selected);
if (handler != from) handler.brokeredBlockSelect(blocksIds, selected);
}
}
public broadcastClear(from): void {
this.allHandlers.forEach(handler => {
for (const handler of this.allHandlers) {
if (handler != from) handler.brokeredClear();
});
}
}
private selectInstructionsAndRegisterAllocations(from, nodes: Set<string>, selected: boolean):
void {
const instructionsOffsets = new Array<[number, number]>();
for (const node of nodes) {
const instructionRange = this.sourceResolver.instructionsPhase.nodeIdToInstructionRange[node];
if (instructionRange) instructionsOffsets.push(instructionRange);
}
if (instructionsOffsets.length > 0) {
// Select the lines from the disassembly (right panel)
for (const handler of this.instructionHandlers) {
if (handler != from) handler.brokeredInstructionSelect(instructionsOffsets, selected);
}
// Select the lines from the middle panel for the register allocation phase.
for (const handler of this.registerAllocationHandlers) {
if (handler != from) {
handler.brokeredRegisterAllocationSelect(instructionsOffsets, selected);
}
}
}
}
}

View File

@ -2,37 +2,43 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { TurboshaftGraphNode } from "../phases/turboshaft-graph-phase/turboshaft-graph-node";
import { GraphNode } from "../phases/graph-phase/graph-node";
import { TurboshaftGraphBlock } from "../phases/turboshaft-graph-phase/turboshaft-graph-block";
import { GenericPosition } from "../source-resolver";
export interface ClearableHandler {
brokeredClear(): void;
}
export interface SelectionHandler {
select(nodeIds: any, selected: any): void;
clear(): void;
brokeredSourcePositionSelect(sourcePositions: any, selected: any): void;
}
export interface NodeSelectionHandler {
select(nodeIds: any, selected: any): void;
select(nodes: Iterable<TurboshaftGraphNode | GraphNode | string>, selected: boolean): void;
clear(): void;
brokeredNodeSelect(nodeIds: any, selected: any): void;
brokeredNodeSelect(nodeIds: Set<string>, selected: boolean): void;
}
export interface BlockSelectionHandler {
select(nodeIds: any, selected: any): void;
select(blocks: Iterable<TurboshaftGraphBlock | string>, selected: boolean): void;
clear(): void;
brokeredBlockSelect(blockIds: any, selected: any): void;
brokeredBlockSelect(blockIds: Array<string>, selected: boolean): void;
}
export interface InstructionSelectionHandler {
select(instructionIds: any, selected: any): void;
select(instructionIds: Array<string>, selected: boolean): void;
clear(): void;
brokeredInstructionSelect(instructionIds: any, selected: any): void;
brokeredInstructionSelect(instructionsOffsets: Array<[number, number]>, selected: boolean): void;
}
export interface SourcePositionSelectionHandler {
select(sourcePositions: Array<GenericPosition>, selected: boolean): void;
clear(): void;
brokeredSourcePositionSelect(sourcePositions: Array<GenericPosition>, selected: boolean): void;
}
export interface RegisterAllocationSelectionHandler {
// These are called instructionIds since the class of the divs is "instruction-id"
select(instructionIds: any, selected: any): void;
select(instructionIds: Array<string>, selected: boolean): void;
clear(): void;
brokeredRegisterAllocationSelect(instructionIds: any, selected: any): void;
brokeredRegisterAllocationSelect(instructionsOffsets: Array<[number, number]>, selected: boolean):
void;
}

View File

@ -198,7 +198,7 @@ export class SourceResolver {
return nodeIds;
}
public nodeIdsToSourcePositions(nodeIds: Array<string>): Array<GenericPosition> {
public nodeIdsToSourcePositions(nodeIds: Iterable<string>): Array<GenericPosition> {
const sourcePositions = new Map<string, GenericPosition>();
for (const nodeId of nodeIds) {
const position = this.nodePositionMap[nodeId];

View File

@ -8,7 +8,7 @@ import { SelectionBroker } from "../selection/selection-broker";
import { View } from "./view";
import { SelectionMap } from "../selection/selection-map";
import { ViewElements } from "../common/view-elements";
import { ClearableHandler, SelectionHandler } from "../selection/selection-handler";
import { ClearableHandler, SourcePositionSelectionHandler } from "../selection/selection-handler";
import { SourcePosition } from "../position";
interface PR {
@ -31,8 +31,8 @@ export class CodeView extends View {
codeMode: CodeMode;
sourcePositionToHtmlElements: Map<string, Array<HTMLElement>>;
showAdditionalInliningPosition: boolean;
selection: SelectionMap;
selectionHandler: SelectionHandler & ClearableHandler;
sourcePositionSelection: SelectionMap;
sourcePositionSelectionHandler: SourcePositionSelectionHandler & ClearableHandler;
constructor(parent: HTMLElement, broker: SelectionBroker, sourceFunction: Source,
sourceResolver: SourceResolver, codeMode: CodeMode) {
@ -44,9 +44,9 @@ export class CodeView extends View {
this.sourcePositionToHtmlElements = new Map<string, Array<HTMLElement>>();
this.showAdditionalInliningPosition = false;
this.selection = new SelectionMap((gp: GenericPosition) => gp.toString());
this.selectionHandler = this.initializeSourcePositionHandler();
broker.addSourcePositionHandler(this.selectionHandler);
this.sourcePositionSelection = new SelectionMap((gp: GenericPosition) => gp.toString());
this.sourcePositionSelectionHandler = this.initializeSourcePositionSelectionHandler();
broker.addSourcePositionHandler(this.sourcePositionSelectionHandler);
this.initializeCode();
}
@ -112,7 +112,7 @@ export class CodeView extends View {
view.onSelectLine(Number(targetDiv.dataset.lineNumber), !e.shiftKey);
}
} else {
view.selectionHandler.clear();
view.sourcePositionSelectionHandler.clear();
}
};
@ -148,7 +148,8 @@ export class CodeView extends View {
}
}
private initializeSourcePositionHandler(): SelectionHandler & ClearableHandler {
private initializeSourcePositionSelectionHandler(): SourcePositionSelectionHandler
& ClearableHandler {
const view = this;
const broker = this.broker;
const sourceResolver = this.sourceResolver;
@ -160,26 +161,26 @@ export class CodeView extends View {
sourceResolver.addInliningPositions(sourcePosition, locations);
}
if (locations.length == 0) return;
view.selection.select(locations, selected);
view.sourcePositionSelection.select(locations, selected);
view.updateSelection();
broker.broadcastSourcePositionSelect(this, locations, selected);
},
clear: function () {
view.selection.clear();
view.sourcePositionSelection.clear();
view.updateSelection();
broker.broadcastClear(this);
},
brokeredSourcePositionSelect: function (locations: Array<SourcePosition>, selected: boolean) {
const firstSelect = view.selection.isEmpty();
const firstSelect = view.sourcePositionSelection.isEmpty();
for (const location of locations) {
const translated = sourceResolver.translateToSourceId(view.source.sourceId, location);
if (!translated) continue;
view.selection.select([translated], selected);
view.sourcePositionSelection.select([translated], selected);
}
view.updateSelection(firstSelect);
},
brokeredClear: function () {
view.selection.clear();
view.sourcePositionSelection.clear();
view.updateSelection();
},
};
@ -196,7 +197,7 @@ export class CodeView extends View {
private updateSelection(scrollIntoView: boolean = false): void {
const mkVisible = new ViewElements(this.divNode.parentNode as HTMLElement);
for (const [sp, els] of this.sourcePositionToHtmlElements.entries()) {
const isSelected = this.selection.isKeySelected(sp);
const isSelected = this.sourcePositionSelection.isKeySelected(sp);
for (const el of els) {
mkVisible.consider(el, isSelected);
el.classList.toggle("selected", isSelected);
@ -220,19 +221,19 @@ export class CodeView extends View {
private onSelectLine(lineNumber: number, doClear: boolean) {
if (doClear) {
this.selectionHandler.clear();
this.sourcePositionSelectionHandler.clear();
}
const positions = this.sourceResolver.lineToSourcePositions(lineNumber - 1);
if (positions !== undefined) {
this.selectionHandler.select(positions, undefined);
this.sourcePositionSelectionHandler.select(positions, undefined);
}
}
private onSelectSourcePosition(sourcePosition: SourcePosition, doClear: boolean) {
if (doClear) {
this.selectionHandler.clear();
this.sourcePositionSelectionHandler.clear();
}
this.selectionHandler.select([sourcePosition], undefined);
this.sourcePositionSelectionHandler.select([sourcePosition], undefined);
}
private insertSourcePositions(currentSpan: HTMLSpanElement, lineNumber: number,

View File

@ -57,7 +57,7 @@ export class DisassemblyView extends TextView {
public updateSelection(scrollIntoView: boolean = false): void {
super.updateSelection(scrollIntoView);
const selectedKeys = this.selection.selectedKeys();
const selectedKeys = this.nodeSelection.selectedKeys();
const keyPcOffsets: Array<TurbolizerInstructionStartInfo | string> = [
...this.sourceResolver.instructionsPhase.nodesToKeyPcOffsets(selectedKeys)
];
@ -186,7 +186,7 @@ export class DisassemblyView extends TextView {
const view = this;
const broker = this.broker;
return {
select: function (instructionIds: Array<number>, selected: boolean) {
select: function (instructionIds: Array<string>, selected: boolean) {
view.offsetSelection.select(instructionIds, selected);
view.updateSelection();
broker.broadcastBlockSelect(this, instructionIds, selected);
@ -196,11 +196,14 @@ export class DisassemblyView extends TextView {
view.updateSelection();
broker.broadcastClear(this);
},
brokeredInstructionSelect: function (instructionIds: Array<number>, selected: boolean) {
brokeredInstructionSelect: function (instructionsOffsets: Array<[number, number]>,
selected: boolean) {
const firstSelect = view.offsetSelection.isEmpty();
const keyPcOffsets = view.sourceResolver.instructionsPhase
.instructionsToKeyPcOffsets(instructionIds);
view.offsetSelection.select(keyPcOffsets, selected);
for (const instructionOffset of instructionsOffsets) {
const keyPcOffsets = view.sourceResolver.instructionsPhase
.instructionsToKeyPcOffsets(instructionOffset);
view.offsetSelection.select(keyPcOffsets, selected);
}
view.updateSelection(firstSelect);
},
brokeredClear: function () {
@ -221,8 +224,8 @@ export class DisassemblyView extends TextView {
const nodes = this.sourceResolver.instructionsPhase.nodesForPCOffset(offset);
if (nodes.length > 0) {
e.stopPropagation();
if (!e.shiftKey) this.selectionHandler.clear();
this.selectionHandler.select(nodes, true);
if (!e.shiftKey) this.nodeSelectionHandler.clear();
this.nodeSelectionHandler.select(nodes, true);
} else {
this.updateSelection();
}
@ -235,7 +238,7 @@ export class DisassemblyView extends TextView {
const blockId = spanBlockElement.dataset.blockId;
if (blockId !== undefined) {
const blockIds = blockId.split(",");
if (!e.shiftKey) this.selectionHandler.clear();
if (!e.shiftKey) this.nodeSelectionHandler.clear();
this.blockSelectionHandler.select(blockIds, true);
}
}

View File

@ -412,10 +412,10 @@ export class GraphView extends MovableView<Graph> {
view.broker.broadcastClear(this);
view.updateGraphVisibility();
},
brokeredNodeSelect: function (locations, selected: boolean) {
brokeredNodeSelect: function (nodeIds: Set<string>, selected: boolean) {
if (!view.graph) return;
const selection = view.graph.nodes(node =>
locations.has(node.identifier()) && (!view.state.hideDead || node.isLive()));
const selection = view.graph.nodes(node => nodeIds.has(node.identifier())
&& (!view.state.hideDead || node.isLive()));
view.state.selection.select(selection, selected);
// Update edge visibility based on selection.
for (const item of view.state.selection.selectedKeys()) {

View File

@ -24,14 +24,14 @@ export class ScheduleView extends TextView {
private attachSelection(adaptedSelection: SelectionStorage): void {
if (!(adaptedSelection instanceof SelectionStorage)) return;
this.selectionHandler.clear();
this.nodeSelectionHandler.clear();
this.blockSelectionHandler.clear();
this.selectionHandler.select(adaptedSelection.adaptedNodes, true);
this.nodeSelectionHandler.select(adaptedSelection.adaptedNodes, true);
this.blockSelectionHandler.select(adaptedSelection.adaptedBocks, true);
}
public detachSelection(): SelectionStorage {
return new SelectionStorage(this.selection.detachSelection(),
return new SelectionStorage(this.nodeSelection.detachSelection(),
this.blockSelection.detachSelection());
}
@ -71,9 +71,9 @@ export class ScheduleView extends TextView {
return function (e) {
e.stopPropagation();
if (!e.shiftKey) {
view.selectionHandler.clear();
view.nodeSelectionHandler.clear();
}
view.selectionHandler.select([nodeId], true);
view.nodeSelectionHandler.select([nodeId], true);
};
}
@ -180,7 +180,7 @@ export class ScheduleView extends TextView {
searchInputAction(searchBar, e, onlyVisible) {
e.stopPropagation();
this.selectionHandler.clear();
this.nodeSelectionHandler.clear();
const query = searchBar.value;
if (query.length == 0) return;
const select = [];
@ -192,6 +192,6 @@ export class ScheduleView extends TextView {
select.push(node.id);
}
}
this.selectionHandler.select(select, true);
this.nodeSelectionHandler.select(select, true);
}
}

View File

@ -40,14 +40,14 @@ export class SequenceView extends TextView {
private attachSelection(adaptedSelection: SelectionStorage): void {
if (!(adaptedSelection instanceof SelectionStorage)) return;
this.selectionHandler.clear();
this.nodeSelectionHandler.clear();
this.blockSelectionHandler.clear();
this.selectionHandler.select(adaptedSelection.adaptedNodes, true);
this.nodeSelectionHandler.select(adaptedSelection.adaptedNodes, true);
this.blockSelectionHandler.select(adaptedSelection.adaptedBocks, true);
}
public detachSelection(): SelectionStorage {
return new SelectionStorage(this.selection.detachSelection(),
return new SelectionStorage(this.nodeSelection.detachSelection(),
this.blockSelection.detachSelection());
}
@ -89,13 +89,6 @@ export class SequenceView extends TextView {
this.divNode.innerHTML = '';
this.sequence = sequence;
this.searchInfo = [];
this.divNode.onclick = (e: MouseEvent) => {
if (!(e.target instanceof HTMLElement)) return;
const instructionId = Number.parseInt(e.target.dataset.instructionId, 10);
if (!instructionId) return;
if (!e.shiftKey) this.broker.broadcastClear(null);
this.broker.broadcastInstructionSelect(null, [instructionId], true);
};
this.phaseSelect = (document.getElementById('phase-select') as HTMLSelectElement);
this.currentPhaseIndex = this.phaseSelect.selectedIndex;
this.addBlocks(this.sequence.blocks);
@ -131,7 +124,7 @@ export class SequenceView extends TextView {
}
function mkOperandLinkHandler(text) {
return mkLinkHandler(text, view.selectionHandler);
return mkLinkHandler(text, view.nodeSelectionHandler);
}
function elementForOperandWithSpan(span, text, searchInfo, isVirtual) {
@ -367,7 +360,7 @@ export class SequenceView extends TextView {
searchInputAction(searchBar, e) {
e.stopPropagation();
this.selectionHandler.clear();
this.nodeSelectionHandler.clear();
const query = searchBar.value;
if (query.length == 0) return;
const select = [];
@ -378,6 +371,6 @@ export class SequenceView extends TextView {
select.push(item);
}
}
this.selectionHandler.select(select, true);
this.nodeSelectionHandler.select(select, true);
}
}

View File

@ -20,10 +20,12 @@ import {
type GenericTextPhase = DisassemblyPhase | SchedulePhase | SequencePhase;
export abstract class TextView extends PhaseView {
selectionHandler: NodeSelectionHandler & ClearableHandler;
broker: SelectionBroker;
sourceResolver: SourceResolver;
nodeSelectionHandler: NodeSelectionHandler & ClearableHandler;
blockSelectionHandler: BlockSelectionHandler & ClearableHandler;
registerAllocationSelectionHandler: RegisterAllocationSelectionHandler & ClearableHandler;
selection: SelectionMap;
nodeSelection: SelectionMap;
blockSelection: SelectionMap;
registerAllocationSelection: SelectionMap;
textListNode: HTMLUListElement;
@ -33,8 +35,6 @@ export abstract class TextView extends PhaseView {
blockIdToNodeIds: Map<string, Array<string>>;
nodeIdToBlockId: Array<string>;
patterns: Array<Array<any>>;
sourceResolver: SourceResolver;
broker: SelectionBroker;
constructor(parent: HTMLDivElement, broker: SelectionBroker) {
super(parent);
@ -47,21 +47,21 @@ export abstract class TextView extends PhaseView {
this.blockIdToNodeIds = new Map<string, Array<string>>();
this.nodeIdToBlockId = new Array<string>();
this.selection = new SelectionMap(node => String(node));
this.nodeSelection = new SelectionMap(node => String(node));
this.blockSelection = new SelectionMap(block => String(block));
this.registerAllocationSelection = new SelectionMap(register => String(register));
this.selectionHandler = this.initializeNodeSelectionHandler();
this.nodeSelectionHandler = this.initializeNodeSelectionHandler();
this.blockSelectionHandler = this.initializeBlockSelectionHandler();
this.registerAllocationSelectionHandler = this.initializeRegisterAllocationSelectionHandler();
broker.addNodeHandler(this.selectionHandler);
broker.addNodeHandler(this.nodeSelectionHandler);
broker.addBlockHandler(this.blockSelectionHandler);
broker.addRegisterAllocatorHandler(this.registerAllocationSelectionHandler);
this.divNode.addEventListener("click", e => {
if (!e.shiftKey) {
this.selectionHandler.clear();
this.nodeSelectionHandler.clear();
}
e.stopPropagation();
});
@ -110,7 +110,7 @@ export abstract class TextView extends PhaseView {
element.classList.toggle("selected", false);
}
}
for (const nodeId of this.selection.selectedKeys()) {
for (const nodeId of this.nodeSelection.selectedKeys()) {
const elements = this.nodeIdToHtmlElementsMap.get(nodeId);
if (!elements) continue;
for (const element of elements) {
@ -208,22 +208,22 @@ export abstract class TextView extends PhaseView {
const view = this;
return {
select: function (nodeIds: Array<string>, selected: boolean) {
view.selection.select(nodeIds, selected);
view.nodeSelection.select(nodeIds, selected);
view.updateSelection();
view.broker.broadcastNodeSelect(this, view.selection.selectedKeys(), selected);
view.broker.broadcastNodeSelect(this, view.nodeSelection.selectedKeys(), selected);
},
clear: function () {
view.selection.clear();
view.nodeSelection.clear();
view.updateSelection();
view.broker.broadcastClear(this);
},
brokeredNodeSelect: function (nodeIds: Set<string>, selected: boolean) {
const firstSelect = view.blockSelection.isEmpty();
view.selection.select(nodeIds, selected);
view.nodeSelection.select(nodeIds, selected);
view.updateSelection(firstSelect);
},
brokeredClear: function () {
view.selection.clear();
view.nodeSelection.clear();
view.updateSelection();
}
};
@ -258,7 +258,7 @@ export abstract class TextView extends PhaseView {
& ClearableHandler {
const view = this;
return {
select: function (instructionIds: Array<number>, selected: boolean) {
select: function (instructionIds: Array<string>, selected: boolean) {
view.registerAllocationSelection.select(instructionIds, selected);
view.updateSelection();
view.broker.broadcastInstructionSelect(null, [instructionIds], selected);
@ -268,10 +268,12 @@ export abstract class TextView extends PhaseView {
view.updateSelection();
view.broker.broadcastClear(this);
},
brokeredRegisterAllocationSelect: function (instructionIds: Array<number>,
brokeredRegisterAllocationSelect: function (instructionsOffsets: Array<[number, number]>,
selected: boolean) {
const firstSelect = view.blockSelection.isEmpty();
view.registerAllocationSelection.select(instructionIds, selected);
for (const instructionOffset of instructionsOffsets) {
view.registerAllocationSelection.select(instructionOffset, selected);
}
view.updateSelection(firstSelect);
},
brokeredClear: function () {