Chromium Code Reviews| Index: tracing/tracing/metrics/blink/leak_detection_metric.html |
| diff --git a/tracing/tracing/metrics/blink/leak_detection_metric.html b/tracing/tracing/metrics/blink/leak_detection_metric.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..85103974e248bab85b464554b2fc88c4886eb926 |
| --- /dev/null |
| +++ b/tracing/tracing/metrics/blink/leak_detection_metric.html |
| @@ -0,0 +1,110 @@ |
| +<!DOCTYPE html> |
| +<!-- |
| +Copyright 2017 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/unit.html"> |
| +<link rel="import" href="/tracing/metrics/metric_registry.html"> |
| +<link rel="import" href="/tracing/metrics/system_health/utils.html"> |
| +<link rel="import" href="/tracing/value/histogram.html"> |
| + |
| +<script> |
| +'use strict'; |
| + |
| +tr.exportTo('tr.metrics.blink', function() { |
| + function leakDetectionMetric(histograms, model) { |
| + const pids = extractRendererPids(model); |
| + |
| + const chromeDumps = tr.metrics.sh |
| + .splitGlobalDumpsByBrowserName(model, undefined).get('chrome'); |
| + |
| + let sumCounter = {}; |
|
benjhayden
2017/09/14 19:18:50
Please use an ES6 Map instead:
let sumCounter = ne
yuzuchan
2017/09/15 08:32:25
Done.
|
| + // Add up counters for all the renderer processes. |
| + pids.forEach(function(pid) { |
|
benjhayden
2017/09/14 19:18:50
Please use for..of loops instead of forEach and fo
yuzuchan
2017/09/15 08:32:24
Done.
|
| + if (Object.keys(sumCounter).length === 0) { |
|
benjhayden
2017/09/14 19:18:50
Is this just merging the maps, or is there somethi
yuzuchan
2017/09/15 08:32:24
Right! Thanks for teaching me the simple way.
Done
|
| + sumCounter = countLeakedBlinkObjects(chromeDumps, pid); |
| + } else { |
| + const counterForAnotherRenderer = |
| + countLeakedBlinkObjects(chromeDumps, pid); |
| + for (const key in counters) { |
| + sumCounter[key] += counterForAnotherRenderer[key]; |
| + } |
| + } |
| + }); |
| + |
| + for (const key in sumCounter) { |
| + const histogram = createNumericForBlinkObjectCount(key); |
|
benjhayden
2017/09/14 19:18:50
Please use the existing helper function histograms
yuzuchan
2017/09/15 08:32:25
Done.
|
| + histogram.addSample(sumCounter[key]); |
| + histograms.addHistogram(histogram); |
| + } |
| + } |
| + |
| + tr.metrics.MetricRegistry.register(leakDetectionMetric); |
| + |
| + function extractRendererPids(model) { |
|
benjhayden
2017/09/14 19:18:50
This looks short enough that you can inline it int
yuzuchan
2017/09/15 08:32:25
Done.
|
| + const modelHelper = model.getOrCreateHelper( |
| + tr.model.helpers.ChromeModelHelper); |
| + if (Object.keys(modelHelper).length === 0) { |
| + throw new Error('Chrome is not present.'); |
| + } |
| + const rendererHelpers = modelHelper.rendererHelpers; |
| + if (Object.keys(rendererHelpers).length === 0) { |
| + throw new Error('Renderer process is not present.'); |
| + } |
| + return Object.keys(rendererHelpers); |
| + } |
| + |
| + const count_smallerIsBetter = tr.b.Unit.byName.count_smallerIsBetter; |
| + |
| + function createNumericForBlinkObjectCount(name) { |
| + const n = new tr.v.Histogram(name, count_smallerIsBetter); |
|
benjhayden
2017/09/14 19:18:50
Please prepend the name with something like 'leak:
yuzuchan
2017/09/15 08:32:24
Done.
|
| + n.customizeSummaryOptions({ |
| + avg: false, |
| + count: true, |
| + max: false, |
| + min: false, |
| + std: false, |
| + sum: true, |
| + percentile: [] |
| + }); |
| + return n; |
| + } |
| + |
| + function countLeakedBlinkObjects(dumps, pid) { |
| + if (dumps === undefined || dumps.length < 2) { |
| + throw new Error('Memory dump did not happen twice, and thus leak could' + |
|
keishi
2017/09/14 09:40:46
nit: Maybe something more concise like "Expected a
yuzuchan
2017/09/15 08:32:24
Done.
|
| + ' not be calculated.'); |
| + } |
| + const firstCounter = countBlinkObjects(dumps[0], pid); |
| + const lastCounter = countBlinkObjects(dumps[dumps.length - 1], pid); |
| + const diffCounter = {}; |
|
benjhayden
2017/09/14 19:18:50
Please use an ES6 Map instead.
yuzuchan
2017/09/15 08:32:24
Done.
|
| + for (const key in lastCounter) { |
| + diffCounter[key] = lastCounter[key] - firstCounter[key]; |
| + } |
| + return diffCounter; |
| + } |
| + |
| + function countBlinkObjects(dump, pid) { |
| + const counter = {}; |
| + const processesMemoryDumps = dump.processMemoryDumps; |
| + if (pid in processesMemoryDumps) { |
| + const blinkObjectsDump = processesMemoryDumps[pid].memoryAllocatorDumps |
| + .find(isBlinkObjects); |
|
benjhayden
2017/09/14 19:18:50
Please use an arrow function instead:
find(dump =>
yuzuchan
2017/09/15 08:32:24
Done.
|
| + blinkObjectsDump.children.forEach(function(v) { |
| + counter[v.name] = v.numerics.object_count.value; |
| + }); |
| + } |
| + return counter; |
| + } |
| + |
| + function isBlinkObjects(memoryDump) { |
| + return memoryDump.fullName === 'blink_objects'; |
| + } |
| + |
| + return { |
| + leakDetectionMetric, |
| + }; |
| +}); |
| +</script> |