Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / tools / tracing / trace.html
1 <!--
2 Tracing template
3 ----------------
4 Test_shell has an optional tracing feature.  It can be enabled by running
5 with the --enable-tracing option.  Tracing causes events to be dropped into
6 a trace file during runtime.
7
8 This HTML file can be used to render the output from the trace.  You'll need
9 to rename your trace data to "trace_data.js" in the same directory with this
10 HTML file, and then you can visualize the trace.
11
12 Lots of work remains on this tracing tool; currently development is on hold.
13
14 -->
15
16 <html>
17 <head>
18 <title>
19 Trace Events
20 </title>
21 <style>
22 body {
23   font-family: "Courier New";
24   font-size: 9pt;
25 }
26
27 #header {
28   position: absolute;
29   top: 0px;
30   left: 0px;
31   border-bottom: 1px dashed black;
32   background-color: #F0F0F0;
33   z-index: 3;
34 }
35
36 #outer {
37   position: relative;
38   height: 200px;
39 }
40
41 #time_scale {
42   height: 15px;
43   width: 100%;
44 }
45
46 #tooltip {
47   position: absolute;
48   background-color: #FFFFCC;
49   display: none;
50   font-family: "Courier New";
51   font-size: 9pt;
52   padding: 5px;
53   border: 1px solid #CCCC88;
54   z-index: 3;
55 }
56
57 #legend {
58   position: fixed;
59   left: 10px;
60   bottom: 10px;
61   padding: 5px;
62   border: 1px solid silver;
63   z-index: 10;
64   background-color: #f0f0f0;
65 }
66
67 h2 {
68   margin: 5px;
69 }
70
71 #instructions {
72   position: absolute;
73   top: 
74   float: right;
75   display: none;
76 }
77
78 li.time_tick {
79   background-color: #FFFFCC;
80   height: 15px;
81 }
82
83 li {
84   background: pink;
85   position: absolute;
86   height: 10px;
87   list-style: none;
88   margin: 0px;
89   padding: 0px;
90   z-index: 2;
91 }
92
93 li:hover {
94   border: 1px solid red;
95 }
96
97 .url {
98   background-color: green;
99 }
100
101 .http {
102   background-color: blue;
103 }
104
105 .socket {
106   background-color: black;
107 }
108
109 .v8 {
110   background-color: orange; 
111 }
112
113 .loop {
114   background-color: gray; 
115 }
116
117 .io {
118   background-color: blue;
119 }
120
121 </style>
122
123 <script src='trace_data.js'></script>
124 <script>
125 var scale = 100000;
126 var row_height = 15;
127 var trace_initial_time = 0;
128 var trace_threads = {};
129 var heartbeats = [];
130 var trace_total_time = 0;
131
132 function process_raw_events() {
133   trace_initial_time = raw_trace_events[0].usec_begin;
134   var stack = [];
135   var e;
136   for (var i in raw_trace_events) {
137     e = raw_trace_events[i];
138     var trace_events = trace_threads["e.tid"];
139     if (!trace_events) {
140       trace_events = [];
141       trace_threads["e.tid"] = trace_events;
142     }
143     if (e.name.indexOf("heartbeat.") == 0) {
144       heartbeats.push(e);
145     } else if (e.type == "BEGIN") {
146       trace_events.push(e);
147       stack.unshift(e);
148     } else if (e.type == "END") {
149       for (var s in stack) {
150         var begin = stack[s];
151         if ((begin.id == e.id) && (begin.name == e.name) &&
152             (begin.pid == e.pid) && (begin.tid == e.tid)) {
153           begin.usec_end = e.usec_begin;
154           begin.duration = begin.usec_end - begin.usec_begin;
155           begin.extra += " " + e.extra;
156           stack.splice(s, 1);
157           break;
158         } 
159       }
160     } else if (e.type == "INSTANT") {
161       trace_events.push(e);
162       e.duration = 0;
163     }
164   }
165   if (e.usec_end)
166     trace_total_time = e.usec_end - trace_initial_time;
167   else
168     trace_total_time = e.usec_begin - trace_initial_time;
169 }
170
171 function compute_scale() {
172   var outer = document.getElementById("outer");
173   scale = Math.floor(trace_total_time / (outer.offsetWidth - (row_height * 2)));
174 };
175
176 function show_details(tid, i, event) {
177   var trace_events = trace_threads["e.tid"];
178   var inner = trace_events[i].name + " " +
179               trace_events[i].duration / 1000 + "ms<br />" + 
180               trace_events[i].id  + "<br />" + 
181               trace_events[i].extra  + "<br />";
182   var tooltip = document.getElementById("tooltip");
183   tooltip.innerHTML = inner;
184   if (window.event)
185     event = window.event;
186   tooltip.style.top = event.pageY + 3;
187   tooltip.style.left = event.pageX + 3;
188   tooltip.style.display = "block";
189 };
190
191 function generate_time_scale() {
192   var view_size = window.clientWidth;
193   var body_size = document.body.scrollWidth;
194   var inner = "";
195   
196   var step_ms = Math.floor(scale / 10); // ms per 100px
197   var pow10 = Math.pow(10, Math.floor(Math.log(step_ms) / Math.log(10)));
198   var round = .5 * pow10;
199   step_ms = round * (Math.floor(step_ms / round)); // round to a multiple of round
200   for (var i = step_ms; i < trace_total_time / 1000; i += step_ms) {
201     var x = Math.floor(i * 1000 / scale);
202     inner += "<li class='time_tick' style='left: " + x + "px'>" + i + "</li>";
203   }
204   var time_scale = document.getElementById("time_scale");
205   time_scale.innerHTML = inner;
206   time_scale.style.width = document.body.scrollWidth;
207 }
208
209 function generate_io_graph(trace_events, top) {
210   var max_height = 200;
211   var bucket_size = 50000;  // millisecs
212
213   var inner = "";
214   var buckets = new Array();
215   var value = 0;
216   var max_bucket = 0;
217
218   // Go through events and find all read samples.
219   // Aggregate data into buckets.
220   for (var i in trace_events) {
221     var e = trace_events[i];
222     if (e.name != "socket.read") {
223       continue;
224     }
225
226     var bytes = parseInt(e.extra);
227 //    bytes = 400;
228
229     var start_time = e.usec_begin - trace_initial_time;
230     var mybucket = Math.floor(start_time / bucket_size);
231
232     if (buckets[mybucket] == undefined) {
233       buckets[mybucket] = 0;
234     }
235     buckets[mybucket] += bytes;
236
237     if (buckets[max_bucket] == undefined || 
238         buckets[max_bucket] < buckets[mybucket]) {
239       max_bucket = mybucket;
240     }
241   }
242
243   for (var index = 0; index < buckets.length; index++) {
244     var left = index * Math.floor(bucket_size / scale);
245     var width = Math.floor(bucket_size / scale);
246     if (width == 0)
247       width = 1;
248
249     var height;
250     if (buckets[index] == undefined) {
251       height = 0;
252     } else {
253       height = (buckets[index] / buckets[max_bucket]) * max_height;
254     }
255
256     var my_top = max_height - height;
257
258     var style = "top: " + my_top + "px; left: " + left + "px; width: " + width + "px; height:" + height + "px;";
259     var cls = "io";
260     inner += "<li title='" + buckets[index] + " bytes' class='" + cls + "' id='li-" + i + "' style='" + style + "'></li>\n";
261   }
262
263   var subchart = document.createElement('div');
264   subchart.setAttribute("class", "iograph");
265   subchart.setAttribute("id", trace_events[0].tid);
266   subchart.innerHTML = inner;
267   subchart.style.height = max_height;
268   subchart.style.top = top;
269   subchart.style.left = 0;
270   subchart.style.position = "absolute";
271 //  subchart.style.width = row_height + last_max_x;
272   var chart = document.getElementById("chart");
273   chart.appendChild(subchart);
274
275   return top + max_height;
276 }
277
278 function generate_subchart(trace_events, top) {
279   var start_top = top;
280   var heights = new Array();
281   var max_row = 0;
282   var inner = "";
283   var last_max_time = 0;
284   var last_max_x = 0;
285   for (var i in trace_events) {
286     var e = trace_events[i];
287     var start_time = e.usec_begin - trace_initial_time;
288     var left = row_height + Math.floor(start_time / scale);
289     var width = Math.floor(e.duration / scale);
290     if (width == 0)
291       width = 1;
292
293     if (heights[e.id]) {
294       top = heights[e.id];
295     } else {
296       max_row += row_height;
297       heights[e.id] = max_row;
298       top = heights[e.id];
299     }
300     //if (start_time < last_max_time)
301     //  top += row_height;
302     var style = "top: " + top + "px; left: " + left + "px; width: " + width + "px;";
303     var js = 'javascript:show_details("' + e.tid + '", ' + i + ', event);';
304     var cls = e.name.split('.')[0];
305     inner += "<li class='" + cls + "' onmouseover='" + js + "' id='li-" + i + "' style='" + style + "'></li>\n";
306     last_max_time = start_time + e.duration;
307     last_max_x = left + width;
308   }
309   var subchart = document.createElement('div');
310   subchart.setAttribute("class", "subchart");
311   subchart.setAttribute("id", trace_events[0].tid);
312   subchart.innerHTML = inner;
313   subchart.style.top = start_top + "px";
314   subchart.style.height = top + row_height;
315   subchart.style.width = row_height + last_max_x;
316   subchart.style.position = "absolute";
317   var chart = document.getElementById("chart");
318   chart.appendChild(subchart);
319   
320   return top;
321 };
322
323 function generate_chart() {
324   var chart = document.getElementById("chart");
325   chart.innerHTML = "";
326   var top = 60;
327   for (var t in trace_threads) {
328     top = generate_io_graph(trace_threads[t], top);
329     top = generate_subchart(trace_threads[t], top);
330   }
331   generate_time_scale();
332 }
333
334 function change_scale(event) {
335   if (!event)
336     event = window.event;
337   if (!event.shiftKey)
338     return;
339   var delta = 0;
340   if (event.wheelDelta) {
341     delta = event.wheelDelta / 120;
342   } else if (event.detail) {
343     delta = - event.detail / 3;
344   }
345   if (delta) {
346     var tooltip = document.getElementById("tooltip");
347     tooltip.style.display = "none";
348     var factor = 1.1;
349     if (delta < 0)
350       scale = Math.floor(scale * factor);
351     else
352       scale = Math.floor(scale / factor);
353     if (scale > 300000)
354       scale = 300000;
355     generate_chart();
356     if (event.preventDefault)
357       event.preventDefault();
358   }
359   event.returnValue = false;
360 };
361
362 function initial_load() {
363   if (window.addEventListener)
364     window.addEventListener('DOMMouseScroll', change_scale, false);
365   window.onmousewheel = document.onmousewheel = change_scale;
366
367   process_raw_events();
368   compute_scale();
369   generate_chart();
370 };
371
372 </script>
373 </head>
374 <body onload='initial_load();'>
375 <div id="header">
376 <h2>Trace Events</h2>
377 <div id="instructions">
378 Use shift+mouse-wheel to zoom in and out.
379 </div>
380 <div id="time_scale"></div>
381 </div>
382 <div id="legend">
383 <span class="url">&nbsp;</span> URL<br />
384 <span class="http">&nbsp;</span> HTTP<br />
385 <span class="socket">&nbsp;</span> Socket<br />
386 <span class="v8">&nbsp;</span> V8<br />
387 <span class="loop">&nbsp;</span> TASKS<br />
388 </div>
389 <div id="chart">
390 <div id="outer">
391 </div>
392 </div>
393 <div id="tooltip" ondblclick="this.style.display = 'none';"></div>
394 </body>
395 </html>