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 5document.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