Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 1 | <html> |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 2 | <!-- |
| 3 | Copyright 2016 the V8 project authors. All rights reserved. Use of this source |
| 4 | code is governed by a BSD-style license that can be found in the LICENSE file. |
| 5 | --> |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 6 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 7 | <head> |
| 8 | <style> |
| 9 | .entry-details {} |
| 10 | |
| 11 | .entry-details TD {} |
| 12 | |
| 13 | .details { |
| 14 | width: 2em; |
| 15 | border: 1px black dotted; |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 16 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 17 | |
| 18 | .count { |
| 19 | text-align: right; |
| 20 | width: 5em; |
| 21 | font-family: monospace; |
| 22 | } |
| 23 | |
| 24 | .percentage { |
| 25 | text-align: right; |
| 26 | width: 5em; |
| 27 | font-family: monospace; |
| 28 | } |
| 29 | |
| 30 | .key { |
| 31 | padding-left: 1em; |
| 32 | } |
| 33 | |
| 34 | .drilldown-group-title { |
| 35 | font-weight: bold; |
| 36 | padding: 0.5em 0 0.2em 0; |
| 37 | } |
| 38 | </style> |
| 39 | <script> |
| 40 | "use strict" |
| 41 | var entries = []; |
| 42 | |
| 43 | class Entry { |
| 44 | constructor(id, line) { |
| 45 | this.id = id; |
| 46 | this.line = line; |
| 47 | var parts = line.split(" "); |
| 48 | if (parts.length < 6) return |
| 49 | this.isValid = false; |
| 50 | if (parts[0][0] !== "[") return; |
| 51 | if (parts[1] === "patching") return; |
| 52 | this.type = parts[0].substr(1); |
| 53 | this.category = "Other"; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 54 | this.map = undefined; |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 55 | if (this.type.indexOf("Store") !== -1) { |
| 56 | this.category = "Store"; |
| 57 | } else if (this.type.indexOf("Load") !== -1) { |
| 58 | this.category = "Load"; |
| 59 | } |
| 60 | if (this.type.length == 0) return; |
| 61 | if (this.type.indexOf('BinaryOpIC(') === 0) { |
| 62 | this.type = "BinaryOpIC"; |
| 63 | var split = parts[0].split('('); |
| 64 | this.state = "(" + split[1] + " => " + parts[2]; |
| 65 | var offset = this.parsePositionAndFile(parts, 6); |
| 66 | if (offset == -1) return |
| 67 | if (this.file === undefined) return |
| 68 | this.file = this.file.slice(0, -1); |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 69 | } else { |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 70 | var offset = this.parsePositionAndFile(parts, 2); |
| 71 | if (offset == -1) return |
| 72 | this.state = parts[++offset]; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 73 | this.map = parts[offset + 1]; |
| 74 | if (this.map !== undefined && this.map.startsWith("map=")) { |
| 75 | this.map = this.map.substring(4); |
| 76 | offset++; |
| 77 | } else { |
| 78 | this.map = undefined; |
| 79 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 80 | if (this.type !== "CompareIC") { |
| 81 | // if there is no address we have a smi key |
| 82 | var address = parts[++offset]; |
| 83 | if (address !== undefined && address.indexOf("0x") === 0) { |
| 84 | this.key = parts.slice(++offset).join(" "); |
| 85 | } else { |
| 86 | this.key = address; |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | this.filePosition = this.file + " " + this.position; |
| 91 | if (this.key) { |
| 92 | var isStringKey = false |
| 93 | if (this.key.indexOf("<String[") === 0) { |
| 94 | isStringKey = true; |
| 95 | this.key = "\"" + this.key.slice(this.key.indexOf(']') + 3); |
| 96 | } else if (this.key.indexOf("<") === 0) { |
| 97 | this.key = this.key.slice(1); |
| 98 | } |
| 99 | if (this.key.endsWith(">]")) { |
| 100 | this.key = this.key.slice(0, -2); |
| 101 | } else if (this.key.endsWith("]")) { |
| 102 | this.key = this.key.slice(0, -1); |
| 103 | } |
| 104 | if (isStringKey) { |
| 105 | this.key = this.key + "\""; |
| 106 | } |
| 107 | } |
| 108 | this.isValid = true; |
| 109 | } |
| 110 | |
| 111 | parsePositionAndFile(parts, start) { |
| 112 | // find the position of 'at' in the parts array. |
| 113 | var offset = start; |
| 114 | for (var i = start + 1; i < parts.length; i++) { |
| 115 | offset++; |
| 116 | if (parts[i] == 'at') break; |
| 117 | } |
| 118 | if (parts[offset] !== 'at') return -1; |
| 119 | this.position = parts.slice(start, offset).join(' '); |
| 120 | offset += 1; |
| 121 | this.isNative = parts[offset] == "native" |
| 122 | offset += this.isNative ? 1 : 0; |
| 123 | this.file = parts[offset]; |
| 124 | return offset; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | function loadFile() { |
| 129 | var files = document.getElementById("uploadInput").files; |
| 130 | |
| 131 | var file = files[0]; |
| 132 | var reader = new FileReader(); |
| 133 | |
| 134 | reader.onload = function(evt) { |
| 135 | entries = []; |
| 136 | var end = this.result.length; |
| 137 | var current = 0; |
| 138 | var next = 0; |
| 139 | var line; |
| 140 | var i = 0; |
| 141 | var entry; |
| 142 | while (current < end) { |
| 143 | next = this.result.indexOf("\n", current); |
| 144 | if (next === -1) break; |
| 145 | i++; |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 146 | line = this.result.substring(current, next); |
| 147 | current = next + 1; |
| 148 | entry = new Entry(i, line); |
| 149 | if (entry.isValid) entries.push(entry); |
| 150 | } |
| 151 | |
| 152 | document.getElementById("count").innerHTML = i; |
| 153 | updateTable(); |
| 154 | } |
| 155 | reader.readAsText(file); |
| 156 | initGroupKeySelect(); |
| 157 | } |
| 158 | |
| 159 | |
| 160 | |
| 161 | var properties = ['type', 'category', 'file', 'filePosition', 'state', |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 162 | 'key', 'isNative', 'map' |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 163 | ] |
| 164 | |
| 165 | class Group { |
| 166 | constructor(property, key, entry) { |
| 167 | this.property = property; |
| 168 | this.key = key; |
| 169 | this.count = 1; |
| 170 | this.entries = [entry]; |
| 171 | this.percentage = undefined; |
| 172 | this.groups = undefined; |
| 173 | } |
| 174 | |
| 175 | add(entry) { |
| 176 | this.count++; |
| 177 | this.entries.push(entry) |
| 178 | } |
| 179 | |
| 180 | createSubGroups() { |
| 181 | this.groups = {}; |
| 182 | for (var i = 0; i < properties.length; i++) { |
| 183 | var subProperty = properties[i]; |
| 184 | if (this.property == subProperty) continue; |
| 185 | this.groups[subProperty] = groupBy(this.entries, subProperty); |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 186 | } |
| 187 | } |
| 188 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 189 | |
| 190 | function groupBy(entries, property) { |
| 191 | var accumulator = {}; |
| 192 | accumulator.__proto__ = null; |
| 193 | var length = entries.length; |
| 194 | for (var i = 0; i < length; i++) { |
| 195 | var entry = entries[i]; |
| 196 | var key = entry[property]; |
| 197 | if (accumulator[key] == undefined) { |
| 198 | accumulator[key] = new Group(property, key, entry) |
| 199 | } else { |
| 200 | var group = accumulator[key]; |
| 201 | if (group.entries == undefined) console.log([group, entry]); |
| 202 | group.add(entry) |
| 203 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 204 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 205 | var result = [] |
| 206 | for (var key in accumulator) { |
| 207 | var group = accumulator[key]; |
| 208 | group.percentage = Math.round(group.count / length * 100 * 100) / 100; |
| 209 | result.push(group); |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 210 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 211 | result.sort((a, b) => { |
| 212 | return b.count - a.count |
| 213 | }); |
| 214 | return result; |
| 215 | } |
| 216 | |
| 217 | |
| 218 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 219 | function escapeHtml(unsafe) { |
| 220 | if (!unsafe) return ""; |
| 221 | return unsafe.toString() |
| 222 | .replace(/&/g, "&") |
| 223 | .replace(/</g, "<") |
| 224 | .replace(/>/g, ">") |
| 225 | .replace(/"/g, """) |
| 226 | .replace(/'/g, "'"); |
| 227 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 228 | |
| 229 | function updateTable() { |
| 230 | var select = document.getElementById("group-key"); |
| 231 | var key = select.options[select.selectedIndex].text; |
| 232 | console.log(key); |
| 233 | var tableBody = document.getElementById("table-body"); |
| 234 | removeAllChildren(tableBody); |
| 235 | var groups = groupBy(entries, key, true); |
| 236 | display(groups, tableBody); |
| 237 | } |
| 238 | |
| 239 | function selecedOption(node) { |
| 240 | return node.options[node.selectedIndex] |
| 241 | } |
| 242 | |
| 243 | function removeAllChildren(node) { |
| 244 | while (node.firstChild) { |
| 245 | node.removeChild(node.firstChild); |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 246 | } |
| 247 | } |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 248 | |
| 249 | function display(entries, parent) { |
| 250 | var fragment = document.createDocumentFragment(); |
| 251 | |
| 252 | function td(tr, content, className) { |
| 253 | var td = document.createElement("td"); |
| 254 | td.innerHTML = content; |
| 255 | td.className = className |
| 256 | tr.appendChild(td); |
| 257 | return td |
| 258 | } |
| 259 | var max = Math.min(1000, entries.length) |
| 260 | for (var i = 0; i < max; i++) { |
| 261 | var entry = entries[i]; |
| 262 | var tr = document.createElement("tr"); |
| 263 | tr.entry = entry; |
| 264 | td(tr, '<span onclick="toggleDetails(this)">details</a>', 'details'); |
| 265 | td(tr, entry.percentage + "%", 'percentage'); |
| 266 | td(tr, entry.count, 'count'); |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 267 | td(tr, escapeHtml(entry.key), 'key'); |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 268 | fragment.appendChild(tr); |
| 269 | } |
| 270 | var omitted = entries.length - max; |
| 271 | if (omitted > 0) { |
| 272 | var tr = document.createElement("tr"); |
| 273 | var td = td(tr, 'Omitted ' + omitted + " entries."); |
| 274 | td.colSpan = 4; |
| 275 | fragment.appendChild(tr); |
| 276 | } |
| 277 | parent.appendChild(fragment); |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 278 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 279 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 280 | function displayDrilldown(entry, previousSibling) { |
| 281 | var tr = document.createElement('tr'); |
| 282 | tr.className = "entry-details"; |
| 283 | tr.style.display = "none"; |
| 284 | // indent by one td. |
| 285 | tr.appendChild(document.createElement("td")); |
| 286 | var td = document.createElement("td"); |
| 287 | td.colSpan = 3; |
| 288 | for (var key in entry.groups) { |
| 289 | td.appendChild(displayDrilldownGroup(entry, key)); |
| 290 | } |
| 291 | tr.appendChild(td); |
| 292 | // Append the new TR after previousSibling. |
| 293 | previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling) |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 294 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 295 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 296 | function displayDrilldownGroup(entry, key) { |
| 297 | var max = 20; |
| 298 | var group = entry.groups[key]; |
| 299 | var div = document.createElement("div") |
| 300 | div.className = 'drilldown-group-title' |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 301 | div.innerHTML = key + ' [top ' + max + ' out of ' + group.length + ']'; |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 302 | var table = document.createElement("table"); |
| 303 | display(group.slice(0, max), table, false) |
| 304 | div.appendChild(table); |
| 305 | return div; |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 306 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 307 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 308 | function toggleDetails(node) { |
| 309 | var tr = node.parentNode.parentNode; |
| 310 | var entry = tr.entry; |
| 311 | |
| 312 | // Create subgroup in-place if the don't exist yet. |
| 313 | if (entry.groups === undefined) { |
| 314 | entry.createSubGroups(); |
| 315 | displayDrilldown(entry, tr); |
| 316 | } |
| 317 | var details = tr.nextSibling; |
| 318 | var display = details.style.display; |
| 319 | if (display != "none") { |
| 320 | display = "none"; |
| 321 | } else { |
| 322 | display = "table-row" |
| 323 | }; |
| 324 | details.style.display = display; |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 325 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 326 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 327 | function initGroupKeySelect() { |
| 328 | var select = document.getElementById("group-key"); |
| 329 | for (var i in properties) { |
| 330 | var option = document.createElement("option"); |
| 331 | option.text = properties[i]; |
| 332 | select.add(option); |
| 333 | } |
| 334 | } |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 335 | </script> |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 336 | </head> |
| 337 | |
| 338 | <body> |
| 339 | <h1> |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 340 | <span style="color: #00FF00">I</span> |
| 341 | <span style="color: #FF00FF">C</span> |
| 342 | <span style="color: #00FFFF">E</span> |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 343 | </h1> Your IC-Explorer. |
| 344 | <h2>Usage</h2> Run your script with <code>--trace_ic</code> and upload on this page:<br/> |
| 345 | <code>/path/to/d8 --trace_ic your_script.js > trace.txt</code> |
| 346 | <h2>Data</h2> |
| 347 | <form name="fileForm"> |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 348 | <p> |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 349 | <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace |
| 350 | entries: <span id="count">0</span> |
| 351 | </p> |
| 352 | </form> |
| 353 | <h2>Result</h2> |
| 354 | <p> |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 355 | Group-Key: |
| 356 | <select id="group-key" onchange="updateTable()"></select> |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 357 | </p> |
| 358 | <p> |
| 359 | <table id="table" width="100%"> |
| 360 | <tbody id="table-body"> |
| 361 | </tbody> |
| 362 | </table> |
| 363 | </p> |
| 364 | </body> |
| 365 | |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 366 | </html> |