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_MEMORY_AVG_ALLOC_OPS = END_KEY++; |
| 132 var KEY_MEMORY_AVG_FREE_OPS = END_KEY++; |
| 133 var KEY_MEMORY_AVG_NET_BYTES = END_KEY++; |
| 134 var KEY_MEMORY_MAX_ALLOCATED_BYTES = END_KEY++; |
| 135 var KEY_MEMORY_ALLOC_OPS = END_KEY++; |
| 136 var KEY_MEMORY_FREE_OPS = END_KEY++; |
| 137 var KEY_MEMORY_ALLOCATED_BYTES = END_KEY++; |
| 138 var KEY_MEMORY_FREED_BYTES = END_KEY++; |
| 139 var KEY_MEMORY_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_MEMORY_AVG_ALLOC_OPS] = { |
| 475 name: 'Avg Allocations', |
| 476 cellAlignment: 'right', |
| 477 sortDescending: true, |
| 478 textPrinter: formatNumberAsText, |
| 479 aggregator: AvgAggregator.create(KEY_MEMORY_ALLOC_OPS, KEY_COUNT), |
| 480 }; |
| 481 |
| 482 KEY_PROPERTIES[KEY_MEMORY_AVG_FREE_OPS] = { |
| 483 name: 'Avg Frees', |
| 484 cellAlignment: 'right', |
| 485 sortDescending: true, |
| 486 textPrinter: formatNumberAsText, |
| 487 aggregator: AvgAggregator.create(KEY_MEMORY_FREE_OPS, KEY_COUNT), |
| 488 }; |
| 489 |
| 490 KEY_PROPERTIES[KEY_MEMORY_AVG_NET_BYTES] = { |
| 491 name: 'Avg Net Bytes', |
| 492 cellAlignment: 'right', |
| 493 sortDescending: true, |
| 494 textPrinter: formatNumberAsText, |
| 495 aggregator: AvgDiffAggregator.create(KEY_MEMORY_ALLOCATED_BYTES, |
| 496 KEY_MEMORY_FREED_BYTES, KEY_COUNT), |
| 497 }; |
| 498 |
| 499 KEY_PROPERTIES[KEY_MEMORY_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_MEMORY_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_MEMORY_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_MEMORY_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_MEMORY_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_MEMORY_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_MEMORY_ALLOC_OPS, |
| 627 KEY_MEMORY_FREE_OPS, |
| 628 KEY_MEMORY_ALLOCATED_BYTES, |
| 629 KEY_MEMORY_FREED_BYTES, |
| 630 KEY_MEMORY_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_MEMORY_AVG_ALLOC_OPS] = e[KEY_MEMORY_ALLOC_OPS] / e[KEY_COUNT]; |
| 980 e[KEY_MEMORY_AVG_FREE_OPS] = e[KEY_MEMORY_FREE_OPS] / e[KEY_COUNT]; |
| 981 e[KEY_MEMORY_AVG_NET_BYTES] = |
| 982 (e[KEY_MEMORY_ALLOCATED_BYTES] - e[KEY_MEMORY_FREED_BYTES]) / |
| 983 e[KEY_COUNT]; |
| 984 } |
828 } | 985 } |
829 | 986 |
830 /** | 987 /** |
831 * Creates and initializes an aggregator object for each key in |columns|. | 988 * Creates and initializes an aggregator object for each key in |columns|. |
832 * Returns an array whose keys are values from |columns|, and whose | 989 * Returns an array whose keys are values from |columns|, and whose |
833 * values are Aggregator instances. | 990 * values are Aggregator instances. |
834 */ | 991 */ |
835 function initializeAggregates(columns) { | 992 function initializeAggregates(columns) { |
836 var aggregates = []; | 993 var aggregates = []; |
837 | 994 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 * time), it is found by subtracting. | 1118 * time), it is found by subtracting. |
962 * | 1119 * |
963 * Rows in data1 and data2 are expected to use the same scheme for the keys. | 1120 * 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]. | 1121 * In other words, data1[k] is considered the analagous row to data2[k]. |
965 */ | 1122 */ |
966 function subtractSnapshots(data1, data2, columnsToExclude) { | 1123 function subtractSnapshots(data1, data2, columnsToExclude) { |
967 // These columns are computed from the other columns. We won't bother | 1124 // These columns are computed from the other columns. We won't bother |
968 // diffing/aggregating these, but rather will derive them again from the | 1125 // diffing/aggregating these, but rather will derive them again from the |
969 // final row. | 1126 // final row. |
970 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME]; | 1127 var COMPUTED_AGGREGATE_KEYS = [KEY_AVG_QUEUE_TIME, KEY_AVG_RUN_TIME]; |
| 1128 if (loadTimeData.getBoolean('enableMemoryTaskProfiler')) { |
| 1129 COMPUTED_AGGREGATE_KEYS = COMPUTED_AGGREGATE_KEYS.concat([ |
| 1130 KEY_MEMORY_AVG_ALLOC_OPS, |
| 1131 KEY_MEMORY_AVG_FREE_OPS, |
| 1132 KEY_MEMORY_AVG_NET_BYTES]); |
| 1133 } |
971 | 1134 |
972 // These are the keys which determine row equality. Since we are not doing | 1135 // 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 | 1136 // any merging yet at this point, it is simply the list of all identity |
974 // columns. | 1137 // columns. |
975 var identityKeys = IDENTITY_KEYS.slice(0); | 1138 var identityKeys = IDENTITY_KEYS.slice(0); |
976 deleteValuesFromArray(identityKeys, columnsToExclude); | 1139 deleteValuesFromArray(identityKeys, columnsToExclude); |
977 | 1140 |
978 // The columns to compute via aggregation is everything else. | 1141 // The columns to compute via aggregation is everything else. |
979 var aggregateKeys = ALL_KEYS.slice(0); | 1142 var aggregateKeys = ALL_KEYS.slice(0); |
980 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); | 1143 deleteValuesFromArray(aggregateKeys, IDENTITY_KEYS); |
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1909 checkbox.checked = true; | 2072 checkbox.checked = true; |
1910 checkbox.__time = getTimeMillis(); | 2073 checkbox.__time = getTimeMillis(); |
1911 this.updateSnapshotCheckboxStyling_(); | 2074 this.updateSnapshotCheckboxStyling_(); |
1912 } | 2075 } |
1913 }, | 2076 }, |
1914 | 2077 |
1915 updateSnapshotCheckboxStyling_: function() { | 2078 updateSnapshotCheckboxStyling_: function() { |
1916 for (var i = 0; i < this.snapshots_.length; ++i) { | 2079 for (var i = 0; i < this.snapshots_.length; ++i) { |
1917 var checkbox = this.getSnapshotCheckbox_(i); | 2080 var checkbox = this.getSnapshotCheckbox_(i); |
1918 checkbox.parentNode.parentNode.className = | 2081 checkbox.parentNode.parentNode.className = |
1919 checkbox.checked ? 'selected_snapshot' : ''; | 2082 checkbox.checked ? 'selected-snapshot' : ''; |
1920 } | 2083 } |
1921 }, | 2084 }, |
1922 | 2085 |
1923 onSnapshotCheckboxChanged_: function(event) { | 2086 onSnapshotCheckboxChanged_: function(event) { |
1924 // Keep track of when we clicked this box (for when we need to uncheck | 2087 // Keep track of when we clicked this box (for when we need to uncheck |
1925 // older boxes). | 2088 // older boxes). |
1926 event.target.__time = getTimeMillis(); | 2089 event.target.__time = getTimeMillis(); |
1927 | 2090 |
1928 // Find all the checked boxes. Either 1 or 2 can be checked. If a third | 2091 // 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 | 2092 // 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); | 2366 groupKey.push(entry); |
2204 } | 2367 } |
2205 | 2368 |
2206 return JSON.stringify(groupKey); | 2369 return JSON.stringify(groupKey); |
2207 }; | 2370 }; |
2208 }, | 2371 }, |
2209 }; | 2372 }; |
2210 | 2373 |
2211 return MainView; | 2374 return MainView; |
2212 })(); | 2375 })(); |
OLD | NEW |