| 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.
 | 
| 
 |