| <!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.blink', function() { |
| // Maps the Blink GC events in timeline to telemetry friendly names. |
| var BLINK_GC_EVENTS = { |
| 'BlinkGCMarking': 'blink-gc-marking', |
| 'ThreadState::completeSweep': 'blink-gc-complete-sweep', |
| 'ThreadState::performIdleLazySweep': 'blink-gc-idle-lazy-sweep' |
| }; |
| |
| function isBlinkGarbageCollectionEvent(event) { |
| return event.title in BLINK_GC_EVENTS; |
| } |
| |
| function blinkGarbageCollectionEventName(event) { |
| return BLINK_GC_EVENTS[event.title]; |
| } |
| |
| function blinkGcMetric(values, model) { |
| addDurationOfTopEvents(values, model); |
| addTotalDurationOfTopEvents(values, model); |
| addIdleTimesOfTopEvents(values, model); |
| addTotalIdleTimesOfTopEvents(values, model); |
| } |
| |
| tr.metrics.MetricRegistry.register(blinkGcMetric); |
| |
| var timeDurationInMs_smallerIsBetter = |
| tr.b.Unit.byName.timeDurationInMs_smallerIsBetter; |
| var percentage_biggerIsBetter = |
| tr.b.Unit.byName.normalizedPercentage_biggerIsBetter; |
| |
| // 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 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) { |
| var histogram = new tr.v.Histogram(name, percentage_biggerIsBetter); |
| if (denominator === 0) |
| histogram.addSample(0); |
| else |
| histogram.addSample(numerator / denominator); |
| return histogram; |
| } |
| |
| /** |
| * Example output: |
| * - blink-gc-marking. |
| */ |
| function addDurationOfTopEvents(values, model) { |
| tr.metrics.v8.utils.groupAndProcessEvents(model, |
| isBlinkGarbageCollectionEvent, |
| blinkGarbageCollectionEventName, |
| function(name, events) { |
| var cpuDuration = createNumericForTopEventTime(name); |
| events.forEach(function(event) { |
| cpuDuration.addSample(event.cpuDuration); |
| }); |
| values.addHistogram(cpuDuration); |
| } |
| ); |
| } |
| |
| /** |
| * Example output: |
| * - blink-gc-total |
| */ |
| function addTotalDurationOfTopEvents(values, model) { |
| tr.metrics.v8.utils.groupAndProcessEvents(model, |
| isBlinkGarbageCollectionEvent, |
| event => 'blink-gc-total', |
| function(name, events) { |
| var cpuDuration = createNumericForTopEventTime(name); |
| events.forEach(function(event) { |
| cpuDuration.addSample(event.cpuDuration); |
| }); |
| values.addHistogram(cpuDuration); |
| } |
| ); |
| } |
| |
| /** |
| * Example output: |
| * - blink-gc-marking_idle_deadline_overrun, |
| * - blink-gc-marking_outside_idle, |
| * - blink-gc-marking_percentage_idle. |
| */ |
| function addIdleTimesOfTopEvents(values, model) { |
| tr.metrics.v8.utils.groupAndProcessEvents(model, |
| isBlinkGarbageCollectionEvent, |
| blinkGarbageCollectionEventName, |
| function(name, events) { |
| addIdleTimes(values, model, name, events); |
| } |
| ); |
| } |
| |
| /** |
| * Example output: |
| * - blink-gc-total_idle_deadline_overrun, |
| * - blink-gc-total_outside_idle, |
| * - blink-gc-total_percentage_idle. |
| */ |
| function addTotalIdleTimesOfTopEvents(values, model) { |
| tr.metrics.v8.utils.groupAndProcessEvents(model, |
| isBlinkGarbageCollectionEvent, |
| event => 'blink-gc-total', |
| function(name, events) { |
| addIdleTimes(values, model, name, events); |
| } |
| ); |
| } |
| |
| function addIdleTimes(values, model, name, events) { |
| var cpuDuration = createNumericForIdleTime(name + '_cpu'); |
| var insideIdle = createNumericForIdleTime(name + '_inside_idle'); |
| 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); |
| values.addHistogram(percentage); |
| } |
| |
| return { |
| blinkGcMetric: blinkGcMetric |
| }; |
| }); |
| </script> |