<!DOCTYPE html>
<!--
Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/tracing/base/range.html">
<link rel="import" href="/tracing/base/unit.html">
<link rel="import" href="/tracing/metrics/metric_registry.html">
<link rel="import" href="/tracing/metrics/v8/utils.html">
<link rel="import" href="/tracing/value/histogram.html">

<script>
'use strict';

tr.exportTo('tr.metrics.v8', function() {
  // The time window size for mutator utilization computation.
  // It is equal to the duration of one frame corresponding to 60 FPS rendering.
  var TARGET_FPS = 60;
  var MS_PER_SECOND = 1000;
  var WINDOW_SIZE_MS = MS_PER_SECOND / TARGET_FPS;

  function gcMetric(values, model) {
    addDurationOfTopEvents(values, model);
    addTotalDurationOfTopEvents(values, model);
    addDurationOfSubEvents(values, model);
    addIdleTimesOfTopEvents(values, model);
    addTotalIdleTimesOfTopEvents(values, model);
    addPercentageInV8ExecuteOfTopEvents(values, model);
    addTotalPercentageInV8Execute(values, model);
    addV8ExecuteMutatorUtilization(values, model);
  }

  tr.metrics.MetricRegistry.register(gcMetric);

  var timeDurationInMs_smallerIsBetter =
      tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;
  var percentage_biggerIsBetter =
      tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;
  var percentage_smallerIsBetter =
      tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;

  // 0.1 steps from 0 to 20 since it is the most common range.
  // Exponentially increasing steps from 20 to 200.
  var CUSTOM_BOUNDARIES = tr.v.HistogramBinBoundaries.createLinear(0, 20, 200)
    .addExponentialBins(200, 100);

  function createNumericForTopEventTime(name) {
    var n = new tr.v.Histogram(name,
        timeDurationInMs_smallerIsBetter, CUSTOM_BOUNDARIES);
    n.customizeSummaryOptions({
        avg: true,
        count: true,
        max: true,
        min: false,
        std: true,
        sum: true,
        percentile: [0.90]});
    return n;
  }

  function createNumericForSubEventTime(name) {
    var n = new tr.v.Histogram(name,
        timeDurationInMs_smallerIsBetter, CUSTOM_BOUNDARIES);
    n.customizeSummaryOptions({
        avg: true,
        count: false,
        max: true,
        min: false,
        std: false,
        sum: false,
        percentile: [0.90]
    });
    return n;
  }

  function createNumericForIdleTime(name) {
    var n = new tr.v.Histogram(name,
        timeDurationInMs_smallerIsBetter, CUSTOM_BOUNDARIES);
    n.customizeSummaryOptions({
        avg: true,
        count: false,
        max: true,
        min: false,
        std: false,
        sum: true,
        percentile: []
    });
    return n;
  }

  function createPercentage(name, numerator, denominator, unit) {
    var hist = new tr.v.Histogram(name, unit);
    if (denominator === 0)
      hist.addSample(0);
    else
      hist.addSample(numerator / denominator);
    hist.customizeSummaryOptions({
        avg: true,
        count: false,
        max: false,
        min: false,
        std: false,
        sum: false,
        percentile: []
      });
    return hist;
  }

  function isNotForcedTopGarbageCollectionEvent(event) {
    // We exclude garbage collection events forced by benchmark runner,
    // because they cannot happen in real world.
    return tr.metrics.v8.utils.isTopGarbageCollectionEvent(event) &&
           !tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);
  }

  function isNotForcedSubGarbageCollectionEvent(event) {
    // We exclude garbage collection events forced by benchmark runner,
    // because they cannot happen in real world.
    return tr.metrics.v8.utils.isSubGarbageCollectionEvent(event) &&
           !tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);
  }

  /**
   * Example output:
   * - v8-gc-full-mark-compactor.
   */
  function addDurationOfTopEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      tr.metrics.v8.utils.topGarbageCollectionEventName,
      function(name, events) {
        var cpuDuration = createNumericForTopEventTime(name);
        events.forEach(function(event) {
          cpuDuration.addSample(event.cpuDuration);
        });
        values.addHistogram(cpuDuration);
      }
    );
  }

  /**
   * Example output:
   * - v8-gc-total
   */
  function addTotalDurationOfTopEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      event => 'v8-gc-total',
      function(name, events) {
        var cpuDuration = createNumericForTopEventTime(name);
        events.forEach(function(event) {
          cpuDuration.addSample(event.cpuDuration);
        });
        values.addHistogram(cpuDuration);
      }
    );
  }

  /**
   * Example output:
   * - v8-gc-full-mark-compactor-evacuate.
   */
  function addDurationOfSubEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedSubGarbageCollectionEvent,
      tr.metrics.v8.utils.subGarbageCollectionEventName,
      function(name, events) {
        var cpuDuration = createNumericForSubEventTime(name);
        events.forEach(function(event) {
          cpuDuration.addSample(event.cpuDuration);
        });
        values.addHistogram(cpuDuration);
      }
    );
  }

  /**
   * Example output:
   * - v8-gc-full-mark-compactor_idle_deadline_overrun,
   * - v8-gc-full-mark-compactor_outside_idle,
   * - v8-gc-full-mark-compactor_percentage_idle.
   */
  function addIdleTimesOfTopEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      tr.metrics.v8.utils.topGarbageCollectionEventName,
      function(name, events) {
        addIdleTimes(values, model, name, events);
      }
    );
  }

  /**
   * Example output:
   * - v8-gc-total_idle_deadline_overrun,
   * - v8-gc-total_outside_idle,
   * - v8-gc-total_percentage_idle.
   */
  function addTotalIdleTimesOfTopEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      event => 'v8-gc-total',
      function(name, events) {
        addIdleTimes(values, model, name, events);
      }
    );
  }

  function addIdleTimes(values, model, name, events) {
    var cpuDuration = createNumericForIdleTime();
    var insideIdle = createNumericForIdleTime();
    var outsideIdle = createNumericForIdleTime(name + '_outside_idle');
    var idleDeadlineOverrun = createNumericForIdleTime(
        name + '_idle_deadline_overrun');
    events.forEach(function(event) {
      var idleTask = tr.metrics.v8.utils.findParent(
          event, tr.metrics.v8.utils.isIdleTask);
      var inside = 0;
      var overrun = 0;
      if (idleTask) {
        var allottedTime = idleTask['args']['allotted_time_ms'];
        if (event.duration > allottedTime) {
          overrun = event.duration - allottedTime;
          // Don't count time over the deadline as being inside idle time.
          // Since the deadline should be relative to wall clock we
          // compare allotted_time_ms with wall duration instead of thread
          // duration, and then assume the thread duration was inside idle
          // for the same percentage of time.
          inside = event.cpuDuration * allottedTime / event.duration;
        } else {
          inside = event.cpuDuration;
        }
      }
      cpuDuration.addSample(event.cpuDuration);
      insideIdle.addSample(inside);
      outsideIdle.addSample(event.cpuDuration - inside);
      idleDeadlineOverrun.addSample(overrun);
    });
    values.addHistogram(idleDeadlineOverrun);
    values.addHistogram(outsideIdle);
    var percentage = createPercentage(name + '_percentage_idle', insideIdle.sum,
                                      cpuDuration.sum,
                                      percentage_biggerIsBetter);
    values.addHistogram(percentage);
  }


  /**
   * Example output:
   * - v8-gc-full-mark-compactor_percentage_in_v8_execute.
   */
  function addPercentageInV8ExecuteOfTopEvents(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      tr.metrics.v8.utils.topGarbageCollectionEventName,
      function(name, events) {
        addPercentageInV8Execute(values, model, name, events);
      }
    );
  }

  /**
   * Example output:
   * - v8-gc-total_percentage_in_v8_execute.
   */
  function addTotalPercentageInV8Execute(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
      isNotForcedTopGarbageCollectionEvent,
      event => 'v8-gc-total',
      function(name, events) {
        addPercentageInV8Execute(values, model, name, events);
      }
    );
  }

  function addPercentageInV8Execute(values, model, name, events) {
    var cpuDurationInV8Execute = 0;
    var cpuDurationTotal = 0;
    events.forEach(function(event) {
      var v8Execute = tr.metrics.v8.utils.findParent(
          event, tr.metrics.v8.utils.isV8ExecuteEvent);
      if (v8Execute) {
        cpuDurationInV8Execute += event.cpuDuration;
      }
      cpuDurationTotal += event.cpuDuration;
    });
    var percentage = createPercentage(
        name + '_percentage_in_v8_execute', cpuDurationInV8Execute,
        cpuDurationTotal, percentage_smallerIsBetter);
    values.addHistogram(percentage);
  }

  function addV8ExecuteMutatorUtilization(values, model) {
    tr.metrics.v8.utils.groupAndProcessEvents(model,
        tr.metrics.v8.utils.isTopV8ExecuteEvent,
        event => 'v8-execute',
        function(name, events) {
          events.sort((a, b) => a.start - b.start);
          var time = 0;
          var pauses = [];
          // Glue together the v8.execute events and adjust the GC pause
          // times accordingly.
          for (var topEvent of events) {
            for (var e of topEvent.enumerateAllDescendents()) {
              if (isNotForcedTopGarbageCollectionEvent(e)) {
                pauses.push({ start: e.start - topEvent.start + time,
                              end: e.end - topEvent.start + time });
              }
            }
            time += topEvent.duration;
          }
          // Now we have one big v8.execute interval from 0 to |time| and
          // a list of GC pauses.
          var mutatorUtilization = tr.metrics.v8.utils.mutatorUtilization(
              0, time, WINDOW_SIZE_MS, pauses);
          [0.90, 0.95, 0.99].forEach(function(percent) {
            var hist = new tr.v.Histogram(
                'v8-execute-mutator-utilization_pct_0' + percent * 100,
                percentage_biggerIsBetter);
            hist.addSample(mutatorUtilization.percentile(1.0 - percent));
            values.addHistogram(hist);
          });
          var hist = new tr.v.Histogram(
              'v8-execute-mutator-utilization_min', percentage_biggerIsBetter);
          hist.addSample(mutatorUtilization.min);
          values.addHistogram(hist);
        }
    );
  }

  return {
    gcMetric: gcMetric,
    WINDOW_SIZE_MS: WINDOW_SIZE_MS // For testing purposes only.
  };
});
</script>
