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 toggleSourceExpanded() { 48 setSourceExpanded(!sourceExpanded); 49 } 50 51 function setSourceExpanded(newState) { 52 sourceExpanded = newState; 53 updatePanes(); 54 if (newState) { 55 sourceCollapseClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE); 56 sourceCollapseClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE); 57 sourceExpandClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE); 58 sourceExpandClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE); 59 } else { 60 sourceCollapseClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE); 61 sourceCollapseClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE); 62 sourceExpandClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE); 63 sourceExpandClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE); 64 } 65 } 66 67 function toggleDisassemblyExpanded() { 68 setDisassemblyExpanded(!disassemblyExpanded); 69 } 70 71 function setDisassemblyExpanded(newState) { 72 disassemblyExpanded = newState; 73 updatePanes(); 74 if (newState) { 75 disassemblyCollapseClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE); 76 disassemblyCollapseClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE); 77 disassemblyExpandClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE); 78 disassemblyExpandClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE); 79 } else { 80 disassemblyCollapseClassList.add(COLLAPSE_PANE_BUTTON_INVISIBLE); 81 disassemblyCollapseClassList.remove(COLLAPSE_PANE_BUTTON_VISIBLE); 82 disassemblyExpandClassList.add(COLLAPSE_PANE_BUTTON_VISIBLE); 83 disassemblyExpandClassList.remove(COLLAPSE_PANE_BUTTON_INVISIBLE); 84 } 85 } 86 87 function hideCurrentPhase() { 88 var rememberedSelection = null; 89 if (currentPhaseView != null) { 90 rememberedSelection = currentPhaseView.detachSelection(); 91 currentPhaseView.hide(); 92 currentPhaseView = null; 93 } 94 return rememberedSelection; 95 } 96 97 function displayPhaseView(view, data) { 98 var rememberedSelection = hideCurrentPhase(); 99 view.show(data, rememberedSelection); 100 d3.select("#middle").classed("scrollable", view.isScrollable()); 101 currentPhaseView = view; 102 } 103 104 function displayPhase(phase) { 105 if (phase.type == 'graph') { 106 displayPhaseView(graph, phase.data); 107 } else if (phase.type == 'schedule') { 108 displayPhaseView(schedule, phase.data); 109 } else { 110 displayPhaseView(empty, null); 111 } 112 } 113 114 function fitPanesToParents() { 115 d3.select("#left").classed("scrollable", false) 116 d3.select("#right").classed("scrollable", false); 117 118 graph.fitGraphViewToWindow(); 119 disassemblyView.resizeToParent(); 120 sourceView.resizeToParent(); 121 122 d3.select("#left").classed("scrollable", true); 123 d3.select("#right").classed("scrollable", true); 124 } 125 126 selectionBroker = new SelectionBroker(); 127 128 function initializeHandlers(g) { 129 d3.select("#source-collapse").on("click", function(){ 130 toggleSourceExpanded(true); 131 setTimeout(function(){ 132 g.fitGraphViewToWindow(); 133 }, 1000); 134 }); 135 d3.select("#disassembly-collapse").on("click", function(){ 136 toggleDisassemblyExpanded(); 137 setTimeout(function(){ 138 g.fitGraphViewToWindow(); 139 }, 1000); 140 }); 141 window.onresize = function(){ 142 fitPanesToParents(); 143 }; 144 d3.select("#hidden-file-upload").on("change", function() { 145 if (window.File && window.FileReader && window.FileList) { 146 var uploadFile = this.files[0]; 147 var filereader = new window.FileReader(); 148 var consts = Node.consts; 149 filereader.onload = function(){ 150 var txtRes = filereader.result; 151 // If the JSON isn't properly terminated, assume compiler crashed and 152 // add best-guess empty termination 153 if (txtRes[txtRes.length-2] == ',') { 154 txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}'; 155 } 156 try{ 157 jsonObj = JSON.parse(txtRes); 158 159 sourceView.initializeCode(jsonObj.source, jsonObj.sourcePosition); 160 schedule.setNodePositionMap(jsonObj.nodePositions); 161 162 var selectMenu = document.getElementById('display-selector'); 163 var disassemblyPhase = null; 164 selectMenu.innerHTML = ''; 165 for (var i = 0; i < jsonObj.phases.length; ++i) { 166 var optionElement = document.createElement("option"); 167 optionElement.text = jsonObj.phases[i].name; 168 if (optionElement.text == 'disassembly') { 169 disassemblyPhase = jsonObj.phases[i]; 170 } else { 171 selectMenu.add(optionElement, null); 172 } 173 } 174 disassemblyView.setNodePositionMap(jsonObj.nodePositions); 175 disassemblyView.show(disassemblyPhase.data, null); 176 177 displayPhase(jsonObj.phases[0]); 178 179 selectMenu.onchange = function(item) { 180 displayPhase(jsonObj.phases[selectMenu.selectedIndex]); 181 } 182 183 fitPanesToParents(); 184 } 185 catch(err) { 186 window.alert("Invalid TurboFan JSON file\n" + 187 "error: " + err.message); 188 return; 189 } 190 }; 191 filereader.readAsText(uploadFile); 192 } else { 193 alert("Can't load graph"); 194 } 195 }); 196 } 197 198 sourceView = new CodeView(SOURCE_PANE_ID, PR, "", 0, selectionBroker); 199 disassemblyView = new DisassemblyView(DISASSEMBLY_PANE_ID, selectionBroker); 200 graph = new GraphView(d3, GRAPH_PANE_ID, [], [], selectionBroker); 201 schedule = new ScheduleView(SCHEDULE_PANE_ID, selectionBroker); 202 empty = new EmptyView(EMPTY_PANE_ID, selectionBroker); 203 204 initializeHandlers(graph); 205 206 setSourceExpanded(true); 207 setDisassemblyExpanded(false); 208 209 displayPhaseView(empty, null); 210 fitPanesToParents(); 211 })(window.d3); 212