Chromium Code Reviews| 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..f131c6e4fd170daa579456840a57e6d737d5ffd7 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,106 @@ 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, |
| + makeKeyUniqueAndSet, |
|
benjhayden
2017/09/15 17:30:46
It looks like this doesn't need to be exported.
yuzuchan
2017/09/19 07:56:26
Done.
|
| + skipDumpsThatDoNotIntersectRange |
|
benjhayden
2017/09/15 17:30:46
It looks like this doesn't need to be exported.
yuzuchan
2017/09/19 07:56:26
Done.
|
| }; |
| }); |
| </script> |