Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: runtime/observatory/lib/src/cpu_profile/cpu_profile.dart

Issue 2748403002: Added page to Observatory to display native memory allocation information. (Closed)
Patch Set: Added cpp test, fixed NativeAllocationSampleFilter Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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;
11 final int inclusiveNativeAllocations;
12 final int exclusiveNativeAllocations;
11 double get percentage => _percentage; 13 double get percentage => _percentage;
12 double _percentage = 0.0; 14 double _percentage = 0.0;
13 final Set<String> attributes = new Set<String>(); 15 final Set<String> attributes = new Set<String>();
14 16
15 // Either a ProfileCode or a ProfileFunction. 17 // Either a ProfileCode or a ProfileFunction.
16 Object get profileData; 18 Object get profileData;
17 String get name; 19 String get name;
18 20
19 CallTreeNode(this.children, this.count); 21 CallTreeNode(this.children, this.count, this.inclusiveNativeAllocations,
22 this.exclusiveNativeAllocations);
20 } 23 }
21 24
22 class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode> 25 class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode>
23 implements M.CodeCallTreeNode { 26 implements M.CodeCallTreeNode {
24 final ProfileCode profileCode; 27 final ProfileCode profileCode;
25 28
26 Object get profileData => profileCode; 29 Object get profileData => profileCode;
27 30
28 String get name => profileCode.code.name; 31 String get name => profileCode.code.name;
29 32
30 final Set<String> attributes = new Set<String>(); 33 final Set<String> attributes = new Set<String>();
31 CodeCallTreeNode(this.profileCode, int count) 34 CodeCallTreeNode(this.profileCode, int count, int inclusiveNativeAllocations,
32 : super(new List<CodeCallTreeNode>(), count) { 35 int exclusiveNativeAllocations)
36 : super(new List<CodeCallTreeNode>(), count, inclusiveNativeAllocations,
37 exclusiveNativeAllocations) {
33 attributes.addAll(profileCode.attributes); 38 attributes.addAll(profileCode.attributes);
34 } 39 }
35 } 40 }
36 41
37 class CallTree<NodeT extends CallTreeNode> { 42 class CallTree<NodeT extends CallTreeNode> {
38 final bool inclusive; 43 final bool inclusive;
39 final NodeT root; 44 final NodeT root;
40 45
41 CallTree(this.inclusive, this.root); 46 CallTree(this.inclusive, this.root);
42 } 47 }
43 48
44 class CodeCallTree extends CallTree<CodeCallTreeNode> 49 class CodeCallTree extends CallTree<CodeCallTreeNode>
45 implements M.CodeCallTree { 50 implements M.CodeCallTree {
46 CodeCallTree(bool inclusive, CodeCallTreeNode root) : super(inclusive, root) { 51 CodeCallTree(bool inclusive, CodeCallTreeNode root) : super(inclusive, root) {
47 _setCodePercentage(null, root); 52 if (root.inclusiveNativeAllocations != 0) {
53 _setCodeMemoryPercentage(null, root);
54 } else {
55 _setCodePercentage(null, root);
56 }
48 } 57 }
49 58
50 CodeCallTree filtered(CallTreeNodeFilter filter) { 59 CodeCallTree filtered(CallTreeNodeFilter filter) {
51 var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this); 60 var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this);
52 treeFilter.build(); 61 treeFilter.build();
53 _setCodePercentage(null, treeFilter.filtered.root); 62 if (treeFilter.filtered.root.inclusiveNativeAllocations != 0) {
63 _setCodeMemoryPercentage(null, treeFilter.filtered.root);
64 } else {
65 _setCodePercentage(null, treeFilter.filtered.root);
66 }
54 return treeFilter.filtered; 67 return treeFilter.filtered;
55 } 68 }
56 69
57 _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) { 70 _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) {
58 assert(node != null); 71 assert(node != null);
59 var parentPercentage = 1.0; 72 var parentPercentage = 1.0;
60 var parentCount = node.count; 73 var parentCount = node.count;
61 if (parent != null) { 74 if (parent != null) {
62 parentPercentage = parent._percentage; 75 parentPercentage = parent._percentage;
63 parentCount = parent.count; 76 parentCount = parent.count;
64 } 77 }
65 if (inclusive) { 78 if (inclusive) {
66 node._percentage = parentPercentage * (node.count / parentCount); 79 node._percentage = parentPercentage * (node.count / parentCount);
67 } else { 80 } else {
68 node._percentage = (node.count / parentCount); 81 node._percentage = (node.count / parentCount);
69 } 82 }
70 for (var child in node.children) { 83 for (var child in node.children) {
71 _setCodePercentage(node, child); 84 _setCodePercentage(node, child);
72 } 85 }
73 } 86 }
74 87
88 _setCodeMemoryPercentage(CodeCallTreeNode parent, CodeCallTreeNode node) {
89 assert(node != null);
90 var parentPercentage = 1.0;
91 var parentMemory = node.inclusiveNativeAllocations;
92 if (parent != null) {
93 parentPercentage = parent._percentage;
94 parentMemory = parent.inclusiveNativeAllocations;
95 }
96 if (inclusive) {
97 node._percentage =
98 parentPercentage * (node.inclusiveNativeAllocations / parentMemory);
99 } else {
100 node._percentage = (node.inclusiveNativeAllocations / parentMemory);
Cutch 2017/03/23 23:39:44 should this be exclusiveNativeAllocations?
bkonyi 2017/03/24 00:53:38 No, since the variable "inclusive" represents the
101 }
102 for (var child in node.children) {
103 _setCodeMemoryPercentage(node, child);
104 }
105 }
106
75 _recordCallerAndCalleesInner( 107 _recordCallerAndCalleesInner(
76 CodeCallTreeNode caller, CodeCallTreeNode callee) { 108 CodeCallTreeNode caller, CodeCallTreeNode callee) {
77 if (caller != null) { 109 if (caller != null) {
78 caller.profileCode._recordCallee(callee.profileCode, callee.count); 110 caller.profileCode._recordCallee(callee.profileCode, callee.count);
79 callee.profileCode._recordCaller(caller.profileCode, caller.count); 111 callee.profileCode._recordCaller(caller.profileCode, caller.count);
80 } 112 }
81 113
82 for (var child in callee.children) { 114 for (var child in callee.children) {
83 _recordCallerAndCalleesInner(callee, child); 115 _recordCallerAndCalleesInner(callee, child);
84 } 116 }
(...skipping 14 matching lines...) Expand all
99 131
100 class FunctionCallTreeNode extends CallTreeNode { 132 class FunctionCallTreeNode extends CallTreeNode {
101 final ProfileFunction profileFunction; 133 final ProfileFunction profileFunction;
102 final codes = new List<FunctionCallTreeNodeCode>(); 134 final codes = new List<FunctionCallTreeNodeCode>();
103 int _totalCodeTicks = 0; 135 int _totalCodeTicks = 0;
104 int get totalCodesTicks => _totalCodeTicks; 136 int get totalCodesTicks => _totalCodeTicks;
105 137
106 String get name => M.getFunctionFullName(profileFunction.function); 138 String get name => M.getFunctionFullName(profileFunction.function);
107 Object get profileData => profileFunction; 139 Object get profileData => profileFunction;
108 140
109 FunctionCallTreeNode(this.profileFunction, int count) 141 FunctionCallTreeNode(this.profileFunction, int count,
110 : super(new List<FunctionCallTreeNode>(), count) { 142 inclusiveNativeAllocations, exclusiveNativeAllocations)
143 : super(new List<FunctionCallTreeNode>(), count,
144 inclusiveNativeAllocations, exclusiveNativeAllocations) {
111 profileFunction._addKindBasedAttributes(attributes); 145 profileFunction._addKindBasedAttributes(attributes);
112 } 146 }
113 147
114 // Does this function have an optimized version of itself? 148 // Does this function have an optimized version of itself?
115 bool hasOptimizedCode() { 149 bool hasOptimizedCode() {
116 for (var nodeCode in codes) { 150 for (var nodeCode in codes) {
117 var profileCode = nodeCode.code; 151 var profileCode = nodeCode.code;
118 if (!profileCode.code.isDartCode) { 152 if (!profileCode.code.isDartCode) {
119 continue; 153 continue;
120 } 154 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 317
284 class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder { 318 class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder {
285 _FilteredFunctionCallTreeBuilder( 319 _FilteredFunctionCallTreeBuilder(
286 CallTreeNodeFilter filter, FunctionCallTree tree) 320 CallTreeNodeFilter filter, FunctionCallTree tree)
287 : super( 321 : super(
288 filter, 322 filter,
289 tree, 323 tree,
290 new FunctionCallTree( 324 new FunctionCallTree(
291 tree.inclusive, 325 tree.inclusive,
292 new FunctionCallTreeNode( 326 new FunctionCallTreeNode(
293 tree.root.profileData, tree.root.count))); 327 tree.root.profileData,
328 tree.root.count,
329 tree.root.inclusiveNativeAllocations,
330 tree.root.exclusiveNativeAllocations)));
294 331
295 _copyNode(FunctionCallTreeNode node) { 332 _copyNode(FunctionCallTreeNode node) {
296 return new FunctionCallTreeNode(node.profileData, node.count); 333 return new FunctionCallTreeNode(node.profileData, node.count,
334 node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
297 } 335 }
298 } 336 }
299 337
300 class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder { 338 class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder {
301 _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter, CodeCallTree tree) 339 _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter, CodeCallTree tree)
302 : super( 340 : super(
303 filter, 341 filter,
304 tree, 342 tree,
305 new CodeCallTree(tree.inclusive, 343 new CodeCallTree(
306 new CodeCallTreeNode(tree.root.profileData, tree.root.count))); 344 tree.inclusive,
345 new CodeCallTreeNode(
346 tree.root.profileData,
347 tree.root.count,
348 tree.root.inclusiveNativeAllocations,
349 tree.root.exclusiveNativeAllocations)));
307 350
308 _copyNode(CodeCallTreeNode node) { 351 _copyNode(CodeCallTreeNode node) {
309 return new CodeCallTreeNode(node.profileData, node.count); 352 return new CodeCallTreeNode(node.profileData, node.count,
353 node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
310 } 354 }
311 } 355 }
312 356
313 class FunctionCallTree extends CallTree implements M.FunctionCallTree { 357 class FunctionCallTree extends CallTree implements M.FunctionCallTree {
314 FunctionCallTree(bool inclusive, FunctionCallTreeNode root) 358 FunctionCallTree(bool inclusive, FunctionCallTreeNode root)
315 : super(inclusive, root) { 359 : super(inclusive, root) {
316 _setFunctionPercentage(null, root); 360 if (root.inclusiveNativeAllocations != 0 &&
361 root.inclusiveNativeAllocations != null) {
Cutch 2017/03/23 23:39:44 test for null before testing against 0. wrap each
bkonyi 2017/03/24 00:53:38 Done.
362 _setFunctionMemoryPercentage(null, root);
363 } else {
364 _setFunctionPercentage(null, root);
365 }
317 } 366 }
318 367
319 FunctionCallTree filtered(CallTreeNodeFilter filter) { 368 FunctionCallTree filtered(CallTreeNodeFilter filter) {
320 var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this); 369 var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this);
321 treeFilter.build(); 370 treeFilter.build();
322 _setFunctionPercentage(null, treeFilter.filtered.root); 371 if (treeFilter.filtered.root.inclusiveNativeAllocations != 0 &&
Cutch 2017/03/23 23:39:44 ditto
bkonyi 2017/03/24 00:53:38 Done.
372 treeFilter.filtered.root.inclusiveNativeAllocations != null) {
373 _setFunctionMemoryPercentage(null, treeFilter.filtered.root);
374 } else {
375 _setFunctionPercentage(null, treeFilter.filtered.root);
376 }
323 return treeFilter.filtered; 377 return treeFilter.filtered;
324 } 378 }
325 379
326 void _setFunctionPercentage( 380 void _setFunctionPercentage(
327 FunctionCallTreeNode parent, FunctionCallTreeNode node) { 381 FunctionCallTreeNode parent, FunctionCallTreeNode node) {
328 assert(node != null); 382 assert(node != null);
329 var parentPercentage = 1.0; 383 var parentPercentage = 1.0;
330 var parentCount = node.count; 384 var parentCount = node.count;
331 if (parent != null) { 385 if (parent != null) {
332 parentPercentage = parent._percentage; 386 parentPercentage = parent._percentage;
333 parentCount = parent.count; 387 parentCount = parent.count;
334 } 388 }
335 if (inclusive) { 389 if (inclusive) {
336 node._percentage = parentPercentage * (node.count / parentCount); 390 node._percentage = parentPercentage * (node.count / parentCount);
337 } else { 391 } else {
338 node._percentage = (node.count / parentCount); 392 node._percentage = (node.count / parentCount);
339 } 393 }
340 for (var child in node.children) { 394 for (var child in node.children) {
341 _setFunctionPercentage(node, child); 395 _setFunctionPercentage(node, child);
342 } 396 }
343 } 397 }
344 398
399 void _setFunctionMemoryPercentage(
400 FunctionCallTreeNode parent, FunctionCallTreeNode node) {
401 assert(node != null);
402 var parentPercentage = 1.0;
403 var parentMemory = node.inclusiveNativeAllocations;
404 if (parent != null) {
405 parentPercentage = parent._percentage;
406 parentMemory = parent.inclusiveNativeAllocations;
407 }
408 if (inclusive) {
409 node._percentage =
410 parentPercentage * (node.inclusiveNativeAllocations / parentMemory);
411 } else {
412 node._percentage = (node.inclusiveNativeAllocations / parentMemory);
Cutch 2017/03/23 23:39:44 should this be exclusiveNativeAllocations?
bkonyi 2017/03/24 00:53:38 See reply above.
413 }
414 for (var child in node.children) {
415 _setFunctionMemoryPercentage(node, child);
416 }
417 }
418
345 _markFunctionCallsInner( 419 _markFunctionCallsInner(
346 FunctionCallTreeNode caller, FunctionCallTreeNode callee) { 420 FunctionCallTreeNode caller, FunctionCallTreeNode callee) {
347 if (caller != null) { 421 if (caller != null) {
348 caller.profileFunction 422 caller.profileFunction
349 ._recordCallee(callee.profileFunction, callee.count); 423 ._recordCallee(callee.profileFunction, callee.count);
350 callee.profileFunction 424 callee.profileFunction
351 ._recordCaller(caller.profileFunction, caller.count); 425 ._recordCaller(caller.profileFunction, caller.count);
352 } 426 }
353 for (var child in callee.children) { 427 for (var child in callee.children) {
354 _markFunctionCallsInner(callee, child); 428 _markFunctionCallsInner(callee, child);
(...skipping 20 matching lines...) Expand all
375 int _exclusiveTicks = 0; 449 int _exclusiveTicks = 0;
376 int get exclusiveTicks => _exclusiveTicks; 450 int get exclusiveTicks => _exclusiveTicks;
377 InlineIntervalTick(this.startAddress); 451 InlineIntervalTick(this.startAddress);
378 } 452 }
379 453
380 class ProfileCode implements M.ProfileCode { 454 class ProfileCode implements M.ProfileCode {
381 final CpuProfile profile; 455 final CpuProfile profile;
382 final Code code; 456 final Code code;
383 int exclusiveTicks; 457 int exclusiveTicks;
384 int inclusiveTicks; 458 int inclusiveTicks;
459 int exclusiveNativeAllocations;
460 int inclusiveNativeAllocations;
385 double normalizedExclusiveTicks = 0.0; 461 double normalizedExclusiveTicks = 0.0;
386 double normalizedInclusiveTicks = 0.0; 462 double normalizedInclusiveTicks = 0.0;
387 final addressTicks = new Map<int, CodeTick>(); 463 final addressTicks = new Map<int, CodeTick>();
388 final intervalTicks = new Map<int, InlineIntervalTick>(); 464 final intervalTicks = new Map<int, InlineIntervalTick>();
389 String formattedInclusiveTicks = ''; 465 String formattedInclusiveTicks = '';
390 String formattedExclusiveTicks = ''; 466 String formattedExclusiveTicks = '';
391 String formattedExclusivePercent = ''; 467 String formattedExclusivePercent = '';
392 String formattedCpuTime = ''; 468 String formattedCpuTime = '';
393 String formattedOnStackTime = ''; 469 String formattedOnStackTime = '';
394 final Set<String> attributes = new Set<String>(); 470 final Set<String> attributes = new Set<String>();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 527
452 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount; 528 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount;
453 529
454 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; 530 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount;
455 531
456 var ticks = data['ticks']; 532 var ticks = data['ticks'];
457 if (ticks != null) { 533 if (ticks != null) {
458 _processTicks(ticks); 534 _processTicks(ticks);
459 } 535 }
460 536
537 if (data.containsKey('exclusiveNativeAllocations') &&
538 data.containsKey('inclusiveNativeAllocations')) {
539 exclusiveNativeAllocations =
540 int.parse(data['exclusiveNativeAllocations']);
541 inclusiveNativeAllocations =
542 int.parse(data['inclusiveNativeAllocations']);
543 }
544
461 formattedExclusivePercent = 545 formattedExclusivePercent =
462 Utils.formatPercent(exclusiveTicks, profile.sampleCount); 546 Utils.formatPercent(exclusiveTicks, profile.sampleCount);
463 547
464 formattedCpuTime = Utils.formatTimeMilliseconds( 548 formattedCpuTime = Utils.formatTimeMilliseconds(
465 profile.approximateMillisecondsForCount(exclusiveTicks)); 549 profile.approximateMillisecondsForCount(exclusiveTicks));
466 550
467 formattedOnStackTime = Utils.formatTimeMilliseconds( 551 formattedOnStackTime = Utils.formatTimeMilliseconds(
468 profile.approximateMillisecondsForCount(inclusiveTicks)); 552 profile.approximateMillisecondsForCount(inclusiveTicks));
469 553
470 formattedInclusiveTicks = 554 formattedInclusiveTicks =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 final Map<ProfileFunction, int> callees = new Map<ProfileFunction, int>(); 586 final Map<ProfileFunction, int> callees = new Map<ProfileFunction, int>();
503 587
504 // Absolute ticks: 588 // Absolute ticks:
505 int exclusiveTicks = 0; 589 int exclusiveTicks = 0;
506 int inclusiveTicks = 0; 590 int inclusiveTicks = 0;
507 591
508 // Global percentages: 592 // Global percentages:
509 double normalizedExclusiveTicks = 0.0; 593 double normalizedExclusiveTicks = 0.0;
510 double normalizedInclusiveTicks = 0.0; 594 double normalizedInclusiveTicks = 0.0;
511 595
596 // Native allocations:
597 int exclusiveNativeAllocations = 0;
598 int inclusiveNativeAllocations = 0;
599
512 String formattedInclusiveTicks = ''; 600 String formattedInclusiveTicks = '';
513 String formattedExclusiveTicks = ''; 601 String formattedExclusiveTicks = '';
514 String formattedExclusivePercent = ''; 602 String formattedExclusivePercent = '';
515 String formattedCpuTime = ''; 603 String formattedCpuTime = '';
516 String formattedOnStackTime = ''; 604 String formattedOnStackTime = '';
517 final Set<String> attributes = new Set<String>(); 605 final Set<String> attributes = new Set<String>();
518 606
519 int _sortCodes(ProfileCode a, ProfileCode b) { 607 int _sortCodes(ProfileCode a, ProfileCode b) {
520 if (a.code.isOptimized == b.code.isOptimized) { 608 if (a.code.isOptimized == b.code.isOptimized) {
521 return b.code.profile.exclusiveTicks - a.code.profile.exclusiveTicks; 609 return b.code.profile.exclusiveTicks - a.code.profile.exclusiveTicks;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 } 687 }
600 profileCodes.sort(_sortCodes); 688 profileCodes.sort(_sortCodes);
601 689
602 _addKindBasedAttributes(attributes); 690 _addKindBasedAttributes(attributes);
603 exclusiveTicks = int.parse(data['exclusiveTicks']); 691 exclusiveTicks = int.parse(data['exclusiveTicks']);
604 inclusiveTicks = int.parse(data['inclusiveTicks']); 692 inclusiveTicks = int.parse(data['inclusiveTicks']);
605 693
606 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount; 694 normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount;
607 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount; 695 normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount;
608 696
697 if (data.containsKey('exclusiveNativeAllocations') &&
698 data.containsKey('inclusiveNativeAllocations')) {
699 exclusiveNativeAllocations =
700 int.parse(data['exclusiveNativeAllocations']);
701 inclusiveNativeAllocations =
702 int.parse(data['inclusiveNativeAllocations']);
703 }
704
609 formattedExclusivePercent = 705 formattedExclusivePercent =
610 Utils.formatPercent(exclusiveTicks, profile.sampleCount); 706 Utils.formatPercent(exclusiveTicks, profile.sampleCount);
611 707
612 formattedCpuTime = Utils.formatTimeMilliseconds( 708 formattedCpuTime = Utils.formatTimeMilliseconds(
613 profile.approximateMillisecondsForCount(exclusiveTicks)); 709 profile.approximateMillisecondsForCount(exclusiveTicks));
614 710
615 formattedOnStackTime = Utils.formatTimeMilliseconds( 711 formattedOnStackTime = Utils.formatTimeMilliseconds(
616 profile.approximateMillisecondsForCount(inclusiveTicks)); 712 profile.approximateMillisecondsForCount(inclusiveTicks));
617 713
618 formattedInclusiveTicks = 714 formattedInclusiveTicks =
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 sampleRate = 0.0; 799 sampleRate = 0.0;
704 stackDepth = 0; 800 stackDepth = 0;
705 timeSpan = 0.0; 801 timeSpan = 0.0;
706 codes.clear(); 802 codes.clear();
707 functions.clear(); 803 functions.clear();
708 tries.clear(); 804 tries.clear();
709 _builtCodeCalls = false; 805 _builtCodeCalls = false;
710 _builtFunctionCalls = false; 806 _builtFunctionCalls = false;
711 } 807 }
712 808
713 Future load(Isolate isolate, ServiceMap profile) async { 809 Future load(ServiceObjectOwner owner, ServiceMap profile) async {
714 await loadProgress(isolate, profile).last; 810 await loadProgress(owner, profile).last;
715 } 811 }
716 812
717 static Future sleep([Duration duration = const Duration(microseconds: 0)]) { 813 static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
718 final Completer completer = new Completer(); 814 final Completer completer = new Completer();
719 new Timer(duration, () => completer.complete()); 815 new Timer(duration, () => completer.complete());
720 return completer.future; 816 return completer.future;
721 } 817 }
722 818
723 Stream<double> loadProgress(Isolate isolate, ServiceMap profile) { 819 Stream<double> loadProgress(ServiceObjectOwner owner, ServiceMap profile) {
724 var progress = new StreamController<double>.broadcast(); 820 var progress = new StreamController<double>.broadcast();
725 821
726 (() async { 822 (() async {
727 final Stopwatch watch = new Stopwatch(); 823 final Stopwatch watch = new Stopwatch();
728 watch.start(); 824 watch.start();
729 int count = 0; 825 int count = 0;
730 var needToUpdate = () { 826 var needToUpdate = () {
731 count++; 827 count++;
732 if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) { 828 if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) {
733 watch.reset(); 829 watch.reset();
734 return true; 830 return true;
735 } 831 }
736 return false; 832 return false;
737 }; 833 };
738 var signal = (double p) { 834 var signal = (double p) {
739 progress.add(p); 835 progress.add(p);
740 return sleep(); 836 return sleep();
741 }; 837 };
742 try { 838 try {
743 clear(); 839 clear();
744 progress.add(0.0); 840 progress.add(0.0);
745 if ((isolate == null) || (profile == null)) { 841 if (profile == null) {
746 return; 842 return;
747 } 843 }
748 844
749 this.isolate = isolate; 845 if (owner != null && owner is Isolate) {
Cutch 2017/03/23 23:39:44 here and everywhere: wrap in parens ((owner != nu
bkonyi 2017/03/24 00:53:38 Done.
750 isolate.resetCachedProfileData(); 846 isolate = owner as Isolate;
847 isolate.resetCachedProfileData();
848 }
751 849
752 sampleCount = profile['sampleCount']; 850 sampleCount = profile['sampleCount'];
753 samplePeriod = profile['samplePeriod']; 851 samplePeriod = profile['samplePeriod'];
754 sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod); 852 sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod);
755 stackDepth = profile['stackDepth']; 853 stackDepth = profile['stackDepth'];
756 timeSpan = profile['timeSpan']; 854 timeSpan = profile['timeSpan'];
757 855
758 num length = profile['codes'].length + profile['functions'].length; 856 num length = profile['codes'].length + profile['functions'].length;
759 857
760 // Process code table. 858 // Process code table.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 } 915 }
818 916
819 CodeCallTreeNode _readCodeTrieNode(List<int> data) { 917 CodeCallTreeNode _readCodeTrieNode(List<int> data) {
820 // Lookup code object. 918 // Lookup code object.
821 var codeIndex = data[_dataCursor++]; 919 var codeIndex = data[_dataCursor++];
822 var code = codes[codeIndex]; 920 var code = codes[codeIndex];
823 // Node tick counter. 921 // Node tick counter.
824 var count = data[_dataCursor++]; 922 var count = data[_dataCursor++];
825 // Child node count. 923 // Child node count.
826 var children = data[_dataCursor++]; 924 var children = data[_dataCursor++];
925 // Inclusive native allocations.
926 var inclusiveNativeAllocations = data[_dataCursor++];
927 // Exclusive native allocations.
928 var exclusiveNativeAllocations = data[_dataCursor++];
827 // Create node. 929 // Create node.
828 var node = new CodeCallTreeNode(code, count); 930 var node = new CodeCallTreeNode(
931 code, count, inclusiveNativeAllocations, exclusiveNativeAllocations);
829 node.children.length = children; 932 node.children.length = children;
830 return node; 933 return node;
831 } 934 }
832 935
833 CodeCallTreeNode _readCodeTrie(List<int> data) { 936 CodeCallTreeNode _readCodeTrie(List<int> data) {
834 final nodeStack = new List<CodeCallTreeNode>(); 937 final nodeStack = new List<CodeCallTreeNode>();
835 final childIndexStack = new List<int>(); 938 final childIndexStack = new List<int>();
836 939
837 _dataCursor = 0; 940 _dataCursor = 0;
838 // Read root. 941 // Read root.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 return new FunctionCallTree(inclusive, root); 990 return new FunctionCallTree(inclusive, root);
888 } 991 }
889 992
890 FunctionCallTreeNode _readFunctionTrieNode(List<int> data) { 993 FunctionCallTreeNode _readFunctionTrieNode(List<int> data) {
891 // Read index into function table. 994 // Read index into function table.
892 var index = data[_dataCursor++]; 995 var index = data[_dataCursor++];
893 // Lookup function object. 996 // Lookup function object.
894 var function = functions[index]; 997 var function = functions[index];
895 // Counter. 998 // Counter.
896 var count = data[_dataCursor++]; 999 var count = data[_dataCursor++];
1000 // Inclusive native allocations.
1001 var inclusiveNativeAllocations = data[_dataCursor++];
1002 // Exclusive native allocations.
1003 var exclusiveNativeAllocations = data[_dataCursor++];
897 // Create node. 1004 // Create node.
898 var node = new FunctionCallTreeNode(function, count); 1005 var node = new FunctionCallTreeNode(function, count,
1006 inclusiveNativeAllocations, exclusiveNativeAllocations);
899 // Number of code index / count pairs. 1007 // Number of code index / count pairs.
900 var codeCount = data[_dataCursor++]; 1008 var codeCount = data[_dataCursor++];
901 node.codes.length = codeCount; 1009 node.codes.length = codeCount;
902 var totalCodeTicks = 0; 1010 var totalCodeTicks = 0;
903 for (var i = 0; i < codeCount; i++) { 1011 for (var i = 0; i < codeCount; i++) {
904 var codeIndex = data[_dataCursor++]; 1012 var codeIndex = data[_dataCursor++];
905 var code = codes[codeIndex]; 1013 var code = codes[codeIndex];
906 assert(code != null); 1014 assert(code != null);
907 var codeTicks = data[_dataCursor++]; 1015 var codeTicks = data[_dataCursor++];
908 totalCodeTicks += codeTicks; 1016 totalCodeTicks += codeTicks;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 } 1071 }
964 1072
965 int approximateMillisecondsForCount(count) { 1073 int approximateMillisecondsForCount(count) {
966 return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND; 1074 return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND;
967 } 1075 }
968 1076
969 double approximateSecondsForCount(count) { 1077 double approximateSecondsForCount(count) {
970 return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND; 1078 return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND;
971 } 1079 }
972 } 1080 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698