| <!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/metrics/metric_registry.html"> |
| <link rel="import" href="/tracing/metrics/v8/utils.html"> |
| <link rel="import" href="/tracing/value/numeric.html"> |
| <link rel="import" href="/tracing/value/unit.html"> |
| <link rel="import" href="/tracing/value/value.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.v.Unit.byName.timeDurationInMs_smallerIsBetter; |
| var percentage_biggerIsBetter = |
| tr.v.Unit.byName.normalizedPercentage_biggerIsBetter; |
| |
| var numericBuilder = new tr.v.NumericBuilder( |
| timeDurationInMs_smallerIsBetter, 0); |
| // 0.1 steps from 0 to 20 since it is the most common range. |
| numericBuilder.addLinearBins(20, 200); |
| // Exponentially increasing steps from 20 to 200. |
| numericBuilder.addExponentialBins(200, 100); |
| |
| function createNumericForTopEventTime() { |
| var n = numericBuilder.build(); |
| n.customizeSummaryOptions({ |
| avg: true, |
| count: true, |
| max: true, |
| min: false, |
| std: true, |
| sum: true, |
| percentile: [0.90]}); |
| return n; |
| } |
| |
| function createNumericForIdleTime() { |
| var n = numericBuilder.build(); |
| n.customizeSummaryOptions({ |
| avg: true, |
| count: false, |
| max: true, |
| min: false, |
| std: false, |
| sum: true, |
| percentile: [] |
| }); |
| return n; |
| } |
| |
| function createPercentage(numerator, denominator) { |
| var percentage = denominator === 0 ? 0 : numerator / denominator * 100; |
| return new tr.v.ScalarNumeric(percentage_biggerIsBetter, percentage); |
| } |
| |
| /** |
| * Example output: |
| * - blink-gc-marking. |
| */ |
| function addDurationOfTopEvents(values, model) { |
| tr.metrics.v8.utils.groupAndProcessEvents(model, |
| isBlinkGarbageCollectionEvent, |
| blinkGarbageCollectionEventName, |
| function(name, events) { |
| var cpuDuration = createNumericForTopEventTime(); |
| events.forEach(function(event) { |
| cpuDuration.add(event.cpuDuration); |
| }); |
| values.addValue(new tr.v.NumericValue(name, 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(); |
| events.forEach(function(event) { |
| cpuDuration.add(event.cpuDuration); |
| }); |
| values.addValue(new tr.v.NumericValue(name, 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(); |
| var insideIdle = createNumericForIdleTime(); |
| var outsideIdle = createNumericForIdleTime(); |
| var idleDeadlineOverrun = createNumericForIdleTime(); |
| 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.add(event.cpuDuration); |
| insideIdle.add(inside); |
| outsideIdle.add(event.cpuDuration - inside); |
| idleDeadlineOverrun.add(overrun); |
| }); |
| values.addValue(new tr.v.NumericValue( |
| name + '_idle_deadline_overrun', |
| idleDeadlineOverrun)); |
| values.addValue(new tr.v.NumericValue( |
| name + '_outside_idle', outsideIdle)); |
| var percentage = createPercentage(insideIdle.sum, |
| cpuDuration.sum); |
| values.addValue(new tr.v.NumericValue( |
| name + '_percentage_idle', percentage)); |
| } |
| |
| return { |
| blinkGcMetric: blinkGcMetric |
| }; |
| }); |
| </script> |