Home | History | Annotate | Download | only in turbolizer
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 document.onload = (function(d3){
      6   "use strict";
      7   var jsonObj;
      8   var sourceExpandClassList = document.getElementById(SOURCE_EXPAND_ID).classList;
      9   var sourceCollapseClassList = document.getElementById(SOURCE_COLLAPSE_ID).classList;
     10   var sourceExpanded = sourceCollapseClassList.contains(COLLAPSE_PANE_BUTTON_VISIBLE);
     11   var disassemblyExpandClassList = document.getElementById(DISASSEMBLY_EXPAND_ID).classList;
     12   var disassemblyCollapseClassList = document.getElementById(DISASSEMBLY_COLLAPSE_ID).classList;
     13   var disassemblyExpanded = disassemblyCollapseClassList.contains(COLLAPSE_PANE_BUTTON_VISIBLE);
     14   var svg  = null;
     15   var graph = null;
     16   var schedule = null;
     17   var empty = null;
     18   var currentPhaseView = null;
     19   var disassemblyView = null;
     20   var sourceView = null;
     21   var selectionBroker = null;
     22 
     23   function updatePanes() {
     24     if (sourceExpanded) {
     25       if (disassemblyExpanded) {
     26         d3.select("#" + SOURCE_PANE_ID).style(WIDTH, "30%");
     27         d3.select("#" + INTERMEDIATE_PANE_ID).style(WIDTH, "40%");
     28         d3.select("#" + GENERATED_PANE_ID).style(WIDTH, "30%");
     29       } else {
     30         d3.select("#" + SOURCE_PANE_ID).style(WIDTH, "50%");
     31         d3.select("#" + INTERMEDIATE_PANE_ID).style(WIDTH, "50%");
     32         d3.select("#" + GENERATED_PANE_ID).style(WIDTH, "0%");
     33       }
     34     } else {
     35       if (disassemblyExpanded) {
     36         d3.select("#" + SOURCE_PANE_ID).style(WIDTH, "0%");
     37         d3.select("#" + INTERMEDIATE_PANE_ID).style(WIDTH, "50%");
     38         d3.select("#" + GENERATED_PANE_ID).style(WIDTH, "50%");
     39       } else {
     40         d3.select("#" + SOURCE_PANE_ID).style(WIDTH, "0%");
     41         d3.select("#" + INTERMEDIATE_PANE_ID).style(WIDTH, "100%");
     42         d3.select("#" + GENERATED_PANE_ID).style(WIDTH, "0%");
     43       }
     44     }
     45   }
     46 
     47   function getLastExpandedState(type, default_state) {
     48     var state = window.sessionStorage.getItem("expandedState-"+type);
     49     if (state === null) return default_state;
     50     return state === 'true';
     51   }
     52 
     53   function setLastExpandedState(type, state) {
     54     window.sessionStorage.setItem("expandedState-"+type, state);
     55   }
     56 
     57   function toggleSourceExpanded() {
     58     setSourceExpanded(!sourceExpanded);
     59   }
     60 
     61   function setSourceExpanded(newState) {
     62     sourceExpanded = newState;
     63     setLastExpandedState("source", newState);
     64     updatePanes();
     65     if (newState) {
     66       sourceCollapseClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE);
     67       sourceCollapseClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE);
     68       sourceExpandClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE);
     69       sourceExpandClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE);
     70     } else {
     71       sourceCollapseClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE);
     72       sourceCollapseClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE);
     73       sourceExpandClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE);
     74       sourceExpandClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE);
     75     }
     76   }
     77 
     78   function toggleDisassemblyExpanded() {
     79     setDisassemblyExpanded(!disassemblyExpanded);
     80   }
     81 
     82   function setDisassemblyExpanded(newState) {
     83     disassemblyExpanded = newState;
     84     setLastExpandedState("disassembly", newState);
     85     updatePanes();
     86     if (newState) {
     87       disassemblyCollapseClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE);
     88       disassemblyCollapseClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE);
     89       disassemblyExpandClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE);
     90       disassemblyExpandClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE);
     91     } else {
     92       disassemblyCollapseClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE);
     93       disassemblyCollapseClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE);
     94       disassemblyExpandClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE);
     95       disassemblyExpandClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE);
     96     }
     97   }
     98 
     99   function hideCurrentPhase() {
    100     var rememberedSelection = null;
    101     if (currentPhaseView != null) {
    102       rememberedSelection = currentPhaseView.detachSelection();
    103       currentPhaseView.hide();
    104       currentPhaseView = null;
    105     }
    106     return rememberedSelection;
    107   }
    108 
    109   function displayPhaseView(view, data) {
    110     var rememberedSelection = hideCurrentPhase();
    111     view.show(data, rememberedSelection);
    112     d3.select("#middle").classed("scrollable", view.isScrollable());
    113     currentPhaseView = view;
    114   }
    115 
    116   function displayPhase(phase) {
    117     if (phase.type == 'graph') {
    118       displayPhaseView(graph, phase.data);
    119     } else if (phase.type == 'schedule') {
    120       displayPhaseView(schedule, phase.data);
    121     } else {
    122       displayPhaseView(empty, null);
    123     }
    124   }
    125 
    126   function fitPanesToParents() {
    127     d3.select("#left").classed("scrollable", false)
    128     d3.select("#right").classed("scrollable", false);
    129 
    130     graph.fitGraphViewToWindow();
    131     disassemblyView.resizeToParent();
    132     sourceView.resizeToParent();
    133 
    134     d3.select("#left").classed("scrollable", true);
    135     d3.select("#right").classed("scrollable", true);
    136   }
    137 
    138   selectionBroker = new SelectionBroker();
    139 
    140   function initializeHandlers(g) {
    141     d3.select("#source-collapse").on("click", function(){
    142       toggleSourceExpanded(true);
    143       setTimeout(function(){
    144         g.fitGraphViewToWindow();
    145       }, 300);
    146     });
    147     d3.select("#disassembly-collapse").on("click", function(){
    148       toggleDisassemblyExpanded();
    149       setTimeout(function(){
    150         g.fitGraphViewToWindow();
    151       }, 300);
    152     });
    153     window.onresize = function(){
    154       fitPanesToParents();
    155     };
    156     d3.select("#hidden-file-upload").on("change", function() {
    157       if (window.File && window.FileReader && window.FileList) {
    158         var uploadFile = this.files[0];
    159         var filereader = new window.FileReader();
    160         var consts = Node.consts;
    161         filereader.onload = function(){
    162           var txtRes = filereader.result;
    163           // If the JSON isn't properly terminated, assume compiler crashed and
    164           // add best-guess empty termination
    165           if (txtRes[txtRes.length-2] == ',') {
    166             txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}';
    167           }
    168           try{
    169             jsonObj = JSON.parse(txtRes);
    170 
    171             hideCurrentPhase();
    172 
    173             selectionBroker.setNodePositionMap(jsonObj.nodePositions);
    174 
    175             sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition);
    176             disassemblyView.initializeCode(jsonObj.source);
    177 
    178             var selectMenu = document.getElementById('display-selector');
    179             var disassemblyPhase = null;
    180             selectMenu.innerHTML = '';
    181             for (var i = 0; i < jsonObj.phases.length; ++i) {
    182               var optionElement = document.createElement("option");
    183               optionElement.text = jsonObj.phases[i].name;
    184               if (optionElement.text == 'disassembly') {
    185                 disassemblyPhase = jsonObj.phases[i];
    186               } else {
    187                 selectMenu.add(optionElement, null);
    188               }
    189             }
    190 
    191             disassemblyView.initializePerfProfile(jsonObj.eventCounts);
    192             disassemblyView.show(disassemblyPhase.data, null);
    193 
    194             var initialPhaseIndex = +window.sessionStorage.getItem("lastSelectedPhase");
    195             if (!(initialPhaseIndex in jsonObj.phases)) {
    196               initialPhaseIndex = 0;
    197             }
    198 
    199             // We wish to show the remembered phase {lastSelectedPhase}, but
    200             // this will crash if the first view we switch to is a
    201             // ScheduleView. So we first switch to the first phase, which
    202             // should never be a ScheduleView.
    203             displayPhase(jsonObj.phases[0]);
    204             displayPhase(jsonObj.phases[initialPhaseIndex]);
    205             selectMenu.selectedIndex = initialPhaseIndex;
    206 
    207             selectMenu.onchange = function(item) {
    208               window.sessionStorage.setItem("lastSelectedPhase", selectMenu.selectedIndex);
    209               displayPhase(jsonObj.phases[selectMenu.selectedIndex]);
    210             }
    211 
    212             fitPanesToParents();
    213 
    214             d3.select("#search-input").attr("value", window.sessionStorage.getItem("lastSearch") || "");
    215 
    216           }
    217           catch(err) {
    218             window.console.log("caught exception, clearing session storage just in case");
    219             window.sessionStorage.clear(); // just in case
    220             window.console.log("showing error");
    221             window.alert("Invalid TurboFan JSON file\n" +
    222                          "error: " + err.message);
    223             return;
    224           }
    225         };
    226         filereader.readAsText(uploadFile);
    227       } else {
    228         alert("Can't load graph");
    229       }
    230     });
    231   }
    232 
    233   sourceView = new CodeView(SOURCE_PANE_ID, PR, "", 0, selectionBroker);
    234   disassemblyView = new DisassemblyView(DISASSEMBLY_PANE_ID, selectionBroker);
    235   graph = new GraphView(d3, GRAPH_PANE_ID, [], [], selectionBroker);
    236   schedule = new ScheduleView(SCHEDULE_PANE_ID, selectionBroker);
    237   empty = new EmptyView(EMPTY_PANE_ID, selectionBroker);
    238 
    239   initializeHandlers(graph);
    240 
    241   setSourceExpanded(getLastExpandedState("source", true));
    242   setDisassemblyExpanded(getLastExpandedState("disassembly", false));
    243 
    244   displayPhaseView(empty, null);
    245   fitPanesToParents();
    246 })(window.d3);
    247