Index: tracing/tracing/metrics/blink/gc_metric.html |
diff --git a/tracing/tracing/metrics/blink/gc_metric.html b/tracing/tracing/metrics/blink/gc_metric.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..71fc823d6a355b008af4193be36afa06e56f6c77 |
--- /dev/null |
+++ b/tracing/tracing/metrics/blink/gc_metric.html |
@@ -0,0 +1,198 @@ |
+<!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> |