[turbolizer] Selection refactoring
- Moved graph-phase.ts to graph-phase folder - Refactored selection.ts, selection-broker.ts, selection-handler.ts, source-resolver.ts Bug: v8:7327 Change-Id: I922c8730f89c53a73a55414378ac1e29a6397a80 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3714945 Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Danylo Boiko <danielboyko02@gmail.com> Cr-Commit-Position: refs/heads/main@{#81385}
This commit is contained in:
parent
087d225520
commit
8e49ce29cd
@ -6,7 +6,7 @@ import * as C from "./common/constants";
|
||||
import { Graph } from "./graph";
|
||||
import { GraphNode } from "./phases/graph-phase/graph-node";
|
||||
import { GraphEdge } from "./phases/graph-phase/graph-edge";
|
||||
import { GraphStateType } from "./phases/graph-phase";
|
||||
import { GraphStateType } from "./phases/graph-phase/graph-phase";
|
||||
|
||||
export class GraphLayout {
|
||||
graph: Graph;
|
||||
|
@ -3,7 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import * as C from "./common/constants";
|
||||
import { GraphPhase, GraphStateType } from "./phases/graph-phase";
|
||||
import { GraphPhase, GraphStateType } from "./phases/graph-phase/graph-phase";
|
||||
import { GraphEdge } from "./phases/graph-phase/graph-edge";
|
||||
import { GraphNode } from "./phases/graph-phase/graph-node";
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { SequenceView } from "./views/sequence-view";
|
||||
import { GenericPhase, SourceResolver } from "./source-resolver";
|
||||
import { SelectionBroker } from "./selection/selection-broker";
|
||||
import { PhaseView, View } from "./views/view";
|
||||
import { GraphPhase } from "./phases/graph-phase";
|
||||
import { GraphPhase } from "./phases/graph-phase/graph-phase";
|
||||
import { GraphNode } from "./phases/graph-phase/graph-node";
|
||||
import { storageGetItem, storageSetItem } from "./common/util";
|
||||
import { PhaseType } from "./phases/phase";
|
||||
@ -147,7 +147,7 @@ export class GraphMultiView extends View {
|
||||
private initializeSelect(): void {
|
||||
const view = this;
|
||||
view.selectMenu.innerHTML = "";
|
||||
view.sourceResolver.forEachPhase((phase: GenericPhase) => {
|
||||
for (const phase of view.sourceResolver.phases) {
|
||||
const optionElement = document.createElement("option");
|
||||
let maxNodeId = "";
|
||||
if (phase instanceof GraphPhase && phase.highestNodeId != 0) {
|
||||
@ -155,7 +155,7 @@ export class GraphMultiView extends View {
|
||||
}
|
||||
optionElement.text = `${phase.name}${maxNodeId}`;
|
||||
view.selectMenu.add(optionElement);
|
||||
});
|
||||
}
|
||||
this.selectMenu.onchange = function (this: HTMLSelectElement) {
|
||||
const phaseIndex = this.selectedIndex;
|
||||
storageSetItem("lastSelectedPhase", phaseIndex);
|
||||
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import { Phase, PhaseType } from "./phase";
|
||||
import { NodeLabel } from "../node-label";
|
||||
import { BytecodeOrigin, NodeOrigin } from "../origin";
|
||||
import { SourcePosition } from "../position";
|
||||
import { GraphNode } from "./graph-phase/graph-node";
|
||||
import { GraphEdge } from "./graph-phase/graph-edge";
|
||||
import { Phase, PhaseType } from "../phase";
|
||||
import { NodeLabel } from "../../node-label";
|
||||
import { BytecodeOrigin, NodeOrigin } from "../../origin";
|
||||
import { SourcePosition } from "../../position";
|
||||
import { GraphNode } from "./graph-node";
|
||||
import { GraphEdge } from "./graph-edge";
|
||||
|
||||
export class GraphPhase extends Phase {
|
||||
highestNodeId: number;
|
@ -29,8 +29,7 @@ export class SourcePosition {
|
||||
}
|
||||
|
||||
public equals(other: SourcePosition): boolean {
|
||||
if (this.scriptOffset != other.scriptOffset) return false;
|
||||
return this.inliningId == other.inliningId;
|
||||
return this.inliningId == other.inliningId && this.scriptOffset == other.scriptOffset;
|
||||
}
|
||||
|
||||
public isValid(): boolean {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import { SourceResolver, sourcePositionValid } from "../source-resolver";
|
||||
import { SourceResolver } from "../source-resolver";
|
||||
import { ClearableHandler, SelectionHandler, NodeSelectionHandler, BlockSelectionHandler, InstructionSelectionHandler, RegisterAllocationSelectionHandler } from "./selection-handler";
|
||||
|
||||
export class SelectionBroker {
|
||||
@ -14,137 +14,141 @@ export class SelectionBroker {
|
||||
instructionHandlers: Array<InstructionSelectionHandler>;
|
||||
registerAllocationHandlers: Array<RegisterAllocationSelectionHandler>;
|
||||
|
||||
constructor(sourceResolver) {
|
||||
this.allHandlers = [];
|
||||
this.sourcePositionHandlers = [];
|
||||
this.nodeHandlers = [];
|
||||
this.blockHandlers = [];
|
||||
this.instructionHandlers = [];
|
||||
this.registerAllocationHandlers = [];
|
||||
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.registerAllocationHandlers = new Array<RegisterAllocationSelectionHandler>();
|
||||
}
|
||||
|
||||
addSourcePositionHandler(handler: SelectionHandler & ClearableHandler) {
|
||||
public addSourcePositionHandler(handler: SelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.sourcePositionHandlers.push(handler);
|
||||
}
|
||||
|
||||
addNodeHandler(handler: NodeSelectionHandler & ClearableHandler) {
|
||||
public addNodeHandler(handler: NodeSelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.nodeHandlers.push(handler);
|
||||
}
|
||||
|
||||
addBlockHandler(handler: BlockSelectionHandler & ClearableHandler) {
|
||||
public addBlockHandler(handler: BlockSelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.blockHandlers.push(handler);
|
||||
}
|
||||
|
||||
addInstructionHandler(handler: InstructionSelectionHandler & ClearableHandler) {
|
||||
public addInstructionHandler(handler: InstructionSelectionHandler & ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.instructionHandlers.push(handler);
|
||||
}
|
||||
|
||||
addRegisterAllocatorHandler(handler: RegisterAllocationSelectionHandler & ClearableHandler) {
|
||||
public addRegisterAllocatorHandler(handler: RegisterAllocationSelectionHandler
|
||||
& ClearableHandler): void {
|
||||
this.allHandlers.push(handler);
|
||||
this.registerAllocationHandlers.push(handler);
|
||||
}
|
||||
|
||||
broadcastInstructionSelect(from, instructionOffsets, selected) {
|
||||
public broadcastInstructionSelect(from, instructionOffsets, selected: boolean): void {
|
||||
// Select the lines from the disassembly (right panel)
|
||||
for (const b of this.instructionHandlers) {
|
||||
if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
for (const handler of this.instructionHandlers) {
|
||||
if (handler != from) handler.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
}
|
||||
|
||||
// Select the lines from the source panel (left panel)
|
||||
const pcOffsets = this.sourceResolver.instructionsPhase
|
||||
.instructionsToKeyPcOffsets(instructionOffsets);
|
||||
|
||||
for (const offset of pcOffsets) {
|
||||
const nodes = this.sourceResolver.instructionsPhase.nodesForPCOffset(offset);
|
||||
const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes);
|
||||
for (const b of this.sourcePositionHandlers) {
|
||||
if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
for (const handler of this.sourcePositionHandlers) {
|
||||
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
}
|
||||
}
|
||||
|
||||
// The middle panel lines have already been selected so there's no need to reselect them.
|
||||
}
|
||||
|
||||
broadcastSourcePositionSelect(from, sourcePositions, selected) {
|
||||
sourcePositions = sourcePositions.filter(l => {
|
||||
if (!sourcePositionValid(l)) {
|
||||
console.log("Warning: invalid source position");
|
||||
public broadcastSourcePositionSelect(from, sourcePositions, selected: boolean): void {
|
||||
sourcePositions = sourcePositions.filter(sourcePosition => {
|
||||
if (!sourcePosition.isValid()) {
|
||||
console.warn("Invalid source position");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Select the lines from the source panel (left panel)
|
||||
for (const b of this.sourcePositionHandlers) {
|
||||
if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
for (const handler of this.sourcePositionHandlers) {
|
||||
if (handler != from) handler.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
}
|
||||
|
||||
// Select the nodes (middle panel)
|
||||
const nodes = this.sourceResolver.sourcePositionsToNodeIds(sourcePositions);
|
||||
for (const b of this.nodeHandlers) {
|
||||
if (b != from) b.brokeredNodeSelect(nodes, selected);
|
||||
for (const handler of this.nodeHandlers) {
|
||||
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 b of this.instructionHandlers) {
|
||||
if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
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 b of this.registerAllocationHandlers) {
|
||||
if (b != from) b.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
for (const handler of this.registerAllocationHandlers) {
|
||||
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
broadcastNodeSelect(from, nodes, selected) {
|
||||
public broadcastNodeSelect(from, nodes, selected: boolean): void {
|
||||
// Select the nodes (middle panel)
|
||||
for (const b of this.nodeHandlers) {
|
||||
if (b != from) b.brokeredNodeSelect(nodes, selected);
|
||||
for (const handler of this.nodeHandlers) {
|
||||
if (handler != from) handler.brokeredNodeSelect(nodes, selected);
|
||||
}
|
||||
|
||||
// Select the lines from the source panel (left panel)
|
||||
const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes);
|
||||
for (const b of this.sourcePositionHandlers) {
|
||||
if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected);
|
||||
for (const handler of this.sourcePositionHandlers) {
|
||||
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 b of this.instructionHandlers) {
|
||||
if (b != from) b.brokeredInstructionSelect(instructionOffsets, selected);
|
||||
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 b of this.registerAllocationHandlers) {
|
||||
if (b != from) b.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
for (const handler of this.registerAllocationHandlers) {
|
||||
if (handler != from) handler.brokeredRegisterAllocationSelect(instructionOffsets, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
broadcastBlockSelect(from, blocks, selected) {
|
||||
for (const b of this.blockHandlers) {
|
||||
if (b != from) b.brokeredBlockSelect(blocks, selected);
|
||||
public broadcastBlockSelect(from, blocks, selected: boolean): void {
|
||||
for (const handler of this.blockHandlers) {
|
||||
if (handler != from) handler.brokeredBlockSelect(blocks, selected);
|
||||
}
|
||||
}
|
||||
|
||||
broadcastClear(from) {
|
||||
this.allHandlers.forEach(function (b) {
|
||||
if (b != from) b.brokeredClear();
|
||||
public broadcastClear(from): void {
|
||||
this.allHandlers.forEach(handler => {
|
||||
if (handler != from) handler.brokeredClear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,56 +4,56 @@
|
||||
|
||||
import { GraphNode } from "../phases/graph-phase/graph-node";
|
||||
|
||||
export class MySelection {
|
||||
selection: any;
|
||||
stringKey: (o: any) => string;
|
||||
export class SelectionMap {
|
||||
selection: Map<string, any>;
|
||||
stringKey: (obj: any) => string;
|
||||
originStringKey: (node: GraphNode) => string;
|
||||
|
||||
constructor(stringKeyFnc, originStringKeyFnc?) {
|
||||
this.selection = new Map();
|
||||
this.selection = new Map<string, any>();
|
||||
this.stringKey = stringKeyFnc;
|
||||
this.originStringKey = originStringKeyFnc;
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
public isEmpty(): boolean {
|
||||
return this.selection.size == 0;
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.selection = new Map();
|
||||
public clear(): void {
|
||||
this.selection = new Map<string, any>();
|
||||
}
|
||||
|
||||
select(s: Iterable<any>, isSelected?: boolean) {
|
||||
for (const i of s) {
|
||||
if (i == undefined) continue;
|
||||
if (isSelected == undefined) {
|
||||
isSelected = !this.selection.has(this.stringKey(i));
|
||||
public select(items: Iterable<any>, isSelected?: boolean): void {
|
||||
for (const item of items) {
|
||||
if (item === undefined) continue;
|
||||
if (isSelected === undefined) {
|
||||
isSelected = !this.selection.has(this.stringKey(item));
|
||||
}
|
||||
if (isSelected) {
|
||||
this.selection.set(this.stringKey(i), i);
|
||||
this.selection.set(this.stringKey(item), item);
|
||||
} else {
|
||||
this.selection.delete(this.stringKey(i));
|
||||
this.selection.delete(this.stringKey(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isSelected(i: any): boolean {
|
||||
return this.selection.has(this.stringKey(i));
|
||||
public isSelected(obj: any): boolean {
|
||||
return this.selection.has(this.stringKey(obj));
|
||||
}
|
||||
|
||||
isKeySelected(key: string): boolean {
|
||||
public isKeySelected(key: string): boolean {
|
||||
return this.selection.has(key);
|
||||
}
|
||||
|
||||
selectedKeys(): Set<string> {
|
||||
public selectedKeys(): Set<string> {
|
||||
const result = new Set<string>();
|
||||
for (const i of this.selection.keys()) {
|
||||
result.add(i);
|
||||
for (const key of this.selection.keys()) {
|
||||
result.add(key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
detachSelection() {
|
||||
public detachSelection(): Map<string, any> {
|
||||
const result = this.selection;
|
||||
this.clear();
|
||||
return result;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import { anyToString, camelize, sortUnique } from "./common/util";
|
||||
import { PhaseType } from "./phases/phase";
|
||||
import { GraphPhase } from "./phases/graph-phase";
|
||||
import { GraphPhase } from "./phases/graph-phase/graph-phase";
|
||||
import { DisassemblyPhase } from "./phases/disassembly-phase";
|
||||
import { BytecodePosition, InliningPosition, SourcePosition } from "./position";
|
||||
import { InstructionsPhase } from "./phases/instructions-phase";
|
||||
@ -15,34 +15,6 @@ import { Source } from "./source";
|
||||
import { NodeLabel } from "./node-label";
|
||||
import { TurboshaftGraphPhase } from "./phases/turboshaft-graph-phase/turboshaft-graph-phase";
|
||||
|
||||
function sourcePositionLe(a, b) {
|
||||
if (a.inliningId == b.inliningId) {
|
||||
return a.scriptOffset - b.scriptOffset;
|
||||
}
|
||||
return a.inliningId - b.inliningId;
|
||||
}
|
||||
|
||||
function sourcePositionEq(a, b) {
|
||||
return a.inliningId == b.inliningId &&
|
||||
a.scriptOffset == b.scriptOffset;
|
||||
}
|
||||
|
||||
export function sourcePositionToStringKey(sourcePosition: GenericPosition): string {
|
||||
if (!sourcePosition) return "undefined";
|
||||
if ('inliningId' in sourcePosition && 'scriptOffset' in sourcePosition) {
|
||||
return "SP:" + sourcePosition.inliningId + ":" + sourcePosition.scriptOffset;
|
||||
}
|
||||
if (sourcePosition.bytecodePosition) {
|
||||
return "BCP:" + sourcePosition.bytecodePosition;
|
||||
}
|
||||
return "undefined";
|
||||
}
|
||||
|
||||
export function sourcePositionValid(l) {
|
||||
return (typeof l.scriptOffset !== undefined
|
||||
&& typeof l.inliningId !== undefined) || typeof l.bytecodePosition != undefined;
|
||||
}
|
||||
|
||||
export type GenericPosition = SourcePosition | BytecodePosition;
|
||||
export type GenericPhase = GraphPhase | TurboshaftGraphPhase | DisassemblyPhase
|
||||
| InstructionsPhase | SchedulePhase | SequencePhase;
|
||||
@ -61,29 +33,29 @@ export class SourceResolver {
|
||||
|
||||
constructor() {
|
||||
// Maps node ids to source positions.
|
||||
this.nodePositionMap = [];
|
||||
this.nodePositionMap = new Array<GenericPosition>();
|
||||
// Maps source ids to source objects.
|
||||
this.sources = [];
|
||||
this.sources = new Array<Source>();
|
||||
// Maps inlining ids to inlining objects.
|
||||
this.inlinings = [];
|
||||
this.inlinings = new Array<InliningPosition>();
|
||||
// Maps source position keys to inlinings.
|
||||
this.inliningsMap = new Map();
|
||||
this.inliningsMap = new Map<string, InliningPosition>();
|
||||
// Maps source position keys to node ids.
|
||||
this.positionToNodes = new Map();
|
||||
this.positionToNodes = new Map<string, Array<string>>();
|
||||
// Maps phase ids to phases.
|
||||
this.phases = [];
|
||||
this.phases = new Array<GenericPhase>();
|
||||
// Maps phase names to phaseIds.
|
||||
this.phaseNames = new Map();
|
||||
this.phaseNames = new Map<string, number>();
|
||||
// The disassembly phase is stored separately.
|
||||
this.disassemblyPhase = undefined;
|
||||
// Maps line numbers to source positions
|
||||
this.linePositionMap = new Map();
|
||||
this.linePositionMap = new Map<string, Array<GenericPosition>>();
|
||||
}
|
||||
|
||||
public getMainFunction(jsonObj): Source {
|
||||
const fncJson = jsonObj.function;
|
||||
// Backwards compatibility.
|
||||
if (typeof fncJson === 'string') {
|
||||
if (typeof fncJson === "string") {
|
||||
return new Source(null, null, jsonObj.source, -1, true,
|
||||
new Array<SourcePosition>(), jsonObj.sourcePosition,
|
||||
jsonObj.sourcePosition + jsonObj.source.length);
|
||||
@ -93,191 +65,66 @@ export class SourceResolver {
|
||||
fncJson.endPosition);
|
||||
}
|
||||
|
||||
setSources(sources, mainBackup) {
|
||||
if (sources) {
|
||||
for (const [sourceId, source] of Object.entries(sources)) {
|
||||
this.sources[sourceId] = source;
|
||||
this.sources[sourceId].sourcePositions = [];
|
||||
}
|
||||
}
|
||||
// This is a fallback if the JSON is incomplete (e.g. due to compiler crash).
|
||||
if (!this.sources[-1]) {
|
||||
this.sources[-1] = mainBackup;
|
||||
this.sources[-1].sourcePositions = [];
|
||||
}
|
||||
}
|
||||
|
||||
setInlinings(inlinings) {
|
||||
if (inlinings) {
|
||||
for (const [inliningId, inlining] of Object.entries<InliningPosition>(inlinings)) {
|
||||
this.inlinings[inliningId] = inlining;
|
||||
this.inliningsMap.set(sourcePositionToStringKey(inlining.inliningPosition), inlining);
|
||||
public setInlinings(inliningsJson): void {
|
||||
if (inliningsJson) {
|
||||
for (const [inliningIdStr, inlining] of Object.entries<InliningPosition>(inliningsJson)) {
|
||||
const scriptOffset = inlining.inliningPosition.scriptOffset;
|
||||
const inliningId = inlining.inliningPosition.inliningId;
|
||||
const inl = new InliningPosition(inlining.sourceId,
|
||||
new SourcePosition(scriptOffset, inliningId));
|
||||
this.inlinings[inliningIdStr] = inl;
|
||||
this.inliningsMap.set(inl.inliningPosition.toString(), inl);
|
||||
}
|
||||
}
|
||||
// This is a default entry for the script itself that helps
|
||||
// keep other code more uniform.
|
||||
this.inlinings[-1] = { sourceId: -1, inliningPosition: null };
|
||||
this.inlinings[-1] = new InliningPosition(-1, null);
|
||||
}
|
||||
|
||||
setNodePositionMap(map) {
|
||||
if (!map) return;
|
||||
if (typeof map[0] != 'object') {
|
||||
const alternativeMap = {};
|
||||
for (const [nodeId, scriptOffset] of Object.entries<number>(map)) {
|
||||
alternativeMap[nodeId] = { scriptOffset: scriptOffset, inliningId: -1 };
|
||||
public setSources(sourcesJson, mainFunc: Source): void {
|
||||
if (sourcesJson) {
|
||||
for (const [sourceId, source] of Object.entries<Source>(sourcesJson)) {
|
||||
const src = new Source(source.sourceName, source.functionName, source.sourceText,
|
||||
source.sourceId, source.backwardsCompatibility, new Array<SourcePosition>(),
|
||||
source.startPosition, source.endPosition);
|
||||
this.sources[sourceId] = src;
|
||||
}
|
||||
}
|
||||
// This is a fallback if the JSON is incomplete (e.g. due to compiler crash).
|
||||
if (!this.sources[-1]) {
|
||||
this.sources[-1] = mainFunc;
|
||||
}
|
||||
map = alternativeMap;
|
||||
}
|
||||
|
||||
for (const [nodeId, sourcePosition] of Object.entries<SourcePosition>(map)) {
|
||||
if (sourcePosition == undefined) {
|
||||
console.log("Warning: undefined source position ", sourcePosition, " for nodeId ", nodeId);
|
||||
public setNodePositionMap(mapJson): void {
|
||||
if (!mapJson) return;
|
||||
if (typeof mapJson[0] !== "object") {
|
||||
const alternativeMap = new Map<string, SourcePosition>();
|
||||
for (const [nodeId, scriptOffset] of Object.entries<number>(mapJson)) {
|
||||
alternativeMap[nodeId] = new SourcePosition(scriptOffset, -1);
|
||||
}
|
||||
const inliningId = sourcePosition.inliningId;
|
||||
const inlining = this.inlinings[inliningId];
|
||||
if (inlining) {
|
||||
const sourceId = inlining.sourceId;
|
||||
this.sources[sourceId].sourcePositions.push(sourcePosition);
|
||||
mapJson = alternativeMap;
|
||||
}
|
||||
this.nodePositionMap[nodeId] = sourcePosition;
|
||||
const key = sourcePositionToStringKey(sourcePosition);
|
||||
|
||||
for (const [nodeId, sourcePosition] of Object.entries<SourcePosition>(mapJson)) {
|
||||
if (sourcePosition === undefined) {
|
||||
console.warn(`Undefined source position for node id ${nodeId}`);
|
||||
}
|
||||
const inlining = this.inlinings[sourcePosition.inliningId];
|
||||
const sp = new SourcePosition(sourcePosition.scriptOffset, sourcePosition.inliningId);
|
||||
if (inlining) this.sources[inlining.sourceId].sourcePositions.push(sp);
|
||||
this.nodePositionMap[nodeId] = sp;
|
||||
const key = sp.toString();
|
||||
if (!this.positionToNodes.has(key)) {
|
||||
this.positionToNodes.set(key, []);
|
||||
this.positionToNodes.set(key, new Array<string>());
|
||||
}
|
||||
this.positionToNodes.get(key).push(nodeId);
|
||||
}
|
||||
for (const [, source] of Object.entries(this.sources)) {
|
||||
|
||||
for (const [, source] of Object.entries<Source>(this.sources)) {
|
||||
source.sourcePositions = sortUnique(source.sourcePositions,
|
||||
sourcePositionLe, sourcePositionEq);
|
||||
}
|
||||
}
|
||||
|
||||
sourcePositionsToNodeIds(sourcePositions) {
|
||||
const nodeIds = new Set<string>();
|
||||
for (const sp of sourcePositions) {
|
||||
const key = sourcePositionToStringKey(sp);
|
||||
const nodeIdsForPosition = this.positionToNodes.get(key);
|
||||
if (!nodeIdsForPosition) continue;
|
||||
for (const nodeId of nodeIdsForPosition) {
|
||||
nodeIds.add(nodeId);
|
||||
}
|
||||
}
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
nodeIdsToSourcePositions(nodeIds): Array<GenericPosition> {
|
||||
const sourcePositions = new Map();
|
||||
for (const nodeId of nodeIds) {
|
||||
const sp = this.nodePositionMap[nodeId];
|
||||
const key = sourcePositionToStringKey(sp);
|
||||
sourcePositions.set(key, sp);
|
||||
}
|
||||
const sourcePositionArray = [];
|
||||
for (const sp of sourcePositions.values()) {
|
||||
sourcePositionArray.push(sp);
|
||||
}
|
||||
return sourcePositionArray;
|
||||
}
|
||||
|
||||
translateToSourceId(sourceId: number, location?: SourcePosition) {
|
||||
for (const position of this.getInlineStack(location)) {
|
||||
const inlining = this.inlinings[position.inliningId];
|
||||
if (!inlining) continue;
|
||||
if (inlining.sourceId == sourceId) {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
addInliningPositions(sourcePosition: GenericPosition, locations: Array<SourcePosition>) {
|
||||
const inlining = this.inliningsMap.get(sourcePositionToStringKey(sourcePosition));
|
||||
if (!inlining) return;
|
||||
const sourceId = inlining.sourceId;
|
||||
const source = this.sources[sourceId];
|
||||
for (const sp of source.sourcePositions) {
|
||||
locations.push(sp);
|
||||
this.addInliningPositions(sp, locations);
|
||||
}
|
||||
}
|
||||
|
||||
getInliningForPosition(sourcePosition: GenericPosition) {
|
||||
return this.inliningsMap.get(sourcePositionToStringKey(sourcePosition));
|
||||
}
|
||||
|
||||
getSource(sourceId: number) {
|
||||
return this.sources[sourceId];
|
||||
}
|
||||
|
||||
getSourceName(sourceId: number) {
|
||||
const source = this.sources[sourceId];
|
||||
return `${source.sourceName}:${source.functionName}`;
|
||||
}
|
||||
|
||||
sourcePositionFor(sourceId: number, scriptOffset: number) {
|
||||
if (!this.sources[sourceId]) {
|
||||
return null;
|
||||
}
|
||||
const list = this.sources[sourceId].sourcePositions;
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const sourcePosition = list[i];
|
||||
const position = sourcePosition.scriptOffset;
|
||||
const nextPosition = list[Math.min(i + 1, list.length - 1)].scriptOffset;
|
||||
if ((position <= scriptOffset && scriptOffset < nextPosition)) {
|
||||
return sourcePosition;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
sourcePositionsInRange(sourceId: number, start: number, end: number) {
|
||||
if (!this.sources[sourceId]) return [];
|
||||
const res = [];
|
||||
const list = this.sources[sourceId].sourcePositions;
|
||||
for (const sourcePosition of list) {
|
||||
if (start <= sourcePosition.scriptOffset && sourcePosition.scriptOffset < end) {
|
||||
res.push(sourcePosition);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
getInlineStack(sourcePosition?: SourcePosition) {
|
||||
if (!sourcePosition) return [];
|
||||
|
||||
const inliningStack = [];
|
||||
let cur = sourcePosition;
|
||||
while (cur && cur.inliningId != -1) {
|
||||
inliningStack.push(cur);
|
||||
const inlining = this.inlinings[cur.inliningId];
|
||||
if (!inlining) {
|
||||
break;
|
||||
}
|
||||
cur = inlining.inliningPosition;
|
||||
}
|
||||
if (cur && cur.inliningId == -1) {
|
||||
inliningStack.push(cur);
|
||||
}
|
||||
return inliningStack;
|
||||
}
|
||||
|
||||
private recordOrigins(graphPhase: GraphPhase): void {
|
||||
if (graphPhase.type !== PhaseType.Graph) return;
|
||||
for (const node of graphPhase.data.nodes) {
|
||||
graphPhase.highestNodeId = Math.max(graphPhase.highestNodeId, node.id);
|
||||
const origin = node.nodeLabel.origin;
|
||||
const isBytecode = origin instanceof BytecodeOrigin;
|
||||
if (isBytecode) {
|
||||
const position = new BytecodePosition(origin.bytecodePosition);
|
||||
this.nodePositionMap[node.id] = position;
|
||||
const key = position.toString();
|
||||
if (!this.positionToNodes.has(key)) {
|
||||
this.positionToNodes.set(key, []);
|
||||
}
|
||||
const nodes = this.positionToNodes.get(key);
|
||||
const identifier = node.identifier();
|
||||
if (!nodes.includes(identifier)) nodes.push(identifier);
|
||||
}
|
||||
(a, b) => a.lessOrEquals(b),
|
||||
(a, b) => a.equals(b));
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,41 +194,144 @@ export class SourceResolver {
|
||||
}
|
||||
}
|
||||
|
||||
repairPhaseId(anyPhaseId) {
|
||||
public sourcePositionsToNodeIds(sourcePositions: Array<GenericPosition>): Set<string> {
|
||||
const nodeIds = new Set<string>();
|
||||
for (const sp of sourcePositions) {
|
||||
const nodeIdsForPosition = this.positionToNodes.get(sp.toString());
|
||||
if (!nodeIdsForPosition) continue;
|
||||
for (const nodeId of nodeIdsForPosition) {
|
||||
nodeIds.add(nodeId);
|
||||
}
|
||||
}
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
public nodeIdsToSourcePositions(nodeIds: Array<string>): Array<GenericPosition> {
|
||||
const sourcePositions = new Map<string, GenericPosition>();
|
||||
for (const nodeId of nodeIds) {
|
||||
const position = this.nodePositionMap[nodeId];
|
||||
if (!position) continue;
|
||||
sourcePositions.set(position.toString(), position);
|
||||
}
|
||||
const sourcePositionArray = new Array<GenericPosition>();
|
||||
for (const sourcePosition of sourcePositions.values()) {
|
||||
sourcePositionArray.push(sourcePosition);
|
||||
}
|
||||
return sourcePositionArray;
|
||||
}
|
||||
|
||||
public translateToSourceId(sourceId: number, location?: SourcePosition): SourcePosition {
|
||||
for (const position of this.getInlineStack(location)) {
|
||||
const inlining = this.inlinings[position.inliningId];
|
||||
if (!inlining) continue;
|
||||
if (inlining.sourceId == sourceId) {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public addInliningPositions(sourcePosition: GenericPosition, locations: Array<SourcePosition>):
|
||||
void {
|
||||
const inlining = this.inliningsMap.get(sourcePosition.toString());
|
||||
if (!inlining) return;
|
||||
const source = this.sources[inlining.sourceId];
|
||||
for (const sp of source.sourcePositions) {
|
||||
locations.push(sp);
|
||||
this.addInliningPositions(sp, locations);
|
||||
}
|
||||
}
|
||||
|
||||
public getInliningForPosition(sourcePosition: GenericPosition): InliningPosition {
|
||||
return this.inliningsMap.get(sourcePosition.toString());
|
||||
}
|
||||
|
||||
public getSource(sourceId: number): Source {
|
||||
return this.sources[sourceId];
|
||||
}
|
||||
|
||||
public addAnyPositionToLine(lineNumber: number | string, sourcePosition: GenericPosition): void {
|
||||
const lineNumberString = anyToString(lineNumber);
|
||||
if (!this.linePositionMap.has(lineNumberString)) {
|
||||
this.linePositionMap.set(lineNumberString, new Array<GenericPosition>());
|
||||
}
|
||||
const storedPositions = this.linePositionMap.get(lineNumberString);
|
||||
if (!storedPositions.includes(sourcePosition)) storedPositions.push(sourcePosition);
|
||||
}
|
||||
|
||||
public repairPhaseId(anyPhaseId: number): number {
|
||||
return Math.max(0, Math.min(anyPhaseId | 0, this.phases.length - 1));
|
||||
}
|
||||
|
||||
getPhase(phaseId: number) {
|
||||
public getPhase(phaseId: number): GenericPhase {
|
||||
return this.phases[phaseId];
|
||||
}
|
||||
|
||||
getPhaseIdByName(phaseName: string) {
|
||||
public getPhaseIdByName(phaseName: string): number {
|
||||
return this.phaseNames.get(phaseName);
|
||||
}
|
||||
|
||||
forEachPhase(f: (value: GenericPhase, index: number, array: Array<GenericPhase>) => void) {
|
||||
this.phases.forEach(f);
|
||||
public lineToSourcePositions(lineNumber: number | string): Array<GenericPosition> {
|
||||
return this.linePositionMap.get(anyToString(lineNumber)) ?? new Array<GenericPosition>();
|
||||
}
|
||||
|
||||
addAnyPositionToLine(lineNumber: number | string, sourcePosition: GenericPosition) {
|
||||
const lineNumberString = anyToString(lineNumber);
|
||||
if (!this.linePositionMap.has(lineNumberString)) {
|
||||
this.linePositionMap.set(lineNumberString, []);
|
||||
}
|
||||
const A = this.linePositionMap.get(lineNumberString);
|
||||
if (!A.includes(sourcePosition)) A.push(sourcePosition);
|
||||
public getSourceName(sourceId: number): string {
|
||||
const source = this.sources[sourceId];
|
||||
return `${source.sourceName}:${source.functionName}`;
|
||||
}
|
||||
|
||||
setSourceLineToBytecodePosition(sourceLineToBytecodePosition: Array<number> | undefined) {
|
||||
if (!sourceLineToBytecodePosition) return;
|
||||
sourceLineToBytecodePosition.forEach((pos, i) => {
|
||||
this.addAnyPositionToLine(i, new BytecodePosition(pos));
|
||||
public sourcePositionsInRange(sourceId: number, start: number, end: number):
|
||||
Array<SourcePosition> {
|
||||
const inRange = Array<SourcePosition>();
|
||||
if (!this.sources[sourceId]) return inRange;
|
||||
const list = this.sources[sourceId].sourcePositions;
|
||||
for (const sourcePosition of list) {
|
||||
if (start <= sourcePosition.scriptOffset && sourcePosition.scriptOffset < end) {
|
||||
inRange.push(sourcePosition);
|
||||
}
|
||||
}
|
||||
return inRange;
|
||||
}
|
||||
|
||||
public setSourceLineToBytecodePosition(sourceLineToBytecodePositionJson): void {
|
||||
if (!sourceLineToBytecodePositionJson) return;
|
||||
sourceLineToBytecodePositionJson.forEach((position, idx) => {
|
||||
this.addAnyPositionToLine(idx, new BytecodePosition(position));
|
||||
});
|
||||
}
|
||||
|
||||
lineToSourcePositions(lineNumber: number | string) {
|
||||
const positions = this.linePositionMap.get(anyToString(lineNumber));
|
||||
if (positions === undefined) return [];
|
||||
return positions;
|
||||
private getInlineStack(sourcePosition?: SourcePosition): Array<SourcePosition> {
|
||||
const inliningStack = Array<SourcePosition>();
|
||||
if (!sourcePosition) return inliningStack;
|
||||
let cur = sourcePosition;
|
||||
while (cur && cur.inliningId != -1) {
|
||||
inliningStack.push(cur);
|
||||
const inlining = this.inlinings[cur.inliningId];
|
||||
if (!inlining) break;
|
||||
cur = inlining.inliningPosition;
|
||||
}
|
||||
if (cur && cur.inliningId == -1) {
|
||||
inliningStack.push(cur);
|
||||
}
|
||||
return inliningStack;
|
||||
}
|
||||
|
||||
private recordOrigins(graphPhase: GraphPhase): void {
|
||||
if (graphPhase.type !== PhaseType.Graph) return;
|
||||
for (const node of graphPhase.data.nodes) {
|
||||
graphPhase.highestNodeId = Math.max(graphPhase.highestNodeId, node.id);
|
||||
const origin = node.nodeLabel.origin;
|
||||
if (origin instanceof BytecodeOrigin) {
|
||||
const position = new BytecodePosition(origin.bytecodePosition);
|
||||
this.nodePositionMap[node.id] = position;
|
||||
const key = position.toString();
|
||||
if (!this.positionToNodes.has(key)) {
|
||||
this.positionToNodes.set(key, new Array<string>());
|
||||
}
|
||||
const nodes = this.positionToNodes.get(key);
|
||||
const identifier = node.identifier();
|
||||
if (!nodes.includes(identifier)) nodes.push(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,10 @@ declare global {
|
||||
const PR: PR;
|
||||
}
|
||||
|
||||
import { SourceResolver, sourcePositionToStringKey } from "../source-resolver";
|
||||
import { GenericPosition, SourceResolver } from "../source-resolver";
|
||||
import { SelectionBroker } from "../selection/selection-broker";
|
||||
import { View } from "./view";
|
||||
import { MySelection } from "../selection/selection";
|
||||
import { SelectionMap } from "../selection/selection";
|
||||
import { ViewElements } from "../common/view-elements";
|
||||
import { SelectionHandler } from "../selection/selection-handler";
|
||||
|
||||
@ -32,7 +32,7 @@ export class CodeView extends View {
|
||||
sourcePositionToHtmlElements: Map<string, Array<HTMLElement>>;
|
||||
showAdditionalInliningPosition: boolean;
|
||||
selectionHandler: SelectionHandler;
|
||||
selection: MySelection;
|
||||
selection: SelectionMap;
|
||||
|
||||
createViewElement() {
|
||||
const sourceContainer = document.createElement("div");
|
||||
@ -81,14 +81,14 @@ export class CodeView extends View {
|
||||
view.updateSelection();
|
||||
},
|
||||
};
|
||||
view.selection = new MySelection(sourcePositionToStringKey);
|
||||
view.selection = new SelectionMap((sp: GenericPosition) => sp.toString());
|
||||
broker.addSourcePositionHandler(selectionHandler);
|
||||
this.selectionHandler = selectionHandler;
|
||||
this.initializeCode();
|
||||
}
|
||||
|
||||
addHtmlElementToSourcePosition(sourcePosition, element) {
|
||||
const key = sourcePositionToStringKey(sourcePosition);
|
||||
const key = sourcePosition.toString();
|
||||
if (!this.sourcePositionToHtmlElements.has(key)) {
|
||||
this.sourcePositionToHtmlElements.set(key, []);
|
||||
}
|
||||
@ -96,8 +96,7 @@ export class CodeView extends View {
|
||||
}
|
||||
|
||||
getHtmlElementForSourcePosition(sourcePosition) {
|
||||
const key = sourcePositionToStringKey(sourcePosition);
|
||||
return this.sourcePositionToHtmlElements.get(key);
|
||||
return this.sourcePositionToHtmlElements.get(sourcePosition.toString());
|
||||
}
|
||||
|
||||
updateSelection(scrollIntoView: boolean = false): void {
|
||||
@ -248,7 +247,7 @@ export class CodeView extends View {
|
||||
offset += splitLength;
|
||||
const replacementNode = textnode.splitText(splitLength);
|
||||
const span = document.createElement('span');
|
||||
span.setAttribute("scriptOffset", sourcePosition.scriptOffset);
|
||||
span.setAttribute("scriptOffset", sourcePosition.scriptOffset.toString());
|
||||
span.classList.add("source-position");
|
||||
const marker = document.createElement('span');
|
||||
marker.classList.add("marker");
|
||||
|
@ -5,7 +5,7 @@
|
||||
import { PROF_COLS, UNICODE_BLOCK } from "../common/constants";
|
||||
import { SelectionBroker } from "../selection/selection-broker";
|
||||
import { TextView } from "./text-view";
|
||||
import { MySelection } from "../selection/selection";
|
||||
import { SelectionMap } from "../selection/selection";
|
||||
import { anyToString, interpolate } from "../common/util";
|
||||
import { InstructionSelectionHandler } from "../selection/selection-handler";
|
||||
import { TurbolizerInstructionStartInfo } from "../phases/instructions-phase";
|
||||
@ -25,7 +25,7 @@ export class DisassemblyView extends TextView {
|
||||
maxEventCounts: any;
|
||||
posLines: Array<any>;
|
||||
instructionSelectionHandler: InstructionSelectionHandler;
|
||||
offsetSelection: MySelection;
|
||||
offsetSelection: SelectionMap;
|
||||
showInstructionAddressHandler: () => void;
|
||||
showInstructionBinaryHandler: () => void;
|
||||
highlightGapInstructionsHandler: () => void;
|
||||
@ -197,7 +197,7 @@ export class DisassemblyView extends TextView {
|
||||
};
|
||||
view.divNode.addEventListener('click', linkHandlerBlock);
|
||||
|
||||
this.offsetSelection = new MySelection(anyToString);
|
||||
this.offsetSelection = new SelectionMap(anyToString);
|
||||
const instructionSelectionHandler = {
|
||||
clear: function () {
|
||||
view.offsetSelection.clear();
|
||||
|
@ -6,20 +6,20 @@ import * as C from "../common/constants";
|
||||
import * as d3 from "d3";
|
||||
import { partial, storageGetItem, storageSetItem } from "../common/util";
|
||||
import { PhaseView } from "./view";
|
||||
import { MySelection } from "../selection/selection";
|
||||
import { SelectionMap } from "../selection/selection";
|
||||
import { ClearableHandler, NodeSelectionHandler } from "../selection/selection-handler";
|
||||
import { Graph } from "../graph";
|
||||
import { SelectionBroker } from "../selection/selection-broker";
|
||||
import { GraphNode } from "../phases/graph-phase/graph-node";
|
||||
import { GraphEdge } from "../phases/graph-phase/graph-edge";
|
||||
import { GraphLayout } from "../graph-layout";
|
||||
import { GraphPhase, GraphStateType } from "../phases/graph-phase";
|
||||
import { GraphPhase, GraphStateType } from "../phases/graph-phase/graph-phase";
|
||||
import { BytecodePosition } from "../position";
|
||||
import { BytecodeOrigin } from "../origin";
|
||||
|
||||
interface GraphState {
|
||||
showTypes: boolean;
|
||||
selection: MySelection;
|
||||
selection: SelectionMap;
|
||||
mouseDownNode: any;
|
||||
justDragged: boolean;
|
||||
justScaleTransGraph: boolean;
|
||||
@ -131,7 +131,7 @@ export class GraphView extends PhaseView {
|
||||
}
|
||||
};
|
||||
|
||||
view.state.selection = new MySelection(n => n.identifier(),
|
||||
view.state.selection = new SelectionMap(n => n.identifier(),
|
||||
n => n.nodeLabel?.origin?.identifier());
|
||||
|
||||
const defs = svg.append('svg:defs');
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import { PhaseView } from "./view";
|
||||
import { anyToString, isIterable } from "../common/util";
|
||||
import { MySelection } from "../selection/selection";
|
||||
import { SelectionMap } from "../selection/selection";
|
||||
import { SourceResolver } from "../source-resolver";
|
||||
import { SelectionBroker } from "../selection/selection-broker";
|
||||
import { NodeSelectionHandler, BlockSelectionHandler, RegisterAllocationSelectionHandler } from "../selection/selection-handler";
|
||||
@ -14,9 +14,9 @@ export abstract class TextView extends PhaseView {
|
||||
selectionHandler: NodeSelectionHandler;
|
||||
blockSelectionHandler: BlockSelectionHandler;
|
||||
registerAllocationSelectionHandler: RegisterAllocationSelectionHandler;
|
||||
selection: MySelection;
|
||||
blockSelection: MySelection;
|
||||
registerAllocationSelection: MySelection;
|
||||
selection: SelectionMap;
|
||||
blockSelection: SelectionMap;
|
||||
registerAllocationSelection: SelectionMap;
|
||||
textListNode: HTMLUListElement;
|
||||
instructionIdToHtmlElementsMap: Map<string, Array<HTMLElement>>;
|
||||
nodeIdToHtmlElementsMap: Map<string, Array<HTMLElement>>;
|
||||
@ -37,8 +37,8 @@ export abstract class TextView extends PhaseView {
|
||||
view.blockIdToHtmlElementsMap = new Map();
|
||||
view.blockIdToNodeIds = new Map();
|
||||
view.nodeIdToBlockId = [];
|
||||
view.selection = new MySelection(anyToString);
|
||||
view.blockSelection = new MySelection(anyToString);
|
||||
view.selection = new SelectionMap(anyToString);
|
||||
view.blockSelection = new SelectionMap(anyToString);
|
||||
view.broker = broker;
|
||||
view.sourceResolver = broker.sourceResolver;
|
||||
const selectionHandler = {
|
||||
@ -95,7 +95,7 @@ export abstract class TextView extends PhaseView {
|
||||
this.blockSelectionHandler = blockSelectionHandler;
|
||||
broker.addBlockHandler(blockSelectionHandler);
|
||||
|
||||
view.registerAllocationSelection = new MySelection(anyToString);
|
||||
view.registerAllocationSelection = new SelectionMap(anyToString);
|
||||
const registerAllocationSelectionHandler = {
|
||||
clear: function () {
|
||||
view.registerAllocationSelection.clear();
|
||||
|
@ -17,6 +17,7 @@
|
||||
"src/common/util.ts",
|
||||
"src/common/constants.ts",
|
||||
"src/common/view-elements.ts",
|
||||
"src/phases/graph-phase/graph-phase.ts",
|
||||
"src/phases/graph-phase/graph-node.ts",
|
||||
"src/phases/graph-phase/graph-edge.ts",
|
||||
"src/phases/turboshaft-graph-phase/turboshaft-graph-phase.ts",
|
||||
@ -24,7 +25,6 @@
|
||||
"src/phases/turboshaft-graph-phase/turboshaft-graph-node.ts",
|
||||
"src/phases/turboshaft-graph-phase/turboshaft-graph-edge.ts",
|
||||
"src/phases/disassembly-phase.ts",
|
||||
"src/phases/graph-phase.ts",
|
||||
"src/phases/instructions-phase.ts",
|
||||
"src/phases/phase.ts",
|
||||
"src/phases/schedule-phase.ts",
|
||||
|
Loading…
Reference in New Issue
Block a user