turbo-visualizer.ts 6.02 KB
Newer Older
1
// Copyright 2017 the V8 project authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7 8 9 10 11 12
import { SourceResolver } from "../src/source-resolver";
import { SelectionBroker } from "../src/selection-broker";
import { DisassemblyView } from "../src/disassembly-view";
import { GraphMultiView } from "../src/graphmultiview";
import { CodeMode, CodeView } from "../src/code-view";
import { Tabs } from "../src/tabs";
import { Resizer } from "../src/resizer";
import * as C from "../src/constants";
13
import { InfoView } from "./info-view";
14

15
window.onload = function () {
16 17 18 19 20
  let multiview: GraphMultiView = null;
  let disassemblyView: DisassemblyView = null;
  let sourceViews: Array<CodeView> = [];
  let selectionBroker: SelectionBroker = null;
  let sourceResolver: SourceResolver = null;
21
  const resizer = new Resizer(panesUpdatedCallback, 75, 75);
22 23 24 25 26 27 28 29 30 31
  const sourceTabsContainer = document.getElementById(C.SOURCE_PANE_ID);
  const sourceTabs = new Tabs(sourceTabsContainer);
  sourceTabs.addTab("&#x2b;").classList.add("last-tab", "persistent-tab");
  const disassemblyTabsContainer = document.getElementById(C.GENERATED_PANE_ID);
  const disassemblyTabs = new Tabs(disassemblyTabsContainer);
  disassemblyTabs.addTab("&#x2b;").classList.add("last-tab", "persistent-tab");
  const [infoTab, infoContainer] = sourceTabs.addTabAndContent("Info");
  infoTab.classList.add("persistent-tab");
  infoContainer.classList.add("viewpane", "scrollable");
  const infoView = new InfoView(infoContainer);
32
  infoView.show();
33
  sourceTabs.activateTab(infoTab);
34 35

  function panesUpdatedCallback() {
36
    if (multiview) multiview.onresize();
37 38
  }

39
  function loadFile(txtRes: string) {
40 41
    sourceTabs.clearTabsAndContent();
    disassemblyTabs.clearTabsAndContent();
42 43 44 45 46 47
    // If the JSON isn't properly terminated, assume compiler crashed and
    // add best-guess empty termination
    if (txtRes[txtRes.length - 2] == ',') {
      txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}';
    }
    try {
48
      sourceViews.forEach(sv => sv.hide());
49 50
      if (multiview) multiview.hide();
      multiview = null;
51 52
      document.getElementById("ranges").innerHTML = '';
      document.getElementById('ranges').style.visibility = "hidden";
53
      document.getElementById('show-hide-ranges').style.visibility = "hidden";
54 55 56 57 58 59 60
      if (disassemblyView) disassemblyView.hide();
      sourceViews = [];
      sourceResolver = new SourceResolver();
      selectionBroker = new SelectionBroker(sourceResolver);

      const jsonObj = JSON.parse(txtRes);

61
      let fnc = null;
62
      // Backwards compatibility.
63
      if (typeof jsonObj.function == 'string') {
64 65 66 67 68
        fnc = {
          functionName: fnc,
          sourceId: -1,
          startPosition: jsonObj.sourcePosition,
          endPosition: jsonObj.sourcePosition + jsonObj.source.length,
69 70
          sourceText: jsonObj.source,
          backwardsCompatibility: true
71
        };
72
      } else {
73
        fnc = Object.assign(jsonObj.function, { backwardsCompatibility: false });
74
      }
75

76
      sourceResolver.setInlinings(jsonObj.inlinings);
77
      sourceResolver.setSourceLineToBytecodePosition(jsonObj.sourceLineToBytecodePosition);
78
      sourceResolver.setSources(jsonObj.sources, fnc);
79 80
      sourceResolver.setNodePositionMap(jsonObj.nodePositions);
      sourceResolver.parsePhases(jsonObj.phases);
81

82
      const [sourceTab, sourceContainer] = sourceTabs.addTabAndContent("Source");
83 84
      sourceContainer.classList.add("viewpane", "scrollable");
      sourceTabs.activateTab(sourceTab);
85
      const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, fnc, CodeMode.MAIN_SOURCE);
86
      sourceView.show();
87
      sourceViews.push(sourceView);
88

89
      sourceResolver.forEachSource(source => {
90
        const sourceView = new CodeView(sourceContainer, selectionBroker, sourceResolver, source, CodeMode.INLINED_SOURCE);
91
        sourceView.show();
92 93 94
        sourceViews.push(sourceView);
      });

95
      const [disassemblyTab, disassemblyContainer] = disassemblyTabs.addTabAndContent("Disassembly");
96 97 98
      disassemblyContainer.classList.add("viewpane", "scrollable");
      disassemblyTabs.activateTab(disassemblyTab);
      disassemblyView = new DisassemblyView(disassemblyContainer, selectionBroker);
99 100 101
      disassemblyView.initializeCode(fnc.sourceText);
      if (sourceResolver.disassemblyPhase) {
        disassemblyView.initializePerfProfile(jsonObj.eventCounts);
102 103
        disassemblyView.showContent(sourceResolver.disassemblyPhase.data);
        disassemblyView.show();
104 105
      }

106
      multiview = new GraphMultiView(C.INTERMEDIATE_PANE_ID, selectionBroker, sourceResolver);
107
      multiview.show();
108 109
    } catch (err) {
      if (window.confirm("Error: Exception during load of TurboFan JSON file:\n" +
110
        "error: " + err.message + "\nDo you want to clear session storage?")) {
111 112 113 114 115 116 117 118 119 120
        window.sessionStorage.clear();
      }
      return;
    }
  }

  function initializeUploadHandlers() {
    // The <input> form #upload-helper with type file can't be a picture.
    // We hence keep it hidden, and forward the click from the picture
    // button #upload.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    document.getElementById("upload").addEventListener("click", e => {
      document.getElementById("upload-helper").click();
      e.stopPropagation();
    });
    document.getElementById("upload-helper").addEventListener("change",
      function (this: HTMLInputElement) {
        const uploadFile = this.files && this.files[0];
        if (uploadFile) {
          const filereader = new FileReader();
          filereader.onload = () => {
            const txtRes = filereader.result;
            if (typeof txtRes == 'string') {
              loadFile(txtRes);
            }
          };
          filereader.readAsText(uploadFile);
        }
      }
    );
    window.addEventListener("keydown", (e: KeyboardEvent) => {
      if (e.keyCode == 76 && e.ctrlKey) { // CTRL + L
        document.getElementById("upload-helper").click();
        e.stopPropagation();
        e.preventDefault();
145
      }
146 147 148
    });
  }

149
  initializeUploadHandlers();
150
  resizer.updatePanes();
151
};