OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2015 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2015 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
| 7 <link rel="import" href="/tracing/extras/chrome/chrome_processes.html"> |
7 <link rel="import" href="/tracing/model/user_model/user_expectation.html"> | 8 <link rel="import" href="/tracing/model/user_model/user_expectation.html"> |
8 | 9 |
9 <script> | 10 <script> |
10 'use strict'; | 11 'use strict'; |
11 | 12 |
12 tr.exportTo('tr.metrics.sh', function() { | 13 tr.exportTo('tr.metrics.sh', function() { |
13 // Returns a weight for this score. | 14 // Returns a weight for this score. |
14 // score should be a number between 0 and 1 inclusive. | 15 // score should be a number between 0 and 1 inclusive. |
15 // This function is expected to be passed to tr.b.math.Statistics.weightedMean | 16 // This function is expected to be passed to tr.b.math.Statistics.weightedMean |
16 // as its weightCallback. | 17 // as its weightCallback. |
(...skipping 11 matching lines...) Expand all Loading... |
28 if (!(ir instanceof tr.model.um.UserExpectation)) return; | 29 if (!(ir instanceof tr.model.um.UserExpectation)) return; |
29 | 30 |
30 if (!opt_range || | 31 if (!opt_range || |
31 opt_range.intersectsExplicitRangeInclusive(ir.start, ir.end)) { | 32 opt_range.intersectsExplicitRangeInclusive(ir.start, ir.end)) { |
32 filteredExpectations.push(ir); | 33 filteredExpectations.push(ir); |
33 } | 34 } |
34 }); | 35 }); |
35 return filteredExpectations; | 36 return filteredExpectations; |
36 } | 37 } |
37 | 38 |
| 39 /** |
| 40 * Splits the global memory dumps in |model| by browser name. |
| 41 * |
| 42 * @param {!tr.Model} model The trace model from which the global dumps |
| 43 * should be extracted. |
| 44 * @param {!tr.b.math.Range=} opt_rangeOfInterest If provided, global memory |
| 45 * dumps that do not inclusively intersect the range will be skipped. |
| 46 * @return {!Map<string, !Array<!tr.model.GlobalMemoryDump>} A map from |
| 47 * browser names to the associated global memory dumps. |
| 48 */ |
| 49 function splitGlobalDumpsByBrowserName(model, opt_rangeOfInterest) { |
| 50 const chromeModelHelper = |
| 51 model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper); |
| 52 const browserNameToGlobalDumps = new Map(); |
| 53 const globalDumpToBrowserHelper = new WeakMap(); |
| 54 |
| 55 // 1. For each browser process in the model, add its global memory dumps to |
| 56 // |browserNameToGlobalDumps|. |chromeModelHelper| can be undefined if |
| 57 // it fails to find any browser, renderer or GPU process (see |
| 58 // tr.model.helpers.ChromeModelHelper.supportsModel). |
| 59 |
| 60 if (chromeModelHelper) { |
| 61 chromeModelHelper.browserHelpers.forEach(function(helper) { |
| 62 // Retrieve the associated global memory dumps and check that they |
| 63 // haven't been classified as belonging to another browser process. |
| 64 const globalDumps = skipDumpsThatDoNotIntersectRange( |
| 65 helper.process.memoryDumps.map(d => d.globalMemoryDump), |
| 66 opt_rangeOfInterest); |
| 67 globalDumps.forEach(function(globalDump) { |
| 68 const existingHelper = globalDumpToBrowserHelper.get(globalDump); |
| 69 if (existingHelper !== undefined) { |
| 70 throw new Error('Memory dump ID clash across multiple browsers ' + |
| 71 'with PIDs: ' + existingHelper.pid + ' and ' + helper.pid); |
| 72 } |
| 73 globalDumpToBrowserHelper.set(globalDump, helper); |
| 74 }); |
| 75 |
| 76 makeKeyUniqueAndSet(browserNameToGlobalDumps, |
| 77 tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName), |
| 78 globalDumps); |
| 79 }); |
| 80 } |
| 81 |
| 82 // 2. If any global memory dump does not have any associated browser |
| 83 // process for some reason, associate it with an 'unknown_browser' browser |
| 84 // so that we don't lose the data. |
| 85 |
| 86 const unclassifiedGlobalDumps = skipDumpsThatDoNotIntersectRange( |
| 87 model.globalMemoryDumps.filter(g => !globalDumpToBrowserHelper.has(g)), |
| 88 opt_rangeOfInterest); |
| 89 if (unclassifiedGlobalDumps.length > 0) { |
| 90 makeKeyUniqueAndSet( |
| 91 browserNameToGlobalDumps, 'unknown_browser', unclassifiedGlobalDumps); |
| 92 } |
| 93 |
| 94 return browserNameToGlobalDumps; |
| 95 } |
| 96 |
| 97 /** |
| 98 * Function for adding entries with duplicate keys to a map without |
| 99 * overriding existing entries. |
| 100 * |
| 101 * This is achieved by appending numeric indices (2, 3, 4, ...) to duplicate |
| 102 * keys. Example: |
| 103 * |
| 104 * const map = new Map(); |
| 105 * // map = Map {}. |
| 106 * |
| 107 * makeKeyUniqueAndSet(map, 'key', 'a'); |
| 108 * // map = Map {"key" => "a"}. |
| 109 * |
| 110 * makeKeyUniqueAndSet(map, 'key', 'b'); |
| 111 * // map = Map {"key" => "a", "key2" => "b"}. |
| 112 * ^^^^ |
| 113 * makeKeyUniqueAndSet(map, 'key', 'c'); |
| 114 * // map = Map {"key" => "a", "key2" => "b", "key3" => "c"}. |
| 115 * ^^^^ ^^^^ |
| 116 */ |
| 117 function makeKeyUniqueAndSet(map, key, value) { |
| 118 let uniqueKey = key; |
| 119 let nextIndex = 2; |
| 120 while (map.has(uniqueKey)) { |
| 121 uniqueKey = key + nextIndex; |
| 122 nextIndex++; |
| 123 } |
| 124 map.set(uniqueKey, value); |
| 125 } |
| 126 |
| 127 function skipDumpsThatDoNotIntersectRange(dumps, opt_range) { |
| 128 if (!opt_range) return dumps; |
| 129 return dumps.filter(d => opt_range.intersectsExplicitRangeInclusive( |
| 130 d.start, d.end)); |
| 131 } |
| 132 |
38 return { | 133 return { |
39 perceptualBlend, | 134 perceptualBlend, |
40 filterExpectationsByRange, | 135 filterExpectationsByRange, |
| 136 splitGlobalDumpsByBrowserName, |
| 137 makeKeyUniqueAndSet, |
| 138 skipDumpsThatDoNotIntersectRange |
41 }; | 139 }; |
42 }); | 140 }); |
43 </script> | 141 </script> |
OLD | NEW |