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 abstract class CallTreeNode<NodeT extends M.CallTreeNode> | 7 abstract class CallTreeNode<NodeT extends M.CallTreeNode> |
8 implements M.CallTreeNode { | 8 implements M.CallTreeNode { |
9 final List<NodeT> children; | 9 final List<NodeT> children; |
10 final int count; | 10 final int count; |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 class CallTree<NodeT extends CallTreeNode> { | 37 class CallTree<NodeT extends CallTreeNode> { |
38 final bool inclusive; | 38 final bool inclusive; |
39 final NodeT root; | 39 final NodeT root; |
40 | 40 |
41 CallTree(this.inclusive, this.root); | 41 CallTree(this.inclusive, this.root); |
42 } | 42 } |
43 | 43 |
44 class CodeCallTree extends CallTree<CodeCallTreeNode> | 44 class CodeCallTree extends CallTree<CodeCallTreeNode> |
45 implements M.CodeCallTree { | 45 implements M.CodeCallTree { |
46 CodeCallTree(bool inclusive, CodeCallTreeNode root) | 46 CodeCallTree(bool inclusive, CodeCallTreeNode root) : super(inclusive, root) { |
47 : super(inclusive, root) { | |
48 _setCodePercentage(null, root); | 47 _setCodePercentage(null, root); |
49 } | 48 } |
50 | 49 |
51 CodeCallTree filtered(CallTreeNodeFilter filter) { | 50 CodeCallTree filtered(CallTreeNodeFilter filter) { |
52 var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this); | 51 var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this); |
53 treeFilter.build(); | 52 treeFilter.build(); |
54 _setCodePercentage(null, treeFilter.filtered.root); | 53 _setCodePercentage(null, treeFilter.filtered.root); |
55 return treeFilter.filtered; | 54 return treeFilter.filtered; |
56 } | 55 } |
57 | 56 |
58 _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) { | 57 _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) { |
59 assert(node != null); | 58 assert(node != null); |
60 var parentPercentage = 1.0; | 59 var parentPercentage = 1.0; |
61 var parentCount = node.count; | 60 var parentCount = node.count; |
62 if (parent != null) { | 61 if (parent != null) { |
63 parentPercentage = parent._percentage; | 62 parentPercentage = parent._percentage; |
64 parentCount = parent.count; | 63 parentCount = parent.count; |
65 } | 64 } |
66 if (inclusive) { | 65 if (inclusive) { |
67 node._percentage = parentPercentage * (node.count / parentCount); | 66 node._percentage = parentPercentage * (node.count / parentCount); |
68 } else { | 67 } else { |
69 node._percentage = (node.count / parentCount); | 68 node._percentage = (node.count / parentCount); |
70 } | 69 } |
71 for (var child in node.children) { | 70 for (var child in node.children) { |
72 _setCodePercentage(node, child); | 71 _setCodePercentage(node, child); |
73 } | 72 } |
74 } | 73 } |
75 | 74 |
76 _recordCallerAndCalleesInner(CodeCallTreeNode caller, | 75 _recordCallerAndCalleesInner( |
77 CodeCallTreeNode callee) { | 76 CodeCallTreeNode caller, CodeCallTreeNode callee) { |
78 if (caller != null) { | 77 if (caller != null) { |
79 caller.profileCode._recordCallee(callee.profileCode, callee.count); | 78 caller.profileCode._recordCallee(callee.profileCode, callee.count); |
80 callee.profileCode._recordCaller(caller.profileCode, caller.count); | 79 callee.profileCode._recordCaller(caller.profileCode, caller.count); |
81 } | 80 } |
82 | 81 |
83 for (var child in callee.children) { | 82 for (var child in callee.children) { |
84 _recordCallerAndCalleesInner(callee, child); | 83 _recordCallerAndCalleesInner(callee, child); |
85 } | 84 } |
86 } | 85 } |
87 | 86 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 continue; | 156 continue; |
158 } | 157 } |
159 // If the code's function isn't this function. | 158 // If the code's function isn't this function. |
160 if (profileCode.code.function != profileFunction.function) { | 159 if (profileCode.code.function != profileFunction.function) { |
161 return true; | 160 return true; |
162 } | 161 } |
163 } | 162 } |
164 return false; | 163 return false; |
165 } | 164 } |
166 | 165 |
167 setCodeAttributes() { | 166 setCodeAttributes() {} |
168 } | |
169 } | 167 } |
170 | 168 |
171 /// Predicate filter function. Returns true if path from root to [node] and all | 169 /// Predicate filter function. Returns true if path from root to [node] and all |
172 /// of [node]'s children should be added to the filtered tree. | 170 /// of [node]'s children should be added to the filtered tree. |
173 typedef bool CallTreeNodeFilter(CallTreeNode node); | 171 typedef bool CallTreeNodeFilter(CallTreeNode node); |
174 | 172 |
175 /// Build a filter version of a FunctionCallTree. | 173 /// Build a filter version of a FunctionCallTree. |
176 abstract class _FilteredCallTreeBuilder { | 174 abstract class _FilteredCallTreeBuilder { |
177 /// The filter. | 175 /// The filter. |
178 final CallTreeNodeFilter filter; | 176 final CallTreeNodeFilter filter; |
| 177 |
179 /// The unfiltered tree. | 178 /// The unfiltered tree. |
180 final CallTree _unfilteredTree; | 179 final CallTree _unfilteredTree; |
| 180 |
181 /// The filtered tree (construct by [build]). | 181 /// The filtered tree (construct by [build]). |
182 final CallTree filtered; | 182 final CallTree filtered; |
183 final List _currentPath = []; | 183 final List _currentPath = []; |
184 | 184 |
185 /// Construct a filtered tree builder using [filter] and [tree]. | 185 /// Construct a filtered tree builder using [filter] and [tree]. |
186 _FilteredCallTreeBuilder(this.filter, CallTree tree, this.filtered) | 186 _FilteredCallTreeBuilder(this.filter, CallTree tree, this.filtered) |
187 : _unfilteredTree = tree; | 187 : _unfilteredTree = tree; |
188 | 188 |
189 /// Build the filtered tree. | 189 /// Build the filtered tree. |
190 build() { | 190 build() { |
191 assert(filtered != null); | 191 assert(filtered != null); |
192 assert(filter != null); | 192 assert(filter != null); |
193 assert(_unfilteredTree != null); | 193 assert(_unfilteredTree != null); |
194 _descend(_unfilteredTree.root); | 194 _descend(_unfilteredTree.root); |
195 } | 195 } |
196 | 196 |
197 CallTreeNode _findInChildren(CallTreeNode current, | 197 CallTreeNode _findInChildren(CallTreeNode current, CallTreeNode needle) { |
198 CallTreeNode needle) { | |
199 for (var child in current.children) { | 198 for (var child in current.children) { |
200 if (child.profileData == needle.profileData) { | 199 if (child.profileData == needle.profileData) { |
201 return child; | 200 return child; |
202 } | 201 } |
203 } | 202 } |
204 return null; | 203 return null; |
205 } | 204 } |
206 | 205 |
207 CallTreeNode _copyNode(CallTreeNode node); | 206 CallTreeNode _copyNode(CallTreeNode node); |
208 | 207 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 _descend(child); | 275 _descend(child); |
277 } | 276 } |
278 } | 277 } |
279 | 278 |
280 var last = _currentPath.removeLast(); | 279 var last = _currentPath.removeLast(); |
281 assert(current == last); | 280 assert(current == last); |
282 } | 281 } |
283 } | 282 } |
284 | 283 |
285 class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder { | 284 class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder { |
286 _FilteredFunctionCallTreeBuilder(CallTreeNodeFilter filter, | 285 _FilteredFunctionCallTreeBuilder( |
287 FunctionCallTree tree) | 286 CallTreeNodeFilter filter, FunctionCallTree tree) |
288 : super(filter, tree, | 287 : super( |
289 new FunctionCallTree(tree.inclusive, | 288 filter, |
290 new FunctionCallTreeNode(tree.root.profileData, | 289 tree, |
291 tree.root.count))); | 290 new FunctionCallTree( |
| 291 tree.inclusive, |
| 292 new FunctionCallTreeNode( |
| 293 tree.root.profileData, tree.root.count))); |
292 | 294 |
293 _copyNode(FunctionCallTreeNode node) { | 295 _copyNode(FunctionCallTreeNode node) { |
294 return new FunctionCallTreeNode(node.profileData, node.count); | 296 return new FunctionCallTreeNode(node.profileData, node.count); |
295 } | 297 } |
296 } | 298 } |
297 | 299 |
298 class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder { | 300 class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder { |
299 _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter, | 301 _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter, CodeCallTree tree) |
300 CodeCallTree tree) | 302 : super( |
301 : super(filter, tree, | 303 filter, |
| 304 tree, |
302 new CodeCallTree(tree.inclusive, | 305 new CodeCallTree(tree.inclusive, |
303 new CodeCallTreeNode(tree.root.profileData, | 306 new CodeCallTreeNode(tree.root.profileData, tree.root.count))); |
304 tree.root.count))); | |
305 | 307 |
306 _copyNode(CodeCallTreeNode node) { | 308 _copyNode(CodeCallTreeNode node) { |
307 return new CodeCallTreeNode(node.profileData, node.count); | 309 return new CodeCallTreeNode(node.profileData, node.count); |
308 } | 310 } |
309 } | 311 } |
310 | 312 |
311 class FunctionCallTree extends CallTree implements M.FunctionCallTree { | 313 class FunctionCallTree extends CallTree implements M.FunctionCallTree { |
312 FunctionCallTree(bool inclusive, FunctionCallTreeNode root) | 314 FunctionCallTree(bool inclusive, FunctionCallTreeNode root) |
313 : super(inclusive, root) { | 315 : super(inclusive, root) { |
314 _setFunctionPercentage(null, root); | 316 _setFunctionPercentage(null, root); |
315 } | 317 } |
316 | 318 |
317 FunctionCallTree filtered(CallTreeNodeFilter filter) { | 319 FunctionCallTree filtered(CallTreeNodeFilter filter) { |
318 var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this); | 320 var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this); |
319 treeFilter.build(); | 321 treeFilter.build(); |
320 _setFunctionPercentage(null, treeFilter.filtered.root); | 322 _setFunctionPercentage(null, treeFilter.filtered.root); |
321 return treeFilter.filtered; | 323 return treeFilter.filtered; |
322 } | 324 } |
323 | 325 |
324 void _setFunctionPercentage(FunctionCallTreeNode parent, | 326 void _setFunctionPercentage( |
325 FunctionCallTreeNode node) { | 327 FunctionCallTreeNode parent, FunctionCallTreeNode node) { |
326 assert(node != null); | 328 assert(node != null); |
327 var parentPercentage = 1.0; | 329 var parentPercentage = 1.0; |
328 var parentCount = node.count; | 330 var parentCount = node.count; |
329 if (parent != null) { | 331 if (parent != null) { |
330 parentPercentage = parent._percentage; | 332 parentPercentage = parent._percentage; |
331 parentCount = parent.count; | 333 parentCount = parent.count; |
332 } | 334 } |
333 if (inclusive) { | 335 if (inclusive) { |
334 node._percentage = parentPercentage * (node.count / parentCount); | 336 node._percentage = parentPercentage * (node.count / parentCount); |
335 } else { | 337 } else { |
336 node._percentage = (node.count / parentCount); | 338 node._percentage = (node.count / parentCount); |
337 } | 339 } |
338 for (var child in node.children) { | 340 for (var child in node.children) { |
339 _setFunctionPercentage(node, child); | 341 _setFunctionPercentage(node, child); |
340 } | 342 } |
341 } | 343 } |
342 | 344 |
343 _markFunctionCallsInner(FunctionCallTreeNode caller, | 345 _markFunctionCallsInner( |
344 FunctionCallTreeNode callee) { | 346 FunctionCallTreeNode caller, FunctionCallTreeNode callee) { |
345 if (caller != null) { | 347 if (caller != null) { |
346 caller.profileFunction._recordCallee(callee.profileFunction, callee.count)
; | 348 caller.profileFunction |
347 callee.profileFunction._recordCaller(caller.profileFunction, caller.count)
; | 349 ._recordCallee(callee.profileFunction, callee.count); |
| 350 callee.profileFunction |
| 351 ._recordCaller(caller.profileFunction, caller.count); |
348 } | 352 } |
349 for (var child in callee.children) { | 353 for (var child in callee.children) { |
350 _markFunctionCallsInner(callee, child); | 354 _markFunctionCallsInner(callee, child); |
351 } | 355 } |
352 } | 356 } |
353 | 357 |
354 _markFunctionCalls() { | 358 _markFunctionCalls() { |
355 for (var child in root.children) { | 359 for (var child in root.children) { |
356 _markFunctionCallsInner(null, child); | 360 _markFunctionCallsInner(null, child); |
357 } | 361 } |
(...skipping 30 matching lines...) Expand all Loading... |
388 String formattedCpuTime = ''; | 392 String formattedCpuTime = ''; |
389 String formattedOnStackTime = ''; | 393 String formattedOnStackTime = ''; |
390 final Set<String> attributes = new Set<String>(); | 394 final Set<String> attributes = new Set<String>(); |
391 final Map<ProfileCode, int> callers = new Map<ProfileCode, int>(); | 395 final Map<ProfileCode, int> callers = new Map<ProfileCode, int>(); |
392 final Map<ProfileCode, int> callees = new Map<ProfileCode, int>(); | 396 final Map<ProfileCode, int> callees = new Map<ProfileCode, int>(); |
393 | 397 |
394 void _processTicks(List<String> profileTicks) { | 398 void _processTicks(List<String> profileTicks) { |
395 assert(profileTicks != null); | 399 assert(profileTicks != null); |
396 assert((profileTicks.length % 3) == 0); | 400 assert((profileTicks.length % 3) == 0); |
397 for (var i = 0; i < profileTicks.length; i += 3) { | 401 for (var i = 0; i < profileTicks.length; i += 3) { |
398 var address = int.parse(profileTicks[i], radix:16); | 402 var address = int.parse(profileTicks[i], radix: 16); |
399 var exclusive = int.parse(profileTicks[i + 1]); | 403 var exclusive = int.parse(profileTicks[i + 1]); |
400 var inclusive = int.parse(profileTicks[i + 2]); | 404 var inclusive = int.parse(profileTicks[i + 2]); |
401 var tick = new CodeTick(exclusive, inclusive); | 405 var tick = new CodeTick(exclusive, inclusive); |
402 addressTicks[address] = tick; | 406 addressTicks[address] = tick; |
403 | 407 |
404 var interval = code.findInterval(address); | 408 var interval = code.findInterval(address); |
405 if (interval != null) { | 409 if (interval != null) { |
406 var intervalTick = intervalTicks[interval.start]; | 410 var intervalTick = intervalTicks[interval.start]; |
407 if (intervalTick == null) { | 411 if (intervalTick == null) { |
408 // Insert into map. | 412 // Insert into map. |
409 intervalTick = new InlineIntervalTick(interval.start); | 413 intervalTick = new InlineIntervalTick(interval.start); |
410 intervalTicks[interval.start] = intervalTick; | 414 intervalTicks[interval.start] = intervalTick; |
411 } | 415 } |
412 intervalTick._inclusiveTicks += inclusive; | 416 intervalTick._inclusiveTicks += inclusive; |
413 intervalTick._exclusiveTicks += exclusive; | 417 intervalTick._exclusiveTicks += exclusive; |
414 } | 418 } |
415 } | 419 } |
416 } | 420 } |
417 | 421 |
418 ProfileCode.fromMap(this.profile, this.code, Map data) { | 422 ProfileCode.fromMap(this.profile, this.code, Map data) { |
419 assert(profile != null); | 423 assert(profile != null); |
420 assert(code != null); | 424 assert(code != null); |
421 | 425 |
422 code.profile = this; | 426 code.profile = this; |
423 | 427 |
424 if (code.kind == M.CodeKind.stub) { | 428 if (code.kind == M.CodeKind.stub) { |
425 attributes.add('stub'); | 429 attributes.add('stub'); |
426 } else if (code.kind == M.CodeKind.dart) { | 430 } else if (code.kind == M.CodeKind.dart) { |
427 if (code.isNative) { | 431 if (code.isNative) { |
428 attributes.add('ffi'); // Not to be confused with a C function. | 432 attributes.add('ffi'); // Not to be confused with a C function. |
429 } else { | 433 } else { |
430 attributes.add('dart'); | 434 attributes.add('dart'); |
431 } | 435 } |
432 if (code.hasIntrinsic) { | 436 if (code.hasIntrinsic) { |
433 attributes.add('intrinsic'); | 437 attributes.add('intrinsic'); |
434 } | 438 } |
435 if (code.isOptimized) { | 439 if (code.isOptimized) { |
436 attributes.add('optimized'); | 440 attributes.add('optimized'); |
437 } else { | 441 } else { |
438 attributes.add('unoptimized'); | 442 attributes.add('unoptimized'); |
(...skipping 11 matching lines...) Expand all Loading... |
450 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; | 454 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; |
451 | 455 |
452 var ticks = data['ticks']; | 456 var ticks = data['ticks']; |
453 if (ticks != null) { | 457 if (ticks != null) { |
454 _processTicks(ticks); | 458 _processTicks(ticks); |
455 } | 459 } |
456 | 460 |
457 formattedExclusivePercent = | 461 formattedExclusivePercent = |
458 Utils.formatPercent(exclusiveTicks, profile.sampleCount); | 462 Utils.formatPercent(exclusiveTicks, profile.sampleCount); |
459 | 463 |
460 formattedCpuTime = | 464 formattedCpuTime = Utils.formatTimeMilliseconds( |
461 Utils.formatTimeMilliseconds( | 465 profile.approximateMillisecondsForCount(exclusiveTicks)); |
462 profile.approximateMillisecondsForCount(exclusiveTicks)); | |
463 | 466 |
464 formattedOnStackTime = | 467 formattedOnStackTime = Utils.formatTimeMilliseconds( |
465 Utils.formatTimeMilliseconds( | 468 profile.approximateMillisecondsForCount(inclusiveTicks)); |
466 profile.approximateMillisecondsForCount(inclusiveTicks)); | |
467 | 469 |
468 formattedInclusiveTicks = | 470 formattedInclusiveTicks = |
469 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' | 471 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' |
470 '($inclusiveTicks)'; | 472 '($inclusiveTicks)'; |
471 | 473 |
472 formattedExclusiveTicks = | 474 formattedExclusiveTicks = |
473 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' | 475 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' |
474 '($exclusiveTicks)'; | 476 '($exclusiveTicks)'; |
475 } | 477 } |
476 | 478 |
477 _recordCaller(ProfileCode caller, int count) { | 479 _recordCaller(ProfileCode caller, int count) { |
478 var r = callers[caller]; | 480 var r = callers[caller]; |
479 if (r == null) { | 481 if (r == null) { |
480 r = 0; | 482 r = 0; |
481 } | 483 } |
482 callers[caller] = r + count; | 484 callers[caller] = r + count; |
483 } | 485 } |
484 | 486 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 void _addKindBasedAttributes(Set<String> attribs) { | 575 void _addKindBasedAttributes(Set<String> attribs) { |
574 if (function.kind == M.FunctionKind.tag) { | 576 if (function.kind == M.FunctionKind.tag) { |
575 attribs.add('tag'); | 577 attribs.add('tag'); |
576 } else if (function.kind == M.FunctionKind.stub) { | 578 } else if (function.kind == M.FunctionKind.stub) { |
577 attribs.add('stub'); | 579 attribs.add('stub'); |
578 } else if (function.kind == M.FunctionKind.native) { | 580 } else if (function.kind == M.FunctionKind.native) { |
579 attribs.add('native'); | 581 attribs.add('native'); |
580 } else if (M.isSyntheticFunction(function.kind)) { | 582 } else if (M.isSyntheticFunction(function.kind)) { |
581 attribs.add('synthetic'); | 583 attribs.add('synthetic'); |
582 } else if (function.isNative) { | 584 } else if (function.isNative) { |
583 attribs.add('ffi'); // Not to be confused with a C function. | 585 attribs.add('ffi'); // Not to be confused with a C function. |
584 } else { | 586 } else { |
585 attribs.add('dart'); | 587 attribs.add('dart'); |
586 } | 588 } |
587 if (function.hasIntrinsic == true) { | 589 if (function.hasIntrinsic == true) { |
588 attribs.add('intrinsic'); | 590 attribs.add('intrinsic'); |
589 } | 591 } |
590 } | 592 } |
591 | 593 |
592 ProfileFunction.fromMap(this.profile, this.function, Map data) { | 594 ProfileFunction.fromMap(this.profile, this.function, Map data) { |
593 function.profile = this; | 595 function.profile = this; |
594 for (var codeIndex in data['codes']) { | 596 for (var codeIndex in data['codes']) { |
595 var profileCode = profile.codes[codeIndex]; | 597 var profileCode = profile.codes[codeIndex]; |
596 profileCodes.add(profileCode); | 598 profileCodes.add(profileCode); |
597 } | 599 } |
598 profileCodes.sort(_sortCodes); | 600 profileCodes.sort(_sortCodes); |
599 | 601 |
600 _addKindBasedAttributes(attributes); | 602 _addKindBasedAttributes(attributes); |
601 exclusiveTicks = int.parse(data['exclusiveTicks']); | 603 exclusiveTicks = int.parse(data['exclusiveTicks']); |
602 inclusiveTicks = int.parse(data['inclusiveTicks']); | 604 inclusiveTicks = int.parse(data['inclusiveTicks']); |
603 | 605 |
604 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount; | 606 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount; |
605 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; | 607 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; |
606 | 608 |
607 formattedExclusivePercent = | 609 formattedExclusivePercent = |
608 Utils.formatPercent(exclusiveTicks, profile.sampleCount); | 610 Utils.formatPercent(exclusiveTicks, profile.sampleCount); |
609 | 611 |
610 formattedCpuTime = | 612 formattedCpuTime = Utils.formatTimeMilliseconds( |
611 Utils.formatTimeMilliseconds( | 613 profile.approximateMillisecondsForCount(exclusiveTicks)); |
612 profile.approximateMillisecondsForCount(exclusiveTicks)); | |
613 | 614 |
614 formattedOnStackTime = | 615 formattedOnStackTime = Utils.formatTimeMilliseconds( |
615 Utils.formatTimeMilliseconds( | 616 profile.approximateMillisecondsForCount(inclusiveTicks)); |
616 profile.approximateMillisecondsForCount(inclusiveTicks)); | |
617 | 617 |
618 formattedInclusiveTicks = | 618 formattedInclusiveTicks = |
619 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' | 619 '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} ' |
620 '($inclusiveTicks)'; | 620 '($inclusiveTicks)'; |
621 | 621 |
622 formattedExclusiveTicks = | 622 formattedExclusiveTicks = |
623 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' | 623 '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} ' |
624 '($exclusiveTicks)'; | 624 '($exclusiveTicks)'; |
625 } | 625 } |
626 | 626 |
627 _recordCaller(ProfileFunction caller, int count) { | 627 _recordCaller(ProfileFunction caller, int count) { |
628 var r = callers[caller]; | 628 var r = callers[caller]; |
629 if (r == null) { | 629 if (r == null) { |
630 r = 0; | 630 r = 0; |
631 } | 631 } |
632 callers[caller] = r + count; | 632 callers[caller] = r + count; |
633 } | 633 } |
634 | 634 |
635 _recordCallee(ProfileFunction callee, int count) { | 635 _recordCallee(ProfileFunction callee, int count) { |
636 var r = callees[callee]; | 636 var r = callees[callee]; |
637 if (r == null) { | 637 if (r == null) { |
638 r = 0; | 638 r = 0; |
639 } | 639 } |
640 callees[callee] = r + count; | 640 callees[callee] = r + count; |
641 } | 641 } |
642 } | 642 } |
643 | 643 |
644 | |
645 // TODO(johnmccutchan): Rename to SampleProfile | 644 // TODO(johnmccutchan): Rename to SampleProfile |
646 class CpuProfile extends M.SampleProfile { | 645 class CpuProfile extends M.SampleProfile { |
647 | |
648 Isolate isolate; | 646 Isolate isolate; |
649 | 647 |
650 int sampleCount = 0; | 648 int sampleCount = 0; |
651 int samplePeriod = 0; | 649 int samplePeriod = 0; |
652 double sampleRate = 0.0; | 650 double sampleRate = 0.0; |
653 | 651 |
654 int stackDepth = 0; | 652 int stackDepth = 0; |
655 | 653 |
656 double timeSpan = 0.0; | 654 double timeSpan = 0.0; |
657 | 655 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 _builtCodeCalls = false; | 709 _builtCodeCalls = false; |
712 _builtFunctionCalls = false; | 710 _builtFunctionCalls = false; |
713 } | 711 } |
714 | 712 |
715 Future load(Isolate isolate, ServiceMap profile) async { | 713 Future load(Isolate isolate, ServiceMap profile) async { |
716 await loadProgress(isolate, profile).last; | 714 await loadProgress(isolate, profile).last; |
717 } | 715 } |
718 | 716 |
719 static Future sleep([Duration duration = const Duration(microseconds: 0)]) { | 717 static Future sleep([Duration duration = const Duration(microseconds: 0)]) { |
720 final Completer completer = new Completer(); | 718 final Completer completer = new Completer(); |
721 new Timer(duration, () => completer.complete() ); | 719 new Timer(duration, () => completer.complete()); |
722 return completer.future; | 720 return completer.future; |
723 } | 721 } |
724 | 722 |
725 Stream<double> loadProgress(Isolate isolate, ServiceMap profile) { | 723 Stream<double> loadProgress(Isolate isolate, ServiceMap profile) { |
726 var progress = new StreamController<double>.broadcast(); | 724 var progress = new StreamController<double>.broadcast(); |
727 | 725 |
728 (() async { | 726 (() async { |
729 final Stopwatch watch = new Stopwatch(); | 727 final Stopwatch watch = new Stopwatch(); |
730 watch.start(); | 728 watch.start(); |
731 int count = 0; | 729 int count = 0; |
(...skipping 18 matching lines...) Expand all Loading... |
750 | 748 |
751 this.isolate = isolate; | 749 this.isolate = isolate; |
752 isolate.resetCachedProfileData(); | 750 isolate.resetCachedProfileData(); |
753 | 751 |
754 sampleCount = profile['sampleCount']; | 752 sampleCount = profile['sampleCount']; |
755 samplePeriod = profile['samplePeriod']; | 753 samplePeriod = profile['samplePeriod']; |
756 sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod); | 754 sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod); |
757 stackDepth = profile['stackDepth']; | 755 stackDepth = profile['stackDepth']; |
758 timeSpan = profile['timeSpan']; | 756 timeSpan = profile['timeSpan']; |
759 | 757 |
760 num length = profile['codes'].length + | 758 num length = profile['codes'].length + profile['functions'].length; |
761 profile['functions'].length; | |
762 | 759 |
763 // Process code table. | 760 // Process code table. |
764 for (var codeRegion in profile['codes']) { | 761 for (var codeRegion in profile['codes']) { |
765 if (needToUpdate()) { | 762 if (needToUpdate()) { |
766 await signal(count * 100.0 / length); | 763 await signal(count * 100.0 / length); |
767 } | 764 } |
768 Code code = codeRegion['code']; | 765 Code code = codeRegion['code']; |
769 assert(code != null); | 766 assert(code != null); |
770 codes.add(new ProfileCode.fromMap(this, code, codeRegion)); | 767 codes.add(new ProfileCode.fromMap(this, code, codeRegion)); |
771 } | 768 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 } | 963 } |
967 | 964 |
968 int approximateMillisecondsForCount(count) { | 965 int approximateMillisecondsForCount(count) { |
969 return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND; | 966 return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND; |
970 } | 967 } |
971 | 968 |
972 double approximateSecondsForCount(count) { | 969 double approximateSecondsForCount(count) { |
973 return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND; | 970 return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND; |
974 } | 971 } |
975 } | 972 } |
OLD | NEW |