| Index: tools/profviz/composer.js
|
| diff --git a/tools/profviz/composer.js b/tools/profviz/composer.js
|
| index 2f7817928c591f2cd3545bddf21c9018fc20d41a..73d5b36ce277c7f70c8f15381fce1d226eff2308 100644
|
| --- a/tools/profviz/composer.js
|
| +++ b/tools/profviz/composer.js
|
| @@ -41,7 +41,9 @@ function PlotScriptComposer(kResX, kResY) {
|
| var kStackFrameWidth = 0.1; // Width of the lower stack frame lines.
|
| var kGapWidth = 0.05; // Gap between stack frame lines.
|
|
|
| - var kY1Offset = 10; // Offset for stack frame vs. event lines.
|
| + var kY1Offset = 11; // Offset for stack frame vs. event lines.
|
| + var kDeoptRow = 7; // Row displaying deopts.
|
| + var kMaxDeoptLength = 4; // Draw size of the largest deopt.
|
| var kPauseLabelPadding = 5; // Padding for pause time labels.
|
| var kNumPauseLabels = 7; // Number of biggest pauses to label.
|
| var kCodeKindLabelPadding = 100; // Padding for code kind labels.
|
| @@ -52,6 +54,9 @@ function PlotScriptComposer(kResX, kResY) {
|
| var kNumThreads = 2; // Number of threads.
|
| var kExecutionThreadId = 0; // ID of main thread.
|
|
|
| + // Init values.
|
| + var num_timer_event = kY1Offset + 0.5;
|
| +
|
| // Data structures.
|
| function TimerEvent(label, color, pause, thread_id) {
|
| assert(thread_id >= 0 && thread_id < kNumThreads, "invalid thread id");
|
| @@ -72,9 +77,13 @@ function PlotScriptComposer(kResX, kResY) {
|
| }
|
|
|
| function Range(start, end) {
|
| - // Everthing here are in milliseconds.
|
| - this.start = start;
|
| - this.end = end;
|
| + this.start = start; // In milliseconds.
|
| + this.end = end; // In milliseconds.
|
| + }
|
| +
|
| + function Deopt(time, size) {
|
| + this.time = time; // In milliseconds.
|
| + this.size = size; // In bytes.
|
| }
|
|
|
| Range.prototype.duration = function() { return this.end - this.start; }
|
| @@ -83,9 +92,6 @@ function PlotScriptComposer(kResX, kResY) {
|
| this.tick = tick;
|
| }
|
|
|
| - // Init values.
|
| - var num_timer_event = kY1Offset + 0.5;
|
| -
|
| var TimerEvents = {
|
| 'V8.Execute':
|
| new TimerEvent("execution", "#000000", false, 0),
|
| @@ -127,6 +133,7 @@ function PlotScriptComposer(kResX, kResY) {
|
|
|
| var code_map = new CodeMap();
|
| var execution_pauses = [];
|
| + var deopts = [];
|
| var event_stack = [];
|
| var last_time_stamp = [];
|
| for (var i = 0; i < kNumThreads; i++) {
|
| @@ -312,6 +319,10 @@ function PlotScriptComposer(kResX, kResY) {
|
| code_map.deleteCode(address);
|
| };
|
|
|
| + var processCodeDeoptEvent = function(time, size) {
|
| + deopts.push(new Deopt(time, size));
|
| + }
|
| +
|
| var processSharedLibrary = function(name, start, end) {
|
| var code_entry = new CodeMap.CodeEntry(end - start, name);
|
| code_entry.kind = -3; // External code kind.
|
| @@ -352,6 +363,8 @@ function PlotScriptComposer(kResX, kResY) {
|
| processor: processCodeMoveEvent },
|
| 'code-delete': { parsers: [parseInt],
|
| processor: processCodeDeleteEvent },
|
| + 'code-deopt': { parsers: [parseTimeStamp, parseInt],
|
| + processor: processCodeDeoptEvent },
|
| 'tick': { parsers: [parseInt, parseInt, parseTimeStamp,
|
| null, null, parseInt, 'var-args'],
|
| processor: processTickEvent }
|
| @@ -422,18 +435,27 @@ function PlotScriptComposer(kResX, kResY) {
|
| output("set style fill pattern 2 bo 1");
|
| output("set style rect fs solid 1 noborder");
|
| output("set style line 1 lt 1 lw 1 lc rgb \"#000000\"");
|
| + output("set style line 2 lt 1 lw 1 lc rgb \"#9944CC\"");
|
| output("set xtics out nomirror");
|
| output("unset key");
|
|
|
| - function DrawBar(row, color, start, end, width) {
|
| + function DrawBarBase(color, start, end, top, bottom) {
|
| obj_index++;
|
| command = "set object " + obj_index + " rect";
|
| - command += " from " + start + ", " + (row - width);
|
| - command += " to " + end + ", " + (row + width);
|
| + command += " from " + start + ", " + top;
|
| + command += " to " + end + ", " + bottom;
|
| command += " fc rgb \"" + color + "\"";
|
| output(command);
|
| }
|
|
|
| + function DrawBar(row, color, start, end, width) {
|
| + DrawBarBase(color, start, end, row + width, row - width);
|
| + }
|
| +
|
| + function DrawHalfBar(row, color, start, end, width) {
|
| + DrawBarBase(color, start, end, row, row - width);
|
| + }
|
| +
|
| var percentages = {};
|
| var total = 0;
|
| for (var name in TimerEvents) {
|
| @@ -446,6 +468,17 @@ function PlotScriptComposer(kResX, kResY) {
|
| percentages[name] = (sum / (range_end - range_start) * 100).toFixed(1);
|
| }
|
|
|
| + // Plot deopts.
|
| + deopts.sort(function(a, b) { return b.size - a.size; });
|
| + var max_deopt_size = deopts.length > 0 ? deopts[0].size : Infinity;
|
| +
|
| + for (var i = 0; i < deopts.length; i++) {
|
| + var deopt = deopts[i];
|
| + DrawHalfBar(kDeoptRow, "#9944CC", deopt.time,
|
| + deopt.time + 10 * pause_tolerance,
|
| + deopt.size / max_deopt_size * kMaxDeoptLength);
|
| + }
|
| +
|
| // Name Y-axis.
|
| var ytics = [];
|
| for (name in TimerEvents) {
|
| @@ -458,6 +491,8 @@ function PlotScriptComposer(kResX, kResY) {
|
| ytics.push('"top ' + kStackFrames + ' js stack frames"' + ' ' +
|
| (kY1Offset - 2));
|
| ytics.push('"pause times" 0');
|
| + ytics.push('"max deopt size: ' + (max_deopt_size / 1024).toFixed(1) +
|
| + ' kB" ' + kDeoptRow);
|
| output("set ytics out nomirror (" + ytics.join(', ') + ")");
|
|
|
| // Plot timeline.
|
|
|