Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of cpu_profiler; | 5 part of cpu_profiler; |
| 6 | 6 |
| 7 class CodeCallTreeNode { | 7 class CodeCallTreeNode { |
| 8 final ProfileCode profileCode; | 8 final ProfileCode profileCode; |
| 9 final int count; | 9 final int count; |
| 10 double get percentage => _percentage; | 10 double get percentage => _percentage; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 } | 34 } |
| 35 if (inclusive) { | 35 if (inclusive) { |
| 36 node._percentage = parentPercentage * (node.count / parentCount); | 36 node._percentage = parentPercentage * (node.count / parentCount); |
| 37 } else { | 37 } else { |
| 38 node._percentage = (node.count / parentCount); | 38 node._percentage = (node.count / parentCount); |
| 39 } | 39 } |
| 40 for (var child in node.children) { | 40 for (var child in node.children) { |
| 41 _setCodePercentage(node, child); | 41 _setCodePercentage(node, child); |
| 42 } | 42 } |
| 43 } | 43 } |
| 44 | |
| 45 _markCodeCallsInner(CodeCallTreeNode caller, | |
| 46 CodeCallTreeNode callee) { | |
| 47 if (caller != null) { | |
| 48 caller.profileCode._noteCallee(callee.profileCode, callee.count); | |
| 49 callee.profileCode._noteCaller(caller.profileCode, callee.count); | |
| 50 } | |
| 51 | |
| 52 for (var child in callee.children) { | |
| 53 _markCodeCallsInner(callee, child); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 _markCodeCalls() { | |
|
turnidge
2015/04/07 21:24:31
What does "marking" mean here? Is there another n
Cutch
2015/04/14 21:45:15
Went with _recordCallerAndCallees.
The class is n
| |
| 58 for (var child in root.children) { | |
| 59 _markCodeCallsInner(null, child); | |
| 60 } | |
| 61 } | |
| 44 } | 62 } |
| 45 | 63 |
| 46 class FunctionCallTreeNodeCode { | 64 class FunctionCallTreeNodeCode { |
| 47 final ProfileCode code; | 65 final ProfileCode code; |
| 48 final int ticks; | 66 final int ticks; |
| 49 FunctionCallTreeNodeCode(this.code, this.ticks); | 67 FunctionCallTreeNodeCode(this.code, this.ticks); |
| 50 } | 68 } |
| 51 | 69 |
| 52 class FunctionCallTreeNode { | 70 class FunctionCallTreeNode { |
| 53 final ProfileFunction profileFunction; | 71 final ProfileFunction profileFunction; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 } | 140 } |
| 123 if (hasUnoptimizedCode()) { | 141 if (hasUnoptimizedCode()) { |
| 124 attributes.add('unoptimized'); | 142 attributes.add('unoptimized'); |
| 125 } | 143 } |
| 126 if (isInlined()) { | 144 if (isInlined()) { |
| 127 attributes.add('inlined'); | 145 attributes.add('inlined'); |
| 128 } | 146 } |
| 129 } | 147 } |
| 130 } | 148 } |
| 131 | 149 |
| 150 typedef bool FunctionCallTreeNodeFilter(FunctionCallTreeNode node); | |
| 151 | |
| 152 class _FilteredTreeBuilder { | |
|
turnidge
2015/04/07 21:24:31
Can you make some of the functions in this class p
Cutch
2015/04/14 21:45:15
Done.
| |
| 153 final FunctionCallTreeNodeFilter filter; | |
| 154 final FunctionCallTree tree; | |
| 155 final FunctionCallTree filtered; | |
| 156 final List currentPath = []; | |
| 157 | |
| 158 _FilteredTreeBuilder(this.filter, FunctionCallTree tree) | |
| 159 : tree = tree, | |
| 160 filtered = | |
| 161 new FunctionCallTree( | |
| 162 tree.inclusive, | |
| 163 new FunctionCallTreeNode( | |
| 164 tree.root.profileFunction, | |
| 165 tree.root.count)); | |
| 166 | |
| 167 FunctionCallTreeNode findFunctionInChildren(FunctionCallTreeNode current, | |
| 168 FunctionCallTreeNode needle) { | |
| 169 for (var child in current.children) { | |
| 170 if (child.profileFunction == needle.profileFunction) { | |
| 171 return child; | |
| 172 } | |
| 173 } | |
| 174 return null; | |
| 175 } | |
| 176 | |
| 177 FunctionCallTreeNode addCurrentPath() { | |
| 178 FunctionCallTreeNode current = filtered.root; | |
| 179 // Tree root is always the first element of the current path. | |
| 180 assert(tree.root == currentPath[0]); | |
| 181 // Assert that tree and filtered are different. | |
| 182 assert(tree.root != current); | |
| 183 for (var i = 1; i < currentPath.length; i++) { | |
| 184 var toAdd = currentPath[i]; | |
| 185 var child = findFunctionInChildren(current, toAdd); | |
| 186 if (child == null) { | |
| 187 child = new FunctionCallTreeNode(toAdd.profileFunction, toAdd.count); | |
| 188 current.children.add(child); | |
| 189 } | |
| 190 current = child; | |
| 191 assert(current.count == toAdd.count); | |
| 192 } | |
| 193 return current; | |
| 194 } | |
| 195 | |
| 196 appendTree(FunctionCallTreeNode current, FunctionCallTreeNode next) { | |
| 197 if (next == null) { | |
| 198 return; | |
| 199 } | |
| 200 var child = findFunctionInChildren(current, next); | |
| 201 if (child == null) { | |
| 202 child = new FunctionCallTreeNode(next.profileFunction, next.count); | |
| 203 current.children.add(child); | |
| 204 } | |
| 205 current = child; | |
| 206 for (var nextChild in next.children) { | |
| 207 appendTree(current, nextChild); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 addTree(FunctionCallTreeNode child) { | |
| 212 var current = addCurrentPath(); | |
| 213 appendTree(current, child); | |
| 214 } | |
| 215 | |
| 216 descend(FunctionCallTreeNode current) { | |
| 217 if (current == null) { | |
| 218 return; | |
| 219 } | |
| 220 currentPath.add(current); | |
| 221 | |
| 222 if (filter(current)) { | |
| 223 // Filter matched. | |
| 224 if (current.children.length == 0) { | |
| 225 // Have no children. Add this path. | |
| 226 addTree(null); | |
| 227 } else { | |
| 228 // Add all child trees. | |
| 229 for (var child in current.children) { | |
| 230 addTree(child); | |
| 231 } | |
| 232 } | |
| 233 } else { | |
| 234 // Did not match, descend to each child. | |
| 235 for (var child in current.children) { | |
| 236 descend(child); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 var last = currentPath.removeLast(); | |
| 241 assert(current == last); | |
| 242 } | |
| 243 | |
| 244 build() { | |
| 245 assert(filtered != null); | |
| 246 assert(filter != null); | |
| 247 assert(tree != null); | |
| 248 descend(tree.root); | |
| 249 } | |
| 250 } | |
| 251 | |
| 132 class FunctionCallTree { | 252 class FunctionCallTree { |
| 133 final bool inclusive; | 253 final bool inclusive; |
| 134 final FunctionCallTreeNode root; | 254 final FunctionCallTreeNode root; |
| 135 FunctionCallTree(this.inclusive, this.root) { | 255 FunctionCallTree(this.inclusive, this.root) { |
| 136 _setFunctionPercentage(null, root); | 256 _setFunctionPercentage(null, root); |
| 137 } | 257 } |
| 138 | 258 |
| 259 FunctionCallTree filtered(FunctionCallTreeNodeFilter filter) { | |
| 260 var treeFilter = new _FilteredTreeBuilder(filter, this); | |
| 261 treeFilter.build(); | |
| 262 _setFunctionPercentage(null, treeFilter.filtered.root); | |
| 263 return treeFilter.filtered; | |
| 264 } | |
| 265 | |
| 139 void _setFunctionPercentage(FunctionCallTreeNode parent, | 266 void _setFunctionPercentage(FunctionCallTreeNode parent, |
| 140 FunctionCallTreeNode node) { | 267 FunctionCallTreeNode node) { |
| 141 assert(node != null); | 268 assert(node != null); |
| 142 var parentPercentage = 1.0; | 269 var parentPercentage = 1.0; |
| 143 var parentCount = node.count; | 270 var parentCount = node.count; |
| 144 if (parent != null) { | 271 if (parent != null) { |
| 145 parentPercentage = parent._percentage; | 272 parentPercentage = parent._percentage; |
| 146 parentCount = parent.count; | 273 parentCount = parent.count; |
| 147 } | 274 } |
| 148 if (inclusive) { | 275 if (inclusive) { |
| 149 node._percentage = parentPercentage * (node.count / parentCount); | 276 node._percentage = parentPercentage * (node.count / parentCount); |
| 150 } else { | 277 } else { |
| 151 node._percentage = (node.count / parentCount); | 278 node._percentage = (node.count / parentCount); |
| 152 } | 279 } |
| 153 for (var child in node.children) { | 280 for (var child in node.children) { |
| 154 _setFunctionPercentage(node, child); | 281 _setFunctionPercentage(node, child); |
| 155 } | 282 } |
| 156 } | 283 } |
| 284 | |
| 285 _markFunctionCallsInner(FunctionCallTreeNode caller, | |
| 286 FunctionCallTreeNode callee) { | |
| 287 if (caller != null) { | |
| 288 caller.profileFunction._noteCallee(callee.profileFunction, callee.count); | |
| 289 callee.profileFunction._noteCaller(caller.profileFunction, callee.count); | |
| 290 } | |
| 291 for (var child in callee.children) { | |
| 292 _markFunctionCallsInner(callee, child); | |
| 293 } | |
| 294 } | |
| 295 | |
| 296 _markFunctionCalls() { | |
| 297 for (var child in root.children) { | |
| 298 _markFunctionCallsInner(null, child); | |
| 299 } | |
| 300 } | |
| 157 } | 301 } |
| 158 | 302 |
| 159 class CodeTick { | 303 class CodeTick { |
| 160 final int exclusiveTicks; | 304 final int exclusiveTicks; |
| 161 final int inclusiveTicks; | 305 final int inclusiveTicks; |
| 162 CodeTick(this.exclusiveTicks, this.inclusiveTicks); | 306 CodeTick(this.exclusiveTicks, this.inclusiveTicks); |
| 163 } | 307 } |
| 164 | 308 |
| 165 class InlineIntervalTick { | 309 class InlineIntervalTick { |
| 166 final int startAddress; | 310 final int startAddress; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 179 double normalizedExclusiveTicks = 0.0; | 323 double normalizedExclusiveTicks = 0.0; |
| 180 double normalizedInclusiveTicks = 0.0; | 324 double normalizedInclusiveTicks = 0.0; |
| 181 final addressTicks = new Map<int, CodeTick>(); | 325 final addressTicks = new Map<int, CodeTick>(); |
| 182 final intervalTicks = new Map<int, InlineIntervalTick>(); | 326 final intervalTicks = new Map<int, InlineIntervalTick>(); |
| 183 String formattedInclusiveTicks = ''; | 327 String formattedInclusiveTicks = ''; |
| 184 String formattedExclusiveTicks = ''; | 328 String formattedExclusiveTicks = ''; |
| 185 String formattedExclusivePercent = ''; | 329 String formattedExclusivePercent = ''; |
| 186 String formattedCpuTime = ''; | 330 String formattedCpuTime = ''; |
| 187 String formattedOnStackTime = ''; | 331 String formattedOnStackTime = ''; |
| 188 final Set<String> attributes = new Set<String>(); | 332 final Set<String> attributes = new Set<String>(); |
| 333 final Map<ProfileCode, int> callers = new Map<ProfileCode, int>(); | |
| 334 final Map<ProfileCode, int> callees = new Map<ProfileCode, int>(); | |
| 189 | 335 |
| 190 void _processTicks(List<String> profileTicks) { | 336 void _processTicks(List<String> profileTicks) { |
| 191 assert(profileTicks != null); | 337 assert(profileTicks != null); |
| 192 assert((profileTicks.length % 3) == 0); | 338 assert((profileTicks.length % 3) == 0); |
| 193 for (var i = 0; i < profileTicks.length; i += 3) { | 339 for (var i = 0; i < profileTicks.length; i += 3) { |
| 194 var address = int.parse(profileTicks[i], radix:16); | 340 var address = int.parse(profileTicks[i], radix:16); |
| 195 var exclusive = int.parse(profileTicks[i + 1]); | 341 var exclusive = int.parse(profileTicks[i + 1]); |
| 196 var inclusive = int.parse(profileTicks[i + 2]); | 342 var inclusive = int.parse(profileTicks[i + 2]); |
| 197 var tick = new CodeTick(exclusive, inclusive); | 343 var tick = new CodeTick(exclusive, inclusive); |
| 198 addressTicks[address] = tick; | 344 addressTicks[address] = tick; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 profile.approximateMillisecondsForCount(inclusiveTicks)); | 401 profile.approximateMillisecondsForCount(inclusiveTicks)); |
| 256 | 402 |
| 257 formattedInclusiveTicks = | 403 formattedInclusiveTicks = |
| 258 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' | 404 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' |
| 259 '($inclusiveTicks)'; | 405 '($inclusiveTicks)'; |
| 260 | 406 |
| 261 formattedExclusiveTicks = | 407 formattedExclusiveTicks = |
| 262 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' | 408 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' |
| 263 '($exclusiveTicks)'; | 409 '($exclusiveTicks)'; |
| 264 } | 410 } |
| 411 | |
| 412 _noteCaller(ProfileCode caller, int count) { | |
|
turnidge
2015/04/07 21:24:31
Maybe _addCaller and _addCallee?
Cutch
2015/04/14 21:45:15
Done.
| |
| 413 var r = callers[caller]; | |
| 414 if (r == null) { | |
| 415 r = 0; | |
| 416 } | |
| 417 callers[caller] = r + count; | |
| 418 } | |
| 419 | |
| 420 _noteCallee(ProfileCode callee, int count) { | |
| 421 var r = callees[callee]; | |
| 422 if (r == null) { | |
| 423 r = 0; | |
| 424 } | |
| 425 callees[callee] = r + count; | |
| 426 } | |
| 265 } | 427 } |
| 266 | 428 |
| 267 class ProfileFunction { | 429 class ProfileFunction { |
| 268 final CpuProfile profile; | 430 final CpuProfile profile; |
| 269 final ServiceFunction function; | 431 final ServiceFunction function; |
| 270 // List of compiled code objects containing this function. | 432 // List of compiled code objects containing this function. |
| 271 final List<ProfileCode> profileCodes = new List<ProfileCode>(); | 433 final List<ProfileCode> profileCodes = new List<ProfileCode>(); |
| 434 final Map<ProfileFunction, int> callers = new Map<ProfileFunction, int>(); | |
| 435 final Map<ProfileFunction, int> callees = new Map<ProfileFunction, int>(); | |
| 436 | |
| 272 // Absolute ticks: | 437 // Absolute ticks: |
| 273 int exclusiveTicks = 0; | 438 int exclusiveTicks = 0; |
| 274 int inclusiveTicks = 0; | 439 int inclusiveTicks = 0; |
| 275 | 440 |
| 276 // Global percentages: | 441 // Global percentages: |
| 277 double normalizedExclusiveTicks = 0.0; | 442 double normalizedExclusiveTicks = 0.0; |
| 278 double normalizedInclusiveTicks = 0.0; | 443 double normalizedInclusiveTicks = 0.0; |
| 279 | 444 |
| 280 String formattedInclusiveTicks = ''; | 445 String formattedInclusiveTicks = ''; |
| 281 String formattedExclusiveTicks = ''; | 446 String formattedExclusiveTicks = ''; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 } else if (function.kind == FunctionKind.kNative) { | 514 } else if (function.kind == FunctionKind.kNative) { |
| 350 attribs.add('native'); | 515 attribs.add('native'); |
| 351 } else if (function.kind.isSynthetic()) { | 516 } else if (function.kind.isSynthetic()) { |
| 352 attribs.add('synthetic'); | 517 attribs.add('synthetic'); |
| 353 } else { | 518 } else { |
| 354 attribs.add('dart'); | 519 attribs.add('dart'); |
| 355 } | 520 } |
| 356 } | 521 } |
| 357 | 522 |
| 358 ProfileFunction.fromMap(this.profile, this.function, Map data) { | 523 ProfileFunction.fromMap(this.profile, this.function, Map data) { |
| 524 function.profile = this; | |
| 359 for (var codeIndex in data['codes']) { | 525 for (var codeIndex in data['codes']) { |
| 360 var profileCode = profile.codes[codeIndex]; | 526 var profileCode = profile.codes[codeIndex]; |
| 361 profileCodes.add(profileCode); | 527 profileCodes.add(profileCode); |
| 362 } | 528 } |
| 363 profileCodes.sort(_sortCodes); | 529 profileCodes.sort(_sortCodes); |
| 364 | 530 |
| 365 if (hasOptimizedCode()) { | 531 if (hasOptimizedCode()) { |
| 366 attributes.add('optimized'); | 532 attributes.add('optimized'); |
| 367 } | 533 } |
| 368 if (hasUnoptimizedCode()) { | 534 if (hasUnoptimizedCode()) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 390 profile.approximateMillisecondsForCount(inclusiveTicks)); | 556 profile.approximateMillisecondsForCount(inclusiveTicks)); |
| 391 | 557 |
| 392 formattedInclusiveTicks = | 558 formattedInclusiveTicks = |
| 393 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' | 559 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' |
| 394 '($inclusiveTicks)'; | 560 '($inclusiveTicks)'; |
| 395 | 561 |
| 396 formattedExclusiveTicks = | 562 formattedExclusiveTicks = |
| 397 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' | 563 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' |
| 398 '($exclusiveTicks)'; | 564 '($exclusiveTicks)'; |
| 399 } | 565 } |
| 566 | |
| 567 _noteCaller(ProfileFunction caller, int count) { | |
| 568 var r = callers[caller]; | |
| 569 if (r == null) { | |
| 570 r = 0; | |
| 571 } | |
| 572 callers[caller] = r + count; | |
| 573 } | |
| 574 | |
| 575 _noteCallee(ProfileFunction callee, int count) { | |
| 576 var r = callees[callee]; | |
| 577 if (r == null) { | |
| 578 r = 0; | |
| 579 } | |
| 580 callees[callee] = r + count; | |
| 581 } | |
| 400 } | 582 } |
| 401 | 583 |
| 402 | 584 |
| 403 class CpuProfile { | 585 class CpuProfile { |
| 404 final double MICROSECONDS_PER_SECOND = 1000000.0; | 586 final double MICROSECONDS_PER_SECOND = 1000000.0; |
| 405 final double displayThreshold = 0.0002; // 0.02%. | 587 final double displayThreshold = 0.0002; // 0.02%. |
| 406 | 588 |
| 407 Isolate isolate; | 589 Isolate isolate; |
| 408 | 590 |
| 409 int sampleCount = 0; | 591 int sampleCount = 0; |
| 410 int samplePeriod = 0; | 592 int samplePeriod = 0; |
| 411 double sampleRate = 0.0; | 593 double sampleRate = 0.0; |
| 412 | 594 |
| 413 int stackDepth = 0; | 595 int stackDepth = 0; |
| 414 | 596 |
| 415 double timeSpan = 0.0; | 597 double timeSpan = 0.0; |
| 416 | 598 |
| 417 final Map<String, List> tries = <String, List>{}; | 599 final Map<String, List> tries = <String, List>{}; |
| 418 final List<ProfileCode> codes = new List<ProfileCode>(); | 600 final List<ProfileCode> codes = new List<ProfileCode>(); |
| 601 bool _markedCodeCalls = false; | |
| 419 final List<ProfileFunction> functions = new List<ProfileFunction>(); | 602 final List<ProfileFunction> functions = new List<ProfileFunction>(); |
| 603 bool _markedFunctionCalls = false; | |
| 420 | 604 |
| 421 CodeCallTree loadCodeTree(String name) { | 605 CodeCallTree loadCodeTree(String name) { |
| 422 if (name == 'inclusive') { | 606 if (name == 'inclusive') { |
| 423 return _loadCodeTree(true, tries['inclusiveCodeTrie']); | 607 return _loadCodeTree(true, tries['inclusiveCodeTrie']); |
| 424 } else { | 608 } else { |
| 425 return _loadCodeTree(false, tries['exclusiveCodeTrie']); | 609 return _loadCodeTree(false, tries['exclusiveCodeTrie']); |
| 426 } | 610 } |
| 427 } | 611 } |
| 428 | 612 |
| 429 FunctionCallTree loadFunctionTree(String name) { | 613 FunctionCallTree loadFunctionTree(String name) { |
| 430 if (name == 'inclusive') { | 614 if (name == 'inclusive') { |
| 431 return _loadFunctionTree(true, tries['inclusiveFunctionTrie']); | 615 return _loadFunctionTree(true, tries['inclusiveFunctionTrie']); |
| 432 } else { | 616 } else { |
| 433 return _loadFunctionTree(false, tries['exclusiveFunctionTrie']); | 617 return _loadFunctionTree(false, tries['exclusiveFunctionTrie']); |
| 434 } | 618 } |
| 435 } | 619 } |
| 436 | 620 |
| 437 void clear() { | 621 markCodeCalls() { |
| 622 if (_markedCodeCalls) { | |
| 623 return; | |
| 624 } | |
| 625 _markedCodeCalls = true; | |
| 626 var tree = loadCodeTree('inclusive'); | |
| 627 tree._markCodeCalls(); | |
| 628 } | |
| 629 | |
| 630 markFunctionCalls() { | |
| 631 if (_markedFunctionCalls) { | |
| 632 return; | |
| 633 } | |
| 634 _markedFunctionCalls = true; | |
| 635 var tree = loadFunctionTree('inclusive'); | |
| 636 tree._markFunctionCalls(); | |
| 637 } | |
| 638 | |
| 639 clear() { | |
| 438 sampleCount = 0; | 640 sampleCount = 0; |
| 439 samplePeriod = 0; | 641 samplePeriod = 0; |
| 440 sampleRate = 0.0; | 642 sampleRate = 0.0; |
| 441 stackDepth = 0; | 643 stackDepth = 0; |
| 442 timeSpan = 0.0; | 644 timeSpan = 0.0; |
| 443 codes.clear(); | 645 codes.clear(); |
| 444 functions.clear(); | 646 functions.clear(); |
| 445 tries.clear(); | 647 tries.clear(); |
| 648 _markedCodeCalls = false; | |
| 649 _markedFunctionCalls = false; | |
| 446 } | 650 } |
| 447 | 651 |
| 448 void load(Isolate isolate, ServiceMap profile) { | 652 load(Isolate isolate, ServiceMap profile) { |
| 449 clear(); | 653 clear(); |
| 450 if ((isolate == null) || (profile == null)) { | 654 if ((isolate == null) || (profile == null)) { |
| 451 return; | 655 return; |
| 452 } | 656 } |
| 453 | 657 |
| 454 this.isolate = isolate; | 658 this.isolate = isolate; |
| 455 isolate.resetCachedProfileData(); | 659 isolate.resetCachedProfileData(); |
| 456 | 660 |
| 457 sampleCount = profile['sampleCount']; | 661 sampleCount = profile['sampleCount']; |
| 458 samplePeriod = profile['samplePeriod']; | 662 samplePeriod = profile['samplePeriod']; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 int approximateMillisecondsForCount(count) { | 861 int approximateMillisecondsForCount(count) { |
| 658 var MICROSECONDS_PER_MILLISECOND = 1000.0; | 862 var MICROSECONDS_PER_MILLISECOND = 1000.0; |
| 659 return (count * samplePeriod) ~/ MICROSECONDS_PER_MILLISECOND; | 863 return (count * samplePeriod) ~/ MICROSECONDS_PER_MILLISECOND; |
| 660 } | 864 } |
| 661 | 865 |
| 662 double approximateSecondsForCount(count) { | 866 double approximateSecondsForCount(count) { |
| 663 var MICROSECONDS_PER_SECOND = 1000000.0; | 867 var MICROSECONDS_PER_SECOND = 1000000.0; |
| 664 return (count * samplePeriod) / MICROSECONDS_PER_SECOND; | 868 return (count * samplePeriod) / MICROSECONDS_PER_SECOND; |
| 665 } | 869 } |
| 666 } | 870 } |
| OLD | NEW |