Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: tools/profviz/composer.js

Issue 17599007: Log deopts with --log-timer-events. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/log.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 23 matching lines...) Expand all
34 function PlotScriptComposer(kResX, kResY) { 34 function PlotScriptComposer(kResX, kResY) {
35 // Constants. 35 // Constants.
36 var kV8BinarySuffixes = ["/d8", "/libv8.so"]; 36 var kV8BinarySuffixes = ["/d8", "/libv8.so"];
37 var kStackFrames = 8; // Stack frames to display in the plot. 37 var kStackFrames = 8; // Stack frames to display in the plot.
38 38
39 var kTimerEventWidth = 0.33; // Width of each timeline. 39 var kTimerEventWidth = 0.33; // Width of each timeline.
40 var kExecutionFrameWidth = 0.2; // Width of the top stack frame line. 40 var kExecutionFrameWidth = 0.2; // Width of the top stack frame line.
41 var kStackFrameWidth = 0.1; // Width of the lower stack frame lines. 41 var kStackFrameWidth = 0.1; // Width of the lower stack frame lines.
42 var kGapWidth = 0.05; // Gap between stack frame lines. 42 var kGapWidth = 0.05; // Gap between stack frame lines.
43 43
44 var kY1Offset = 10; // Offset for stack frame vs. event lines. 44 var kY1Offset = 11; // Offset for stack frame vs. event lines.
45 var kDeoptRow = 7; // Row displaying deopts.
46 var kMaxDeoptLength = 4; // Draw size of the largest deopt.
45 var kPauseLabelPadding = 5; // Padding for pause time labels. 47 var kPauseLabelPadding = 5; // Padding for pause time labels.
46 var kNumPauseLabels = 7; // Number of biggest pauses to label. 48 var kNumPauseLabels = 7; // Number of biggest pauses to label.
47 var kCodeKindLabelPadding = 100; // Padding for code kind labels. 49 var kCodeKindLabelPadding = 100; // Padding for code kind labels.
48 50
49 var kTickHalfDuration = 0.5; // Duration of half a tick in ms. 51 var kTickHalfDuration = 0.5; // Duration of half a tick in ms.
50 var kMinRangeLength = 0.0005; // Minimum length for an event in ms. 52 var kMinRangeLength = 0.0005; // Minimum length for an event in ms.
51 53
52 var kNumThreads = 2; // Number of threads. 54 var kNumThreads = 2; // Number of threads.
53 var kExecutionThreadId = 0; // ID of main thread. 55 var kExecutionThreadId = 0; // ID of main thread.
54 56
57 // Init values.
58 var num_timer_event = kY1Offset + 0.5;
59
55 // Data structures. 60 // Data structures.
56 function TimerEvent(label, color, pause, thread_id) { 61 function TimerEvent(label, color, pause, thread_id) {
57 assert(thread_id >= 0 && thread_id < kNumThreads, "invalid thread id"); 62 assert(thread_id >= 0 && thread_id < kNumThreads, "invalid thread id");
58 this.label = label; 63 this.label = label;
59 this.color = color; 64 this.color = color;
60 this.pause = pause; 65 this.pause = pause;
61 this.ranges = []; 66 this.ranges = [];
62 this.thread_id = thread_id; 67 this.thread_id = thread_id;
63 this.index = ++num_timer_event; 68 this.index = ++num_timer_event;
64 } 69 }
65 70
66 function CodeKind(color, kinds) { 71 function CodeKind(color, kinds) {
67 this.color = color; 72 this.color = color;
68 this.in_execution = []; 73 this.in_execution = [];
69 this.stack_frames = []; 74 this.stack_frames = [];
70 for (var i = 0; i < kStackFrames; i++) this.stack_frames.push([]); 75 for (var i = 0; i < kStackFrames; i++) this.stack_frames.push([]);
71 this.kinds = kinds; 76 this.kinds = kinds;
72 } 77 }
73 78
74 function Range(start, end) { 79 function Range(start, end) {
75 // Everthing here are in milliseconds. 80 this.start = start; // In milliseconds.
76 this.start = start; 81 this.end = end; // In milliseconds.
77 this.end = end; 82 }
83
84 function Deopt(time, size) {
85 this.time = time; // In milliseconds.
86 this.size = size; // In bytes.
78 } 87 }
79 88
80 Range.prototype.duration = function() { return this.end - this.start; } 89 Range.prototype.duration = function() { return this.end - this.start; }
81 90
82 function Tick(tick) { 91 function Tick(tick) {
83 this.tick = tick; 92 this.tick = tick;
84 } 93 }
85 94
86 // Init values.
87 var num_timer_event = kY1Offset + 0.5;
88
89 var TimerEvents = { 95 var TimerEvents = {
90 'V8.Execute': 96 'V8.Execute':
91 new TimerEvent("execution", "#000000", false, 0), 97 new TimerEvent("execution", "#000000", false, 0),
92 'V8.External': 98 'V8.External':
93 new TimerEvent("external", "#3399FF", false, 0), 99 new TimerEvent("external", "#3399FF", false, 0),
94 'V8.CompileFullCode': 100 'V8.CompileFullCode':
95 new TimerEvent("compile unopt", "#CC0000", true, 0), 101 new TimerEvent("compile unopt", "#CC0000", true, 0),
96 'V8.RecompileSynchronous': 102 'V8.RecompileSynchronous':
97 new TimerEvent("recompile sync", "#CC0044", true, 0), 103 new TimerEvent("recompile sync", "#CC0044", true, 0),
98 'V8.RecompileParallel': 104 'V8.RecompileParallel':
(...skipping 21 matching lines...) Expand all
120 'opt code ': new CodeKind("#00EE00", [1]), 126 'opt code ': new CodeKind("#00EE00", [1]),
121 'code stub': new CodeKind("#FF00FF", [2]), 127 'code stub': new CodeKind("#FF00FF", [2]),
122 'built-in ': new CodeKind("#AA00AA", [3]), 128 'built-in ': new CodeKind("#AA00AA", [3]),
123 'inl.cache': new CodeKind("#4444AA", 129 'inl.cache': new CodeKind("#4444AA",
124 [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]), 130 [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]),
125 'reg.exp. ': new CodeKind("#0000FF", [15]), 131 'reg.exp. ': new CodeKind("#0000FF", [15]),
126 }; 132 };
127 133
128 var code_map = new CodeMap(); 134 var code_map = new CodeMap();
129 var execution_pauses = []; 135 var execution_pauses = [];
136 var deopts = [];
130 var event_stack = []; 137 var event_stack = [];
131 var last_time_stamp = []; 138 var last_time_stamp = [];
132 for (var i = 0; i < kNumThreads; i++) { 139 for (var i = 0; i < kNumThreads; i++) {
133 event_stack[i] = []; 140 event_stack[i] = [];
134 last_time_stamp[i] = -1; 141 last_time_stamp[i] = -1;
135 } 142 }
136 143
137 var range_start = undefined; 144 var range_start = undefined;
138 var range_end = undefined; 145 var range_end = undefined;
139 var obj_index = 0; 146 var obj_index = 0;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 }; 312 };
306 313
307 var processCodeMoveEvent = function(from, to) { 314 var processCodeMoveEvent = function(from, to) {
308 code_map.moveCode(from, to); 315 code_map.moveCode(from, to);
309 }; 316 };
310 317
311 var processCodeDeleteEvent = function(address) { 318 var processCodeDeleteEvent = function(address) {
312 code_map.deleteCode(address); 319 code_map.deleteCode(address);
313 }; 320 };
314 321
322 var processCodeDeoptEvent = function(time, size) {
323 deopts.push(new Deopt(time, size));
324 }
325
315 var processSharedLibrary = function(name, start, end) { 326 var processSharedLibrary = function(name, start, end) {
316 var code_entry = new CodeMap.CodeEntry(end - start, name); 327 var code_entry = new CodeMap.CodeEntry(end - start, name);
317 code_entry.kind = -3; // External code kind. 328 code_entry.kind = -3; // External code kind.
318 for (var i = 0; i < kV8BinarySuffixes.length; i++) { 329 for (var i = 0; i < kV8BinarySuffixes.length; i++) {
319 var suffix = kV8BinarySuffixes[i]; 330 var suffix = kV8BinarySuffixes[i];
320 if (name.indexOf(suffix, name.length - suffix.length) >= 0) { 331 if (name.indexOf(suffix, name.length - suffix.length) >= 0) {
321 code_entry.kind = -1; // V8 runtime code kind. 332 code_entry.kind = -1; // V8 runtime code kind.
322 break; 333 break;
323 } 334 }
324 } 335 }
(...skipping 20 matching lines...) Expand all
345 'timer-event-end': { parsers: [null, parseTimeStamp], 356 'timer-event-end': { parsers: [null, parseTimeStamp],
346 processor: processTimerEventEnd }, 357 processor: processTimerEventEnd },
347 'shared-library': { parsers: [null, parseInt, parseInt], 358 'shared-library': { parsers: [null, parseInt, parseInt],
348 processor: processSharedLibrary }, 359 processor: processSharedLibrary },
349 'code-creation': { parsers: [null, parseInt, parseInt, parseInt, null], 360 'code-creation': { parsers: [null, parseInt, parseInt, parseInt, null],
350 processor: processCodeCreateEvent }, 361 processor: processCodeCreateEvent },
351 'code-move': { parsers: [parseInt, parseInt], 362 'code-move': { parsers: [parseInt, parseInt],
352 processor: processCodeMoveEvent }, 363 processor: processCodeMoveEvent },
353 'code-delete': { parsers: [parseInt], 364 'code-delete': { parsers: [parseInt],
354 processor: processCodeDeleteEvent }, 365 processor: processCodeDeleteEvent },
366 'code-deopt': { parsers: [parseTimeStamp, parseInt],
367 processor: processCodeDeoptEvent },
355 'tick': { parsers: [parseInt, parseInt, parseTimeStamp, 368 'tick': { parsers: [parseInt, parseInt, parseTimeStamp,
356 null, null, parseInt, 'var-args'], 369 null, null, parseInt, 'var-args'],
357 processor: processTickEvent } 370 processor: processTickEvent }
358 }); 371 });
359 372
360 var line; 373 var line;
361 while (line = input()) { 374 while (line = input()) {
362 logreader.processLogLine(line); 375 logreader.processLogLine(line);
363 } 376 }
364 377
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 }; 428 };
416 429
417 430
418 this.assembleOutput = function(output) { 431 this.assembleOutput = function(output) {
419 output("set yrange [0:" + (num_timer_event + 1) + "]"); 432 output("set yrange [0:" + (num_timer_event + 1) + "]");
420 output("set xlabel \"execution time in ms\""); 433 output("set xlabel \"execution time in ms\"");
421 output("set xrange [" + range_start + ":" + range_end + "]"); 434 output("set xrange [" + range_start + ":" + range_end + "]");
422 output("set style fill pattern 2 bo 1"); 435 output("set style fill pattern 2 bo 1");
423 output("set style rect fs solid 1 noborder"); 436 output("set style rect fs solid 1 noborder");
424 output("set style line 1 lt 1 lw 1 lc rgb \"#000000\""); 437 output("set style line 1 lt 1 lw 1 lc rgb \"#000000\"");
438 output("set style line 2 lt 1 lw 1 lc rgb \"#9944CC\"");
425 output("set xtics out nomirror"); 439 output("set xtics out nomirror");
426 output("unset key"); 440 output("unset key");
427 441
428 function DrawBar(row, color, start, end, width) { 442 function DrawBarBase(color, start, end, top, bottom) {
429 obj_index++; 443 obj_index++;
430 command = "set object " + obj_index + " rect"; 444 command = "set object " + obj_index + " rect";
431 command += " from " + start + ", " + (row - width); 445 command += " from " + start + ", " + top;
432 command += " to " + end + ", " + (row + width); 446 command += " to " + end + ", " + bottom;
433 command += " fc rgb \"" + color + "\""; 447 command += " fc rgb \"" + color + "\"";
434 output(command); 448 output(command);
435 } 449 }
436 450
451 function DrawBar(row, color, start, end, width) {
452 DrawBarBase(color, start, end, row + width, row - width);
453 }
454
455 function DrawHalfBar(row, color, start, end, width) {
456 DrawBarBase(color, start, end, row, row - width);
457 }
458
437 var percentages = {}; 459 var percentages = {};
438 var total = 0; 460 var total = 0;
439 for (var name in TimerEvents) { 461 for (var name in TimerEvents) {
440 var event = TimerEvents[name]; 462 var event = TimerEvents[name];
441 var ranges = RestrictRangesTo(event.ranges, range_start, range_end); 463 var ranges = RestrictRangesTo(event.ranges, range_start, range_end);
442 ranges = MergeRanges(ranges); 464 ranges = MergeRanges(ranges);
443 var sum = 465 var sum =
444 ranges.map(function(range) { return range.duration(); }) 466 ranges.map(function(range) { return range.duration(); })
445 .reduce(function(a, b) { return a + b; }, 0); 467 .reduce(function(a, b) { return a + b; }, 0);
446 percentages[name] = (sum / (range_end - range_start) * 100).toFixed(1); 468 percentages[name] = (sum / (range_end - range_start) * 100).toFixed(1);
447 } 469 }
448 470
471 // Plot deopts.
472 deopts.sort(function(a, b) { return b.size - a.size; });
473 var max_deopt_size = deopts.length > 0 ? deopts[0].size : Infinity;
474
475 for (var i = 0; i < deopts.length; i++) {
476 var deopt = deopts[i];
477 DrawHalfBar(kDeoptRow, "#9944CC", deopt.time,
478 deopt.time + 10 * pause_tolerance,
479 deopt.size / max_deopt_size * kMaxDeoptLength);
480 }
481
449 // Name Y-axis. 482 // Name Y-axis.
450 var ytics = []; 483 var ytics = [];
451 for (name in TimerEvents) { 484 for (name in TimerEvents) {
452 var index = TimerEvents[name].index; 485 var index = TimerEvents[name].index;
453 var label = TimerEvents[name].label; 486 var label = TimerEvents[name].label;
454 ytics.push('"' + label + ' (' + percentages[name] + '%%)" ' + index); 487 ytics.push('"' + label + ' (' + percentages[name] + '%%)" ' + index);
455 } 488 }
456 ytics.push('"code kind color coding" ' + kY1Offset); 489 ytics.push('"code kind color coding" ' + kY1Offset);
457 ytics.push('"code kind in execution" ' + (kY1Offset - 1)); 490 ytics.push('"code kind in execution" ' + (kY1Offset - 1));
458 ytics.push('"top ' + kStackFrames + ' js stack frames"' + ' ' + 491 ytics.push('"top ' + kStackFrames + ' js stack frames"' + ' ' +
459 (kY1Offset - 2)); 492 (kY1Offset - 2));
460 ytics.push('"pause times" 0'); 493 ytics.push('"pause times" 0');
494 ytics.push('"max deopt size: ' + (max_deopt_size / 1024).toFixed(1) +
495 ' kB" ' + kDeoptRow);
461 output("set ytics out nomirror (" + ytics.join(', ') + ")"); 496 output("set ytics out nomirror (" + ytics.join(', ') + ")");
462 497
463 // Plot timeline. 498 // Plot timeline.
464 for (var name in TimerEvents) { 499 for (var name in TimerEvents) {
465 var event = TimerEvents[name]; 500 var event = TimerEvents[name];
466 var ranges = MergeRanges(event.ranges); 501 var ranges = MergeRanges(event.ranges);
467 for (var i = 0; i < ranges.length; i++) { 502 for (var i = 0; i < ranges.length; i++) {
468 DrawBar(event.index, event.color, 503 DrawBar(event.index, event.color,
469 ranges[i].start, ranges[i].end, 504 ranges[i].start, ranges[i].end,
470 kTimerEventWidth); 505 kTimerEventWidth);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 output("plot '-' using 1:2 axes x1y2 with impulses ls 1"); 570 output("plot '-' using 1:2 axes x1y2 with impulses ls 1");
536 for (var i = 0; i < execution_pauses.length; i++) { 571 for (var i = 0; i < execution_pauses.length; i++) {
537 var pause = execution_pauses[i]; 572 var pause = execution_pauses[i];
538 output(pause.end + " " + pause.duration()); 573 output(pause.end + " " + pause.duration());
539 obj_index++; 574 obj_index++;
540 } 575 }
541 output("e"); 576 output("e");
542 return obj_index; 577 return obj_index;
543 }; 578 };
544 } 579 }
OLDNEW
« no previous file with comments | « src/log.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698