blob: ad1737a6f77346c28ba81023f6d8b987e71c315c [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001<html>
Ben Murdochc5610432016-08-08 18:44:38 +01002<!--
3Copyright 2016 the V8 project authors. All rights reserved. Use of this source
4code is governed by a BSD-style license that can be found in the LICENSE file.
5-->
Ben Murdoch097c5b22016-05-18 11:27:45 +01006
Ben Murdochc5610432016-08-08 18:44:38 +01007<head>
8 <style>
9 .entry-details {}
10
11 .entry-details TD {}
12
13 .details {
14 width: 2em;
15 border: 1px black dotted;
Ben Murdoch097c5b22016-05-18 11:27:45 +010016 }
Ben Murdochc5610432016-08-08 18:44:38 +010017
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";
54 if (this.type.indexOf("Store") !== -1) {
55 this.category = "Store";
56 } else if (this.type.indexOf("Load") !== -1) {
57 this.category = "Load";
58 }
59 if (this.type.length == 0) return;
60 if (this.type.indexOf('BinaryOpIC(') === 0) {
61 this.type = "BinaryOpIC";
62 var split = parts[0].split('(');
63 this.state = "(" + split[1] + " => " + parts[2];
64 var offset = this.parsePositionAndFile(parts, 6);
65 if (offset == -1) return
66 if (this.file === undefined) return
67 this.file = this.file.slice(0, -1);
Ben Murdoch097c5b22016-05-18 11:27:45 +010068 } else {
Ben Murdochc5610432016-08-08 18:44:38 +010069 var offset = this.parsePositionAndFile(parts, 2);
70 if (offset == -1) return
71 this.state = parts[++offset];
72 if (this.type !== "CompareIC") {
73 // if there is no address we have a smi key
74 var address = parts[++offset];
75 if (address !== undefined && address.indexOf("0x") === 0) {
76 this.key = parts.slice(++offset).join(" ");
77 } else {
78 this.key = address;
79 }
80 }
81 }
82 this.filePosition = this.file + " " + this.position;
83 if (this.key) {
84 var isStringKey = false
85 if (this.key.indexOf("<String[") === 0) {
86 isStringKey = true;
87 this.key = "\"" + this.key.slice(this.key.indexOf(']') + 3);
88 } else if (this.key.indexOf("<") === 0) {
89 this.key = this.key.slice(1);
90 }
91 if (this.key.endsWith(">]")) {
92 this.key = this.key.slice(0, -2);
93 } else if (this.key.endsWith("]")) {
94 this.key = this.key.slice(0, -1);
95 }
96 if (isStringKey) {
97 this.key = this.key + "\"";
98 }
99 }
100 this.isValid = true;
101 }
102
103 parsePositionAndFile(parts, start) {
104 // find the position of 'at' in the parts array.
105 var offset = start;
106 for (var i = start + 1; i < parts.length; i++) {
107 offset++;
108 if (parts[i] == 'at') break;
109 }
110 if (parts[offset] !== 'at') return -1;
111 this.position = parts.slice(start, offset).join(' ');
112 offset += 1;
113 this.isNative = parts[offset] == "native"
114 offset += this.isNative ? 1 : 0;
115 this.file = parts[offset];
116 return offset;
117 }
118 }
119
120 function loadFile() {
121 var files = document.getElementById("uploadInput").files;
122
123 var file = files[0];
124 var reader = new FileReader();
125
126 reader.onload = function(evt) {
127 entries = [];
128 var end = this.result.length;
129 var current = 0;
130 var next = 0;
131 var line;
132 var i = 0;
133 var entry;
134 while (current < end) {
135 next = this.result.indexOf("\n", current);
136 if (next === -1) break;
137 i++;
138
139 line = this.result.substring(current, next);
140 current = next + 1;
141 entry = new Entry(i, line);
142 if (entry.isValid) entries.push(entry);
143 }
144
145 document.getElementById("count").innerHTML = i;
146 updateTable();
147 }
148 reader.readAsText(file);
149 initGroupKeySelect();
150 }
151
152
153
154 var properties = ['type', 'category', 'file', 'filePosition', 'state',
155 'key', 'isNative'
156 ]
157
158 class Group {
159 constructor(property, key, entry) {
160 this.property = property;
161 this.key = key;
162 this.count = 1;
163 this.entries = [entry];
164 this.percentage = undefined;
165 this.groups = undefined;
166 }
167
168 add(entry) {
169 this.count++;
170 this.entries.push(entry)
171 }
172
173 createSubGroups() {
174 this.groups = {};
175 for (var i = 0; i < properties.length; i++) {
176 var subProperty = properties[i];
177 if (this.property == subProperty) continue;
178 this.groups[subProperty] = groupBy(this.entries, subProperty);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100179 }
180 }
181 }
Ben Murdochc5610432016-08-08 18:44:38 +0100182
183 function groupBy(entries, property) {
184 var accumulator = {};
185 accumulator.__proto__ = null;
186 var length = entries.length;
187 for (var i = 0; i < length; i++) {
188 var entry = entries[i];
189 var key = entry[property];
190 if (accumulator[key] == undefined) {
191 accumulator[key] = new Group(property, key, entry)
192 } else {
193 var group = accumulator[key];
194 if (group.entries == undefined) console.log([group, entry]);
195 group.add(entry)
196 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100197 }
Ben Murdochc5610432016-08-08 18:44:38 +0100198 var result = []
199 for (var key in accumulator) {
200 var group = accumulator[key];
201 group.percentage = Math.round(group.count / length * 100 * 100) / 100;
202 result.push(group);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100203 }
Ben Murdochc5610432016-08-08 18:44:38 +0100204 result.sort((a, b) => {
205 return b.count - a.count
206 });
207 return result;
208 }
209
210
211
212
213 function updateTable() {
214 var select = document.getElementById("group-key");
215 var key = select.options[select.selectedIndex].text;
216 console.log(key);
217 var tableBody = document.getElementById("table-body");
218 removeAllChildren(tableBody);
219 var groups = groupBy(entries, key, true);
220 display(groups, tableBody);
221 }
222
223 function selecedOption(node) {
224 return node.options[node.selectedIndex]
225 }
226
227 function removeAllChildren(node) {
228 while (node.firstChild) {
229 node.removeChild(node.firstChild);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100230 }
231 }
Ben Murdochc5610432016-08-08 18:44:38 +0100232
233 function display(entries, parent) {
234 var fragment = document.createDocumentFragment();
235
236 function td(tr, content, className) {
237 var td = document.createElement("td");
238 td.innerHTML = content;
239 td.className = className
240 tr.appendChild(td);
241 return td
242 }
243 var max = Math.min(1000, entries.length)
244 for (var i = 0; i < max; i++) {
245 var entry = entries[i];
246 var tr = document.createElement("tr");
247 tr.entry = entry;
248 td(tr, '<span onclick="toggleDetails(this)">details</a>', 'details');
249 td(tr, entry.percentage + "%", 'percentage');
250 td(tr, entry.count, 'count');
251 td(tr, entry.key, 'key');
252 fragment.appendChild(tr);
253 }
254 var omitted = entries.length - max;
255 if (omitted > 0) {
256 var tr = document.createElement("tr");
257 var td = td(tr, 'Omitted ' + omitted + " entries.");
258 td.colSpan = 4;
259 fragment.appendChild(tr);
260 }
261 parent.appendChild(fragment);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100262 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100263
Ben Murdochc5610432016-08-08 18:44:38 +0100264 function displayDrilldown(entry, previousSibling) {
265 var tr = document.createElement('tr');
266 tr.className = "entry-details";
267 tr.style.display = "none";
268 // indent by one td.
269 tr.appendChild(document.createElement("td"));
270 var td = document.createElement("td");
271 td.colSpan = 3;
272 for (var key in entry.groups) {
273 td.appendChild(displayDrilldownGroup(entry, key));
274 }
275 tr.appendChild(td);
276 // Append the new TR after previousSibling.
277 previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling)
Ben Murdoch097c5b22016-05-18 11:27:45 +0100278 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100279
Ben Murdochc5610432016-08-08 18:44:38 +0100280 function displayDrilldownGroup(entry, key) {
281 var max = 20;
282 var group = entry.groups[key];
283 var div = document.createElement("div")
284 div.className = 'drilldown-group-title'
285 div.innerHTML = key + ' [top ' + max + ']';
286 var table = document.createElement("table");
287 display(group.slice(0, max), table, false)
288 div.appendChild(table);
289 return div;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100290 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291
Ben Murdochc5610432016-08-08 18:44:38 +0100292 function toggleDetails(node) {
293 var tr = node.parentNode.parentNode;
294 var entry = tr.entry;
295
296 // Create subgroup in-place if the don't exist yet.
297 if (entry.groups === undefined) {
298 entry.createSubGroups();
299 displayDrilldown(entry, tr);
300 }
301 var details = tr.nextSibling;
302 var display = details.style.display;
303 if (display != "none") {
304 display = "none";
305 } else {
306 display = "table-row"
307 };
308 details.style.display = display;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100309 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100310
Ben Murdochc5610432016-08-08 18:44:38 +0100311 function initGroupKeySelect() {
312 var select = document.getElementById("group-key");
313 for (var i in properties) {
314 var option = document.createElement("option");
315 option.text = properties[i];
316 select.add(option);
317 }
318 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100319 </script>
Ben Murdochc5610432016-08-08 18:44:38 +0100320</head>
321
322<body>
323 <h1>
Ben Murdoch097c5b22016-05-18 11:27:45 +0100324 <span style="color: #00FF00">I</span>
325 <span style="color: #FF00FF">C</span>
326 <span style="color: #00FFFF">E</span>
Ben Murdochc5610432016-08-08 18:44:38 +0100327 </h1> Your IC-Explorer.
328 <h2>Usage</h2> Run your script with <code>--trace_ic</code> and upload on this page:<br/>
329 <code>/path/to/d8 --trace_ic your_script.js > trace.txt</code>
330 <h2>Data</h2>
331 <form name="fileForm">
Ben Murdoch097c5b22016-05-18 11:27:45 +0100332 <p>
Ben Murdochc5610432016-08-08 18:44:38 +0100333 <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace
334 entries: <span id="count">0</span>
335 </p>
336 </form>
337 <h2>Result</h2>
338 <p>
Ben Murdoch097c5b22016-05-18 11:27:45 +0100339 Group-Key:
340 <select id="group-key" onchange="updateTable()"></select>
Ben Murdochc5610432016-08-08 18:44:38 +0100341 </p>
342 <p>
343 <table id="table" width="100%">
344 <tbody id="table-body">
345 </tbody>
346 </table>
347 </p>
348</body>
349
Ben Murdoch097c5b22016-05-18 11:27:45 +0100350</html>