Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var g_browserBridge; | 5 var g_browserBridge; |
| 6 var g_mainView; | 6 var g_mainView; |
| 7 | 7 |
| 8 // TODO(eroman): The handling of "max" across snapshots is not correct. | 8 // TODO(eroman): The handling of "max" across snapshots is not correct. |
| 9 // For starters the browser needs to be aware to generate new maximums. | 9 // For starters the browser needs to be aware to generate new maximums. |
| 10 // Secondly, we need to take into account the "max" of intermediary snapshots, | 10 // Secondly, we need to take into account the "max" of intermediary snapshots, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 var BEGIN_KEY = 1; // Start at 1 rather than 0 to simplify sorting code. | 120 var BEGIN_KEY = 1; // Start at 1 rather than 0 to simplify sorting code. |
| 121 var END_KEY = BEGIN_KEY; | 121 var END_KEY = BEGIN_KEY; |
| 122 | 122 |
| 123 var KEY_COUNT = END_KEY++; | 123 var KEY_COUNT = END_KEY++; |
| 124 var KEY_RUN_TIME = END_KEY++; | 124 var KEY_RUN_TIME = END_KEY++; |
| 125 var KEY_AVG_RUN_TIME = END_KEY++; | 125 var KEY_AVG_RUN_TIME = END_KEY++; |
| 126 var KEY_MAX_RUN_TIME = END_KEY++; | 126 var KEY_MAX_RUN_TIME = END_KEY++; |
| 127 var KEY_QUEUE_TIME = END_KEY++; | 127 var KEY_QUEUE_TIME = END_KEY++; |
| 128 var KEY_AVG_QUEUE_TIME = END_KEY++; | 128 var KEY_AVG_QUEUE_TIME = END_KEY++; |
| 129 var KEY_MAX_QUEUE_TIME = END_KEY++; | 129 var KEY_MAX_QUEUE_TIME = END_KEY++; |
| 130 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { | |
| 131 var KEY_AVG_ALLOC_OPS = END_KEY++; | |
|
eroman
2016/12/02 17:13:37
I suggest giving these a common prefix, like "KEY_
Sigurður Ásgeirsson
2016/12/02 18:58:09
Ah, good idea!
| |
| 132 var KEY_AVG_FREE_OPS = END_KEY++; | |
| 133 var KEY_AVG_NET_BYTES = END_KEY++; | |
| 134 var KEY_MAX_ALLOCATED_BYTES = END_KEY++; | |
| 135 var KEY_ALLOC_OPS = END_KEY++; | |
| 136 var KEY_FREE_OPS = END_KEY++; | |
| 137 var KEY_ALLOCATED_BYTES = END_KEY++; | |
| 138 var KEY_FREED_BYTES = END_KEY++; | |
| 139 var KEY_ALLOC_OVERHEAD_BYTES = END_KEY++; | |
| 140 } | |
| 130 var KEY_BIRTH_THREAD = END_KEY++; | 141 var KEY_BIRTH_THREAD = END_KEY++; |
| 131 var KEY_DEATH_THREAD = END_KEY++; | 142 var KEY_DEATH_THREAD = END_KEY++; |
| 132 var KEY_PROCESS_TYPE = END_KEY++; | 143 var KEY_PROCESS_TYPE = END_KEY++; |
| 133 var KEY_PROCESS_ID = END_KEY++; | 144 var KEY_PROCESS_ID = END_KEY++; |
| 134 var KEY_FUNCTION_NAME = END_KEY++; | 145 var KEY_FUNCTION_NAME = END_KEY++; |
| 135 var KEY_SOURCE_LOCATION = END_KEY++; | 146 var KEY_SOURCE_LOCATION = END_KEY++; |
| 136 var KEY_FILE_NAME = END_KEY++; | 147 var KEY_FILE_NAME = END_KEY++; |
| 137 var KEY_LINE_NUMBER = END_KEY++; | 148 var KEY_LINE_NUMBER = END_KEY++; |
| 138 | 149 |
| 139 var NUM_KEYS = END_KEY - BEGIN_KEY; | 150 var NUM_KEYS = END_KEY - BEGIN_KEY; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 return { | 247 return { |
| 237 create: function(key) { | 248 create: function(key) { |
| 238 return new Aggregator(numeratorKey, divisorKey); | 249 return new Aggregator(numeratorKey, divisorKey); |
| 239 }, | 250 }, |
| 240 }; | 251 }; |
| 241 } | 252 } |
| 242 }; | 253 }; |
| 243 })(); | 254 })(); |
| 244 | 255 |
| 245 /** | 256 /** |
| 257 * This aggregator computes an average by summing the difference of two | |
| 258 * numeric fields, summing a count, and then dividing the totals. | |
| 259 */ | |
| 260 var AvgDiffAggregator = (function() { | |
| 261 function Aggregator(numeratorPosKey, numeratorNegKey, divisorKey) { | |
| 262 this.numeratorPosKey_ = numeratorPosKey; | |
| 263 this.numeratorNegKey_ = numeratorNegKey; | |
| 264 this.divisorKey_ = divisorKey; | |
| 265 | |
| 266 this.numeratorSum_ = 0; | |
| 267 this.divisorSum_ = 0; | |
| 268 } | |
| 269 | |
| 270 Aggregator.prototype = { | |
| 271 consume: function(e) { | |
| 272 this.numeratorSum_ += | |
| 273 e[this.numeratorPosKey_] - e[this.numeratorNegKey_]; | |
| 274 this.divisorSum_ += e[this.divisorKey_]; | |
| 275 }, | |
| 276 | |
| 277 getValue: function() { | |
| 278 return this.numeratorSum_ / this.divisorSum_; | |
| 279 }, | |
| 280 | |
| 281 getValueAsText: function() { | |
| 282 return formatNumberAsText(this.getValue()); | |
| 283 }, | |
| 284 }; | |
| 285 | |
| 286 return { | |
| 287 create: function(numeratorPosKey, numeratorNegKey, divisorKey) { | |
| 288 return { | |
| 289 create: function(key) { | |
| 290 return new Aggregator(numeratorPosKey, numeratorNegKey, divisorKey); | |
| 291 }, | |
| 292 }; | |
| 293 } | |
| 294 }; | |
| 295 })(); | |
| 296 | |
| 297 /** | |
| 246 * This aggregator finds the maximum for a numeric field. | 298 * This aggregator finds the maximum for a numeric field. |
| 247 */ | 299 */ |
| 248 var MaxAggregator = (function() { | 300 var MaxAggregator = (function() { |
| 249 function Aggregator(key) { | 301 function Aggregator(key) { |
| 250 this.key_ = key; | 302 this.key_ = key; |
| 251 this.max_ = -Infinity; | 303 this.max_ = -Infinity; |
| 252 } | 304 } |
| 253 | 305 |
| 254 Aggregator.prototype = { | 306 Aggregator.prototype = { |
| 255 consume: function(e) { | 307 consume: function(e) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 KEY_PROPERTIES[KEY_RUN_TIME] = { | 463 KEY_PROPERTIES[KEY_RUN_TIME] = { |
| 412 name: 'Total run time', | 464 name: 'Total run time', |
| 413 cellAlignment: 'right', | 465 cellAlignment: 'right', |
| 414 sortDescending: true, | 466 sortDescending: true, |
| 415 textPrinter: formatNumberAsText, | 467 textPrinter: formatNumberAsText, |
| 416 inputJsonKey: 'death_data.run_ms', | 468 inputJsonKey: 'death_data.run_ms', |
| 417 aggregator: SumAggregator, | 469 aggregator: SumAggregator, |
| 418 diff: diffFuncForCount, | 470 diff: diffFuncForCount, |
| 419 }; | 471 }; |
| 420 | 472 |
| 473 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { | |
| 474 KEY_PROPERTIES[KEY_AVG_ALLOC_OPS] = { | |
| 475 name: 'Avg Allocations', | |
| 476 cellAlignment: 'right', | |
| 477 sortDescending: true, | |
| 478 textPrinter: formatNumberAsText, | |
| 479 aggregator: AvgAggregator.create(KEY_ALLOC_OPS, KEY_COUNT), | |
| 480 }; | |
| 481 | |
| 482 KEY_PROPERTIES[KEY_AVG_FREE_OPS] = { | |
| 483 name: 'Avg Frees', | |
| 484 cellAlignment: 'right', | |
| 485 sortDescending: true, | |
| 486 textPrinter: formatNumberAsText, | |
| 487 aggregator: AvgAggregator.create(KEY_FREE_OPS, KEY_COUNT), | |
| 488 }; | |
| 489 | |
| 490 KEY_PROPERTIES[KEY_AVG_NET_BYTES] = { | |
| 491 name: 'Avg Net Bytes', | |
| 492 cellAlignment: 'right', | |
| 493 sortDescending: true, | |
| 494 textPrinter: formatNumberAsText, | |
| 495 aggregator: AvgDiffAggregator.create(KEY_ALLOCATED_BYTES, | |
| 496 KEY_FREED_BYTES, KEY_COUNT), | |
| 497 }; | |
| 498 | |
| 499 KEY_PROPERTIES[KEY_ALLOC_OPS] = { | |
| 500 name: 'Allocation count', | |
| 501 cellAlignment: 'right', | |
| 502 sortDescending: true, | |
| 503 textPrinter: formatNumberAsText, | |
| 504 inputJsonKey: 'death_data.alloc_ops', | |
| 505 aggregator: SumAggregator, | |
| 506 diff: diffFuncForCount, | |
| 507 }; | |
| 508 | |
| 509 KEY_PROPERTIES[KEY_FREE_OPS] = { | |
| 510 name: 'Free Count', | |
| 511 cellAlignment: 'right', | |
| 512 sortDescending: true, | |
| 513 textPrinter: formatNumberAsText, | |
| 514 inputJsonKey: 'death_data.free_ops', | |
| 515 aggregator: SumAggregator, | |
| 516 diff: diffFuncForCount, | |
| 517 }; | |
| 518 | |
| 519 KEY_PROPERTIES[KEY_ALLOCATED_BYTES] = { | |
| 520 name: 'Allocated bytes', | |
| 521 cellAlignment: 'right', | |
| 522 sortDescending: true, | |
| 523 textPrinter: formatNumberAsText, | |
| 524 inputJsonKey: 'death_data.allocated_bytes', | |
| 525 aggregator: SumAggregator, | |
| 526 diff: diffFuncForCount, | |
| 527 }; | |
| 528 | |
| 529 KEY_PROPERTIES[KEY_FREED_BYTES] = { | |
| 530 name: 'Freed bytes', | |
| 531 cellAlignment: 'right', | |
| 532 sortDescending: true, | |
| 533 textPrinter: formatNumberAsText, | |
| 534 inputJsonKey: 'death_data.freed_bytes', | |
| 535 aggregator: SumAggregator, | |
| 536 diff: diffFuncForCount, | |
| 537 }; | |
| 538 | |
| 539 KEY_PROPERTIES[KEY_ALLOC_OVERHEAD_BYTES] = { | |
| 540 name: 'Overhead bytes', | |
| 541 cellAlignment: 'right', | |
| 542 sortDescending: true, | |
| 543 textPrinter: formatNumberAsText, | |
| 544 inputJsonKey: 'death_data.alloc_overhead_bytes', | |
| 545 aggregator: SumAggregator, | |
| 546 diff: diffFuncForCount, | |
| 547 }; | |
| 548 | |
| 549 KEY_PROPERTIES[KEY_MAX_ALLOCATED_BYTES] = { | |
| 550 name: 'Max allocated (outstanding) bytes', | |
| 551 cellAlignment: 'right', | |
| 552 sortDescending: true, | |
| 553 textPrinter: formatNumberAsText, | |
| 554 inputJsonKey: 'death_data.max_allocated_bytes', | |
| 555 aggregator: MaxAggregator, | |
| 556 diff: diffFuncForMax, | |
| 557 }; | |
| 558 } | |
| 559 | |
| 421 KEY_PROPERTIES[KEY_AVG_RUN_TIME] = { | 560 KEY_PROPERTIES[KEY_AVG_RUN_TIME] = { |
| 422 name: 'Avg run time', | 561 name: 'Avg run time', |
| 423 cellAlignment: 'right', | 562 cellAlignment: 'right', |
| 424 sortDescending: true, | 563 sortDescending: true, |
| 425 textPrinter: formatNumberAsText, | 564 textPrinter: formatNumberAsText, |
| 426 aggregator: AvgAggregator.create(KEY_RUN_TIME, KEY_COUNT), | 565 aggregator: AvgAggregator.create(KEY_RUN_TIME, KEY_COUNT), |
| 427 }; | 566 }; |
| 428 | 567 |
| 429 KEY_PROPERTIES[KEY_MAX_RUN_TIME] = { | 568 KEY_PROPERTIES[KEY_MAX_RUN_TIME] = { |
| 430 name: 'Max run time', | 569 name: 'Max run time', |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 /** | 614 /** |
| 476 * List of keys for those properties which we want to initially omit | 615 * List of keys for those properties which we want to initially omit |
| 477 * from the table. (They can be re-enabled by clicking [Edit columns]). | 616 * from the table. (They can be re-enabled by clicking [Edit columns]). |
| 478 */ | 617 */ |
| 479 var INITIALLY_HIDDEN_KEYS = [ | 618 var INITIALLY_HIDDEN_KEYS = [ |
| 480 KEY_FILE_NAME, | 619 KEY_FILE_NAME, |
| 481 KEY_LINE_NUMBER, | 620 KEY_LINE_NUMBER, |
| 482 KEY_QUEUE_TIME, | 621 KEY_QUEUE_TIME, |
| 483 ]; | 622 ]; |
| 484 | 623 |
| 624 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { | |
| 625 INITIALLY_HIDDEN_KEYS = INITIALLY_HIDDEN_KEYS.concat([ | |
| 626 KEY_ALLOC_OPS, | |
| 627 KEY_FREE_OPS, | |
| 628 KEY_ALLOCATED_BYTES, | |
| 629 KEY_FREED_BYTES, | |
| 630 KEY_ALLOC_OVERHEAD_BYTES, | |
| 631 ]); | |
| 632 } | |
| 633 | |
| 485 /** | 634 /** |
| 486 * The ordered list of grouping choices to expose in the "Group by" | 635 * The ordered list of grouping choices to expose in the "Group by" |
| 487 * dropdowns. We don't include the numeric properties, since they | 636 * dropdowns. We don't include the numeric properties, since they |
| 488 * leads to awkward bucketing. | 637 * leads to awkward bucketing. |
| 489 */ | 638 */ |
| 490 var GROUPING_DROPDOWN_CHOICES = [ | 639 var GROUPING_DROPDOWN_CHOICES = [ |
| 491 KEY_PROCESS_TYPE, | 640 KEY_PROCESS_TYPE, |
| 492 KEY_PROCESS_ID, | 641 KEY_PROCESS_ID, |
| 493 KEY_BIRTH_THREAD, | 642 KEY_BIRTH_THREAD, |
| 494 KEY_DEATH_THREAD, | 643 KEY_DEATH_THREAD, |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 818 * Adds new derived properties to row. Mutates the provided dictionary |e|. | 967 * Adds new derived properties to row. Mutates the provided dictionary |e|. |
| 819 */ | 968 */ |
| 820 function augmentDataRow(e) { | 969 function augmentDataRow(e) { |
| 821 computeDataRowAverages(e); | 970 computeDataRowAverages(e); |
| 822 e[KEY_SOURCE_LOCATION] = e[KEY_FILE_NAME] + ' [' + e[KEY_LINE_NUMBER] + ']'; | 971 e[KEY_SOURCE_LOCATION] = e[KEY_FILE_NAME] + ' [' + e[KEY_LINE_NUMBER] + ']'; |
| 823 } | 972 } |
| 824 | 973 |
| 825 function computeDataRowAverages(e) { | 974 function computeDataRowAverages(e) { |
| 826 e[KEY_AVG_QUEUE_TIME] = e[KEY_QUEUE_TIME] / e[KEY_COUNT]; | 975 e[KEY_AVG_QUEUE_TIME] = e[KEY_QUEUE_TIME] / e[KEY_COUNT]; |
| 827 e[KEY_AVG_RUN_TIME] = e[KEY_RUN_TIME] / e[KEY_COUNT]; | 976 e[KEY_AVG_RUN_TIME] = e[KEY_RUN_TIME] / e[KEY_COUNT]; |
| 977 | |
| 978 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { | |
| 979 e[KEY_AVG_ALLOC_OPS] = e[KEY_ALLOC_OPS] / e[KEY_COUNT]; | |
| 980 e[KEY_AVG_FREE_OPS] = e[KEY_FREE_OPS] / e[KEY_COUNT]; | |
| 981 e[KEY_AVG_NET_BYTES] = | |
| 982 (e[KEY_ALLOCATED_BYTES] - e[KEY_FREED_BYTES]) / e[KEY_COUNT]; | |
| 983 } | |
| 828 } | 984 } |
| 829 | 985 |
| 830 /** | 986 /** |
| 831 * Creates and initializes an aggregator object for each key in |columns|. | 987 * Creates and initializes an aggregator object for each key in |columns|. |
| 832 * Returns an array whose keys are values from |columns|, and whose | 988 * Returns an array whose keys are values from |columns|, and whose |
| 833 * values are Aggregator instances. | 989 * values are Aggregator instances. |
| 834 */ | 990 */ |
| 835 function initializeAggregates(columns) { | 991 function initializeAggregates(columns) { |
| 836 var aggregates = []; | 992 var aggregates = []; |
| 837 | 993 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 961 * time), it is found by subtracting. | 1117 * time), it is found by subtracting. |
| 962 * | 1118 * |
| 963 * Rows in data1 and data2 are expected to use the same scheme for the keys. | 1119 * Rows in data1 and data2 are expected to use the same scheme for the keys. |
| 964 * In other words, data1[k] is considered the analagous row to data2[k]. | 1120 * In other words, data1[k] is considered the analagous row to data2[k]. |
| 965 */ | 1121 */ |
| 966 function subtractSnapshots(data1, data2, columnsToExclude) { | 1122 function subtractSnapshots(data1, data2, columnsToExclude) { |
| 967 // These columns are computed from the other columns. We won't bother | 1123 // These columns are computed from the other columns. We won't bother |
| 968 // diffing/aggregating these, but rather will derive them again from the | 1124 // diffing/aggregating these, but rather will derive them again from the |
| 969 // final row. | 1125 // final row. |
| 970 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME]; | 1126 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME]; |
| 1127 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { | |
| 1128 COMPUTED_AGGREGATE_KEYS = COMPUTED_AGGREGATE_KEYS.concat([ | |
| 1129 KEY_AVG_ALLOC_OPS, KEY_AVG_FREE_OPS, KEY_AVG_NET_BYTES]); | |
| 1130 } | |
| 971 | 1131 |
| 972 // These are the keys which determine row equality. Since we are not doing | 1132 // These are the keys which determine row equality. Since we are not doing |
| 973 // any merging yet at this point, it is simply the list of all identity | 1133 // any merging yet at this point, it is simply the list of all identity |
| 974 // columns. | 1134 // columns. |
| 975 var identityKeys = IDENTITY_KEYS.slice(0); | 1135 var identityKeys = IDENTITY_KEYS.slice(0); |
| 976 deleteValuesFromArray(identityKeys, columnsToExclude); | 1136 deleteValuesFromArray(identityKeys, columnsToExclude); |
| 977 | 1137 |
| 978 // The columns to compute via aggregation is everything else. | 1138 // The columns to compute via aggregation is everything else. |
| 979 var aggregateKeys = ALL_KEYS.slice(0); | 1139 var aggregateKeys = ALL_KEYS.slice(0); |
| 980 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); | 1140 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1909 checkbox.checked = true; | 2069 checkbox.checked = true; |
| 1910 checkbox.__time = getTimeMillis(); | 2070 checkbox.__time = getTimeMillis(); |
| 1911 this.updateSnapshotCheckboxStyling_(); | 2071 this.updateSnapshotCheckboxStyling_(); |
| 1912 } | 2072 } |
| 1913 }, | 2073 }, |
| 1914 | 2074 |
| 1915 updateSnapshotCheckboxStyling_: function() { | 2075 updateSnapshotCheckboxStyling_: function() { |
| 1916 for (var i = 0; i < this.snapshots_.length; ++i) { | 2076 for (var i = 0; i < this.snapshots_.length; ++i) { |
| 1917 var checkbox = this.getSnapshotCheckbox_(i); | 2077 var checkbox = this.getSnapshotCheckbox_(i); |
| 1918 checkbox.parentNode.parentNode.className = | 2078 checkbox.parentNode.parentNode.className = |
| 1919 checkbox.checked ? 'selected_snapshot' : ''; | 2079 checkbox.checked ? 'selected-snapshot' : ''; |
| 1920 } | 2080 } |
| 1921 }, | 2081 }, |
| 1922 | 2082 |
| 1923 onSnapshotCheckboxChanged_: function(event) { | 2083 onSnapshotCheckboxChanged_: function(event) { |
| 1924 // Keep track of when we clicked this box (for when we need to uncheck | 2084 // Keep track of when we clicked this box (for when we need to uncheck |
| 1925 // older boxes). | 2085 // older boxes). |
| 1926 event.target.__time = getTimeMillis(); | 2086 event.target.__time = getTimeMillis(); |
| 1927 | 2087 |
| 1928 // Find all the checked boxes. Either 1 or 2 can be checked. If a third | 2088 // Find all the checked boxes. Either 1 or 2 can be checked. If a third |
| 1929 // was just checked, then uncheck one of the earlier ones so we only have | 2089 // was just checked, then uncheck one of the earlier ones so we only have |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2203 groupKey.push(entry); | 2363 groupKey.push(entry); |
| 2204 } | 2364 } |
| 2205 | 2365 |
| 2206 return JSON.stringify(groupKey); | 2366 return JSON.stringify(groupKey); |
| 2207 }; | 2367 }; |
| 2208 }, | 2368 }, |
| 2209 }; | 2369 }; |
| 2210 | 2370 |
| 2211 return MainView; | 2371 return MainView; |
| 2212 })(); | 2372 })(); |
| OLD | NEW |