Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library cpu_profile_element; | 5 library cpu_profile_element; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 import 'observatory_element.dart'; | 9 import 'observatory_element.dart'; |
| 10 import 'package:observatory/service.dart'; | 10 import 'package:observatory/service.dart'; |
| 11 import 'package:observatory/app.dart'; | 11 import 'package:observatory/app.dart'; |
| 12 import 'package:observatory/cpu_profile.dart'; | 12 import 'package:observatory/cpu_profile.dart'; |
| 13 import 'package:observatory/elements.dart'; | 13 import 'package:observatory/elements.dart'; |
| 14 import 'package:polymer/polymer.dart'; | 14 import 'package:polymer/polymer.dart'; |
| 15 | 15 |
| 16 List<String> sorted(Set<String> attributes) { | 16 List<String> sorted(Set<String> attributes) { |
| 17 var list = attributes.toList(); | 17 var list = attributes.toList(); |
| 18 list.sort(); | 18 list.sort(); |
| 19 return list; | 19 return list; |
| 20 } | 20 } |
| 21 | 21 |
| 22 abstract class ProfileTreeRow<T> extends TableTreeRow { | 22 abstract class ProfileTreeRow<T> extends TableTreeRow { |
|
rmacnak
2016/03/24 23:20:36
I assume you're just keeping the old ones for refe
Cutch
2016/03/25 03:04:08
Acknowledged.
| |
| 23 final CpuProfile profile; | 23 final CpuProfile profile; |
| 24 final T node; | 24 final T node; |
| 25 final String selfPercent; | 25 final String selfPercent; |
| 26 final String percent; | 26 final String percent; |
| 27 bool _infoBoxShown = false; | 27 bool _infoBoxShown = false; |
| 28 HtmlElement infoBox; | 28 HtmlElement infoBox; |
| 29 HtmlElement infoButton; | 29 HtmlElement infoButton; |
| 30 | 30 |
| 31 ProfileTreeRow(TableTree tree, TableTreeRow parent, | 31 ProfileTreeRow(TableTree tree, TableTreeRow parent, |
| 32 this.profile, this.node, double selfPercent, double percent) | 32 this.profile, this.node, double selfPercent, double percent) |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 } | 562 } |
| 563 | 563 |
| 564 Function onTreeConfigChange; | 564 Function onTreeConfigChange; |
| 565 @observable bool show = true; | 565 @observable bool show = true; |
| 566 @observable bool showModeSelector = true; | 566 @observable bool showModeSelector = true; |
| 567 @observable bool showDirectionSelector = true; | 567 @observable bool showDirectionSelector = true; |
| 568 @observable String modeSelector = 'Function'; | 568 @observable String modeSelector = 'Function'; |
| 569 @observable String directionSelector = 'Up'; | 569 @observable String directionSelector = 'Up'; |
| 570 } | 570 } |
| 571 | 571 |
| 572 class FunctionCallTreeNodeRow extends VirtualTreeRow { | |
| 573 final CpuProfile profile; | |
| 574 final FunctionCallTreeNode node; | |
| 575 final String selfPercent; | |
| 576 final String totalPercent; | |
| 577 final String percent; | |
| 578 | |
| 579 FunctionCallTreeNodeRow(VirtualTree tree, | |
| 580 int depth, | |
| 581 this.profile, | |
| 582 FunctionCallTreeNode node) | |
| 583 : node = node, | |
| 584 selfPercent = Utils.formatPercentNormalized(node.profileFunction.normali zedExclusiveTicks), | |
| 585 totalPercent = Utils.formatPercentNormalized(node.profileFunction.normal izedInclusiveTicks), | |
| 586 percent = Utils.formatPercentNormalized(node.percentage), | |
| 587 super(tree, depth) { | |
| 588 } | |
| 589 | |
| 590 void onRender(DivElement rowDiv) { | |
| 591 rowDiv.children.add(makeIndenter()); | |
| 592 rowDiv.children.add(makeColorBar()); | |
| 593 rowDiv.children.add(makeExpander()); | |
| 594 rowDiv.children.add( | |
| 595 makeText(percent, toolTip: 'tree node %')); | |
| 596 rowDiv.children.add(makeGap()); | |
| 597 rowDiv.children.add( | |
| 598 makeText(selfPercent, toolTip: 'global % executing')); | |
| 599 rowDiv.children.add(makeGap()); | |
| 600 rowDiv.children.add( | |
| 601 makeText(totalPercent, toolTip: 'global % on stack')); | |
| 602 rowDiv.children.add(makeGap()); | |
| 603 var functionRef = new Element.tag('function-ref'); | |
| 604 functionRef.ref = node.profileFunction.function; | |
| 605 rowDiv.children.add(functionRef); | |
| 606 } | |
| 607 | |
| 608 bool hasChildren() => node.children.length > 0; | |
| 609 | |
| 610 void onShow() { | |
| 611 if (children.length > 0) { | |
| 612 return; | |
| 613 } | |
| 614 for (var childNode in node.children) { | |
| 615 var row = new FunctionCallTreeNodeRow(tree, depth + 1, profile, childNode) ; | |
| 616 children.add(row); | |
| 617 } | |
| 618 } | |
| 619 } | |
| 620 | |
| 621 | |
| 622 class CodeCallTreeNodeRow extends VirtualTreeRow { | |
| 623 final CpuProfile profile; | |
| 624 final CodeCallTreeNode node; | |
| 625 final String selfPercent; | |
| 626 final String totalPercent; | |
| 627 final String percent; | |
| 628 | |
| 629 CodeCallTreeNodeRow(VirtualTree tree, | |
| 630 int depth, | |
| 631 this.profile, | |
| 632 CodeCallTreeNode node) | |
| 633 : node = node, | |
| 634 selfPercent = Utils.formatPercentNormalized(node.profileCode.normalizedE xclusiveTicks), | |
| 635 totalPercent = Utils.formatPercentNormalized(node.profileCode.normalized InclusiveTicks), | |
| 636 percent = Utils.formatPercentNormalized(node.percentage), | |
| 637 super(tree, depth) { | |
| 638 } | |
| 639 | |
| 640 void onRender(DivElement rowDiv) { | |
| 641 rowDiv.children.add(makeIndenter()); | |
| 642 rowDiv.children.add(makeColorBar()); | |
| 643 rowDiv.children.add(makeExpander()); | |
| 644 rowDiv.children.add( | |
| 645 makeText(percent, toolTip: 'tree node %')); | |
| 646 rowDiv.children.add(makeGap()); | |
| 647 rowDiv.children.add( | |
| 648 makeText(selfPercent, toolTip: 'global % executing')); | |
| 649 rowDiv.children.add(makeGap()); | |
| 650 rowDiv.children.add( | |
| 651 makeText(totalPercent, toolTip: 'global % on stack')); | |
| 652 rowDiv.children.add(makeGap()); | |
| 653 var codeRef = new Element.tag('code-ref'); | |
| 654 codeRef.ref = node.profileCode.code; | |
| 655 rowDiv.children.add(codeRef); | |
| 656 } | |
| 657 | |
| 658 bool hasChildren() => node.children.length > 0; | |
| 659 | |
| 660 void onShow() { | |
| 661 if (children.length > 0) { | |
| 662 return; | |
| 663 } | |
| 664 for (var childNode in node.children) { | |
| 665 var row = new CodeCallTreeNodeRow(tree, depth + 1, profile, childNode); | |
| 666 children.add(row); | |
| 667 } | |
| 668 } | |
| 669 } | |
| 670 | |
| 572 /// Displays a CpuProfile | 671 /// Displays a CpuProfile |
| 573 @CustomTag('cpu-profile') | 672 @CustomTag('cpu-profile') |
| 574 class CpuProfileElement extends ObservatoryElement { | 673 class CpuProfileElement extends ObservatoryElement { |
| 575 CpuProfileElement.created() : super.created() { | 674 CpuProfileElement.created() : super.created() { |
| 576 _updateTask = new Task(update); | 675 _updateTask = new Task(update); |
| 577 _renderTask = new Task(render); | 676 _renderTask = new Task(render); |
| 578 } | 677 } |
| 579 | 678 |
| 580 attached() { | 679 attached() { |
| 581 super.attached(); | 680 super.attached(); |
| 582 sampleBufferControlElement = | 681 sampleBufferControlElement = |
| 583 shadowRoot.querySelector('#sampleBufferControl'); | 682 shadowRoot.querySelector('#sampleBufferControl'); |
| 584 assert(sampleBufferControlElement != null); | 683 assert(sampleBufferControlElement != null); |
| 585 sampleBufferControlElement.onSampleBufferUpdate = onSampleBufferChange; | 684 sampleBufferControlElement.onSampleBufferUpdate = onSampleBufferChange; |
| 586 stackTraceTreeConfigElement = | 685 stackTraceTreeConfigElement = |
| 587 shadowRoot.querySelector('#stackTraceTreeConfig'); | 686 shadowRoot.querySelector('#stackTraceTreeConfig'); |
| 588 assert(stackTraceTreeConfigElement != null); | 687 assert(stackTraceTreeConfigElement != null); |
| 589 stackTraceTreeConfigElement.onTreeConfigChange = onTreeConfigChange; | 688 stackTraceTreeConfigElement.onTreeConfigChange = onTreeConfigChange; |
| 590 cpuProfileTreeElement = shadowRoot.querySelector('#cpuProfileTree'); | 689 cpuProfileVirtualTreeElement = shadowRoot.querySelector('#cpuProfileVirtualT ree'); |
| 591 assert(cpuProfileTreeElement != null); | 690 assert(cpuProfileVirtualTreeElement != null); |
| 592 cpuProfileTreeElement.profile = sampleBufferControlElement.profile; | 691 cpuProfileVirtualTreeElement.profile = sampleBufferControlElement.profile; |
| 593 _updateTask.queue(); | 692 _updateTask.queue(); |
| 594 } | 693 } |
| 595 | 694 |
| 596 isolateChanged(oldValue) { | 695 isolateChanged(oldValue) { |
| 597 _updateTask.queue(); | 696 _updateTask.queue(); |
| 598 } | 697 } |
| 599 | 698 |
| 600 update() { | 699 update() { |
| 601 if (sampleBufferControlElement != null) { | 700 if (sampleBufferControlElement != null) { |
| 602 sampleBufferControlElement.reload(isolate); | 701 sampleBufferControlElement.reload(isolate); |
| 603 } | 702 } |
| 604 } | 703 } |
| 605 | 704 |
| 606 onSampleBufferChange(CpuProfile sampleBuffer) { | 705 onSampleBufferChange(CpuProfile sampleBuffer) { |
| 607 _renderTask.queue(); | 706 _renderTask.queue(); |
| 608 } | 707 } |
| 609 | 708 |
| 610 onTreeConfigChange(String modeSelector, String directionSelector) { | 709 onTreeConfigChange(String modeSelector, String directionSelector) { |
| 611 ProfileTreeDirection direction = ProfileTreeDirection.Exclusive; | 710 ProfileTreeDirection direction = ProfileTreeDirection.Exclusive; |
| 612 if (directionSelector != 'Up') { | 711 if (directionSelector != 'Up') { |
| 613 direction = ProfileTreeDirection.Inclusive; | 712 direction = ProfileTreeDirection.Inclusive; |
| 614 } | 713 } |
| 615 ProfileTreeMode mode = ProfileTreeMode.Function; | 714 ProfileTreeMode mode = ProfileTreeMode.Function; |
| 616 if (modeSelector == 'Code') { | 715 if (modeSelector == 'Code') { |
| 617 mode = ProfileTreeMode.Code; | 716 mode = ProfileTreeMode.Code; |
| 618 } | 717 } |
| 619 cpuProfileTreeElement.direction = direction; | 718 cpuProfileVirtualTreeElement.direction = direction; |
| 620 cpuProfileTreeElement.mode = mode; | 719 cpuProfileVirtualTreeElement.mode = mode; |
| 621 _renderTask.queue(); | 720 _renderTask.queue(); |
| 622 } | 721 } |
| 623 | 722 |
| 624 Future clearCpuProfile() async { | 723 Future clearCpuProfile() async { |
| 625 await isolate.invokeRpc('_clearCpuProfile', { }); | 724 await isolate.invokeRpc('_clearCpuProfile', { }); |
| 626 _updateTask.queue(); | 725 _updateTask.queue(); |
| 627 return new Future.value(null); | 726 return new Future.value(null); |
| 628 } | 727 } |
| 629 | 728 |
| 630 Future refresh() { | 729 Future refresh() { |
| 631 _updateTask.queue(); | 730 _updateTask.queue(); |
| 632 return new Future.value(null); | 731 return new Future.value(null); |
| 633 } | 732 } |
| 634 | 733 |
| 635 render() { | 734 render() { |
| 636 cpuProfileTreeElement.render(); | 735 cpuProfileVirtualTreeElement.render(); |
| 637 } | 736 } |
| 638 | 737 |
| 639 @published Isolate isolate; | 738 @published Isolate isolate; |
| 640 | 739 |
| 641 Task _updateTask; | 740 Task _updateTask; |
| 642 Task _renderTask; | 741 Task _renderTask; |
| 643 SampleBufferControlElement sampleBufferControlElement; | 742 SampleBufferControlElement sampleBufferControlElement; |
| 644 StackTraceTreeConfigElement stackTraceTreeConfigElement; | 743 StackTraceTreeConfigElement stackTraceTreeConfigElement; |
| 645 CpuProfileTreeElement cpuProfileTreeElement; | 744 CpuProfileVirtualTreeElement cpuProfileVirtualTreeElement; |
| 646 } | 745 } |
| 647 | 746 |
| 648 class NameSortedTable extends SortedTable { | 747 class NameSortedTable extends SortedTable { |
| 649 NameSortedTable(columns) : super(columns); | 748 NameSortedTable(columns) : super(columns); |
| 650 @override | 749 @override |
| 651 dynamic getSortKeyFor(int row, int col) { | 750 dynamic getSortKeyFor(int row, int col) { |
| 652 if (col == FUNCTION_COLUMN) { | 751 if (col == FUNCTION_COLUMN) { |
| 653 // Use name as sort key. | 752 // Use name as sort key. |
| 654 return rows[row].values[col].name; | 753 return rows[row].values[col].name; |
| 655 } | 754 } |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 enum ProfileTreeDirection { | 1232 enum ProfileTreeDirection { |
| 1134 Exclusive, | 1233 Exclusive, |
| 1135 Inclusive | 1234 Inclusive |
| 1136 } | 1235 } |
| 1137 | 1236 |
| 1138 enum ProfileTreeMode { | 1237 enum ProfileTreeMode { |
| 1139 Code, | 1238 Code, |
| 1140 Function, | 1239 Function, |
| 1141 } | 1240 } |
| 1142 | 1241 |
| 1242 @CustomTag('cpu-profile-virtual-tree') | |
| 1243 class CpuProfileVirtualTreeElement extends ObservatoryElement { | |
| 1244 ProfileTreeDirection direction = ProfileTreeDirection.Exclusive; | |
| 1245 ProfileTreeMode mode = ProfileTreeMode.Function; | |
| 1246 CpuProfile profile; | |
| 1247 VirtualTree virtualTree; | |
| 1248 FunctionCallTreeNodeFilter functionFilter; | |
| 1249 @observable bool show = true; | |
| 1250 | |
| 1251 CpuProfileVirtualTreeElement.created() : super.created(); | |
| 1252 | |
| 1253 void render() { | |
| 1254 _updateView(); | |
| 1255 } | |
| 1256 | |
| 1257 showChanged(oldValue) { | |
| 1258 var treeTable = shadowRoot.querySelector('#treeTable'); | |
| 1259 assert(treeTable != null); | |
| 1260 treeTable.style.display = show ? 'table' : 'none'; | |
| 1261 } | |
| 1262 | |
| 1263 void _updateView() { | |
| 1264 virtualTree?.clear(); | |
| 1265 virtualTree?.uninstall(); | |
| 1266 virtualTree = null; | |
| 1267 bool exclusive = direction == ProfileTreeDirection.Exclusive; | |
| 1268 if (mode == ProfileTreeMode.Code) { | |
| 1269 _buildCodeTree(exclusive); | |
| 1270 } else { | |
| 1271 assert(mode == ProfileTreeMode.Function); | |
| 1272 _buildFunctionTree(exclusive); | |
| 1273 } | |
| 1274 virtualTree?.refresh(); | |
| 1275 } | |
| 1276 | |
| 1277 void _buildFunctionTree(bool exclusive) { | |
| 1278 var treeBody = shadowRoot.querySelector('#tree'); | |
| 1279 assert(treeBody != null); | |
| 1280 virtualTree = new VirtualTree(32, treeBody); | |
| 1281 if (profile == null) { | |
| 1282 return; | |
| 1283 } | |
| 1284 var tree = profile.loadFunctionTree(exclusive ? 'exclusive' : 'inclusive'); | |
| 1285 if (tree == null) { | |
| 1286 return; | |
| 1287 } | |
| 1288 if (functionFilter != null) { | |
| 1289 tree = tree.filtered(functionFilter); | |
| 1290 } | |
| 1291 for (var child in tree.root.children) { | |
| 1292 virtualTree.rows.add( | |
| 1293 new FunctionCallTreeNodeRow(virtualTree, 0, profile, child)); | |
| 1294 } | |
| 1295 } | |
| 1296 | |
| 1297 void _buildCodeTree(bool exclusive) { | |
| 1298 var treeBody = shadowRoot.querySelector('#tree'); | |
| 1299 assert(treeBody != null); | |
| 1300 virtualTree = new VirtualTree(32, treeBody); | |
| 1301 if (profile == null) { | |
| 1302 return; | |
| 1303 } | |
| 1304 var tree = profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive'); | |
| 1305 if (tree == null) { | |
| 1306 return; | |
| 1307 } | |
| 1308 for (var child in tree.root.children) { | |
| 1309 virtualTree.rows.add( | |
| 1310 new CodeCallTreeNodeRow(virtualTree, 0, profile, child)); | |
| 1311 } | |
| 1312 } | |
| 1313 } | |
| 1314 | |
| 1143 @CustomTag('cpu-profile-tree') | 1315 @CustomTag('cpu-profile-tree') |
| 1144 class CpuProfileTreeElement extends ObservatoryElement { | 1316 class CpuProfileTreeElement extends ObservatoryElement { |
| 1145 ProfileTreeDirection direction = ProfileTreeDirection.Exclusive; | 1317 ProfileTreeDirection direction = ProfileTreeDirection.Exclusive; |
| 1146 ProfileTreeMode mode = ProfileTreeMode.Function; | 1318 ProfileTreeMode mode = ProfileTreeMode.Function; |
| 1147 CpuProfile profile; | 1319 CpuProfile profile; |
| 1148 TableTree codeTree; | 1320 TableTree codeTree; |
| 1149 TableTree functionTree; | 1321 TableTree functionTree; |
| 1150 FunctionCallTreeNodeFilter functionFilter; | 1322 FunctionCallTreeNodeFilter functionFilter; |
| 1151 @observable bool show = true; | 1323 @observable bool show = true; |
| 1152 | 1324 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 return; | 1383 return; |
| 1212 } | 1384 } |
| 1213 var tree = profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive'); | 1385 var tree = profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive'); |
| 1214 if (tree == null) { | 1386 if (tree == null) { |
| 1215 return; | 1387 return; |
| 1216 } | 1388 } |
| 1217 var rootRow = new CodeProfileTreeRow(codeTree, null, profile, tree.root); | 1389 var rootRow = new CodeProfileTreeRow(codeTree, null, profile, tree.root); |
| 1218 codeTree.initialize(rootRow); | 1390 codeTree.initialize(rootRow); |
| 1219 } | 1391 } |
| 1220 } | 1392 } |
| OLD | NEW |