| Index: tracing/tracing/metrics/system_health/utils.html
|
| diff --git a/tracing/tracing/metrics/system_health/utils.html b/tracing/tracing/metrics/system_health/utils.html
|
| index fa60f7ea1506e4e519821018b6607b6e3ce92012..445fe3308ac6dc560b2c499d183fe4557e257e34 100644
|
| --- a/tracing/tracing/metrics/system_health/utils.html
|
| +++ b/tracing/tracing/metrics/system_health/utils.html
|
| @@ -4,6 +4,7 @@ Copyright (c) 2015 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/extras/chrome/chrome_processes.html">
|
| <link rel="import" href="/tracing/model/user_model/user_expectation.html">
|
|
|
| <script>
|
| @@ -35,9 +36,104 @@ tr.exportTo('tr.metrics.sh', function() {
|
| return filteredExpectations;
|
| }
|
|
|
| + /**
|
| + * Splits the global memory dumps in |model| by browser name.
|
| + *
|
| + * @param {!tr.Model} model The trace model from which the global dumps
|
| + * should be extracted.
|
| + * @param {!tr.b.math.Range=} opt_rangeOfInterest If provided, global memory
|
| + * dumps that do not inclusively intersect the range will be skipped.
|
| + * @return {!Map<string, !Array<!tr.model.GlobalMemoryDump>} A map from
|
| + * browser names to the associated global memory dumps.
|
| + */
|
| + function splitGlobalDumpsByBrowserName(model, opt_rangeOfInterest) {
|
| + const chromeModelHelper =
|
| + model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);
|
| + const browserNameToGlobalDumps = new Map();
|
| + const globalDumpToBrowserHelper = new WeakMap();
|
| +
|
| + // 1. For each browser process in the model, add its global memory dumps to
|
| + // |browserNameToGlobalDumps|. |chromeModelHelper| can be undefined if
|
| + // it fails to find any browser, renderer or GPU process (see
|
| + // tr.model.helpers.ChromeModelHelper.supportsModel).
|
| +
|
| + if (chromeModelHelper) {
|
| + chromeModelHelper.browserHelpers.forEach(function(helper) {
|
| + // Retrieve the associated global memory dumps and check that they
|
| + // haven't been classified as belonging to another browser process.
|
| + const globalDumps = skipDumpsThatDoNotIntersectRange(
|
| + helper.process.memoryDumps.map(d => d.globalMemoryDump),
|
| + opt_rangeOfInterest);
|
| + globalDumps.forEach(function(globalDump) {
|
| + const existingHelper = globalDumpToBrowserHelper.get(globalDump);
|
| + if (existingHelper !== undefined) {
|
| + throw new Error('Memory dump ID clash across multiple browsers ' +
|
| + 'with PIDs: ' + existingHelper.pid + ' and ' + helper.pid);
|
| + }
|
| + globalDumpToBrowserHelper.set(globalDump, helper);
|
| + });
|
| +
|
| + makeKeyUniqueAndSet(browserNameToGlobalDumps,
|
| + tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName),
|
| + globalDumps);
|
| + });
|
| + }
|
| +
|
| + // 2. If any global memory dump does not have any associated browser
|
| + // process for some reason, associate it with an 'unknown_browser' browser
|
| + // so that we don't lose the data.
|
| +
|
| + const unclassifiedGlobalDumps = skipDumpsThatDoNotIntersectRange(
|
| + model.globalMemoryDumps.filter(g => !globalDumpToBrowserHelper.has(g)),
|
| + opt_rangeOfInterest);
|
| + if (unclassifiedGlobalDumps.length > 0) {
|
| + makeKeyUniqueAndSet(
|
| + browserNameToGlobalDumps, 'unknown_browser', unclassifiedGlobalDumps);
|
| + }
|
| +
|
| + return browserNameToGlobalDumps;
|
| + }
|
| +
|
| + /**
|
| + * Function for adding entries with duplicate keys to a map without
|
| + * overriding existing entries.
|
| + *
|
| + * This is achieved by appending numeric indices (2, 3, 4, ...) to duplicate
|
| + * keys. Example:
|
| + *
|
| + * const map = new Map();
|
| + * // map = Map {}.
|
| + *
|
| + * makeKeyUniqueAndSet(map, 'key', 'a');
|
| + * // map = Map {"key" => "a"}.
|
| + *
|
| + * makeKeyUniqueAndSet(map, 'key', 'b');
|
| + * // map = Map {"key" => "a", "key2" => "b"}.
|
| + * ^^^^
|
| + * makeKeyUniqueAndSet(map, 'key', 'c');
|
| + * // map = Map {"key" => "a", "key2" => "b", "key3" => "c"}.
|
| + * ^^^^ ^^^^
|
| + */
|
| + function makeKeyUniqueAndSet(map, key, value) {
|
| + let uniqueKey = key;
|
| + let nextIndex = 2;
|
| + while (map.has(uniqueKey)) {
|
| + uniqueKey = key + nextIndex;
|
| + nextIndex++;
|
| + }
|
| + map.set(uniqueKey, value);
|
| + }
|
| +
|
| + function skipDumpsThatDoNotIntersectRange(dumps, opt_range) {
|
| + if (!opt_range) return dumps;
|
| + return dumps.filter(d => opt_range.intersectsExplicitRangeInclusive(
|
| + d.start, d.end));
|
| + }
|
| +
|
| return {
|
| perceptualBlend,
|
| filterExpectationsByRange,
|
| + splitGlobalDumpsByBrowserName
|
| };
|
| });
|
| </script>
|
|
|