Chromium Code Reviews| Index: runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart |
| diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart |
| index d271ec2059cf83093997f59a156bfef6e517ca89..b3d048832cea9c485d1c13affefd5f5382efc28a 100644 |
| --- a/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart |
| +++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/isolate_profile.dart |
| @@ -6,8 +6,50 @@ library isolate_profile_element; |
| import 'dart:html'; |
| import 'package:logging/logging.dart'; |
| +import 'package:observatory/observatory.dart'; |
| import 'package:polymer/polymer.dart'; |
| import 'observatory_element.dart'; |
| +import 'table_tree.dart'; |
| + |
| +class ProfileTreeRow extends TableTreeRow { |
| + final Isolate isolate; |
| + final Code code; |
| + ProfileTreeRow(this.isolate, this.code, ProfileTreeRow parent) : |
| + super(parent) { |
| + // When the row is created, fill out the columns. |
| + columns.add('${code.user_name} ${code.name}'); |
| + var percent = 100.0 * |
| + (code.exclusiveTicks / isolate.profile.totalSamples); |
| + columns.add(percent.toStringAsFixed(2)); |
| + if (parent == null) { |
| + // Fill with dummy data. |
| + columns.add(' '); |
| + } else { |
| + var totalAttributedCalls = parent.code.callersCount(code); |
| + var totalParentCalls = parent.code.sumCallersCount(); |
| + percent = 100.0 * (totalAttributedCalls / totalParentCalls); |
| + columns.add(percent.toStringAsFixed(2)); |
| + } |
| + percent = 100.0 * |
| + (code.inclusiveTicks / isolate.profile.totalSamples); |
| + columns.add(percent.toStringAsFixed(2)); |
| + } |
| + |
| + void onShow() { |
| + if (children.length > 0) { |
| + // Child rows already created. |
| + return; |
| + } |
| + // Create child rows on demand. |
| + code.callers.forEach((CodeCaller codeCaller) { |
| + var row = new ProfileTreeRow(isolate, codeCaller.code_or_index, this); |
| + children.add(row); |
| + }); |
| + } |
| + |
| + void onHide() { |
| + } |
| +} |
| /// Displays an IsolateProfile |
| @CustomTag('isolate-profile') |
| @@ -15,8 +57,8 @@ class IsolateProfileElement extends ObservatoryElement { |
| IsolateProfileElement.created() : super.created(); |
| @observable int methodCountSelected = 0; |
| final List methodCounts = [10, 20, 50]; |
| - @observable List topInclusiveCodes = toObservable([]); |
| @observable List topExclusiveCodes = toObservable([]); |
| + final _id = '#tableTree'; |
| void enteredView() { |
| var isolateId = app.locationManager.currentIsolateId(); |
| @@ -24,7 +66,11 @@ class IsolateProfileElement extends ObservatoryElement { |
| if (isolate == null) { |
| return; |
| } |
| - _refreshTopMethods(isolate); |
| + var tree = |
| + new TableTree(['Method', 'Exclusive', 'Caller', 'Inclusive']); |
| + var tte = shadowRoot.querySelector(_id); |
|
turnidge
2014/02/24 20:13:00
I can guess what this does, but I want to chat abo
|
| + tte.tree = tree; |
| + _refresh(isolate); |
| } |
| void _startRequest() { |
| @@ -35,13 +81,13 @@ class IsolateProfileElement extends ObservatoryElement { |
| // TODO(johnmccutchan): Indicate visually. |
| } |
| - methodCountSelectedChanged(oldValue) {; |
| + methodCountSelectedChanged(oldValue) { |
| var isolateId = app.locationManager.currentIsolateId(); |
| var isolate = app.isolateManager.getIsolate(isolateId); |
| if (isolate == null) { |
| return; |
| } |
| - _refreshTopMethods(isolate); |
| + _refresh(isolate); |
| } |
| void refreshData(Event e, var detail, Node target) { |
| @@ -66,48 +112,32 @@ class IsolateProfileElement extends ObservatoryElement { |
| void _loadProfileData(Isolate isolate, int totalSamples, Map response) { |
| isolate.profile = new Profile.fromMap(isolate, response); |
| + _refresh(isolate); |
| + } |
| + |
| + void _refresh(Isolate isolate) { |
| _refreshTopMethods(isolate); |
| + _refreshTree(isolate); |
| } |
| + void _refreshTree(Isolate isolate) { |
| + TableTreeElement tte = shadowRoot.querySelector(_id); |
| + var rootChildren = []; |
| + for (var code in topExclusiveCodes) { |
| + var row = new ProfileTreeRow(isolate, code, null); |
| + rootChildren.add(row); |
| + } |
| + tte.tree.initialize(rootChildren); |
| + } |
| + |
| + |
| void _refreshTopMethods(Isolate isolate) { |
| topExclusiveCodes.clear(); |
| - topInclusiveCodes.clear(); |
| if ((isolate == null) || (isolate.profile == null)) { |
| return; |
| } |
| var count = methodCounts[methodCountSelected]; |
| var topExclusive = isolate.profile.topExclusive(count); |
| topExclusiveCodes.addAll(topExclusive); |
| - var topInclusive = isolate.profile.topInclusive(count); |
| - topInclusiveCodes.addAll(topInclusive); |
| - |
| - } |
| - |
| - String codeTicks(Code code, bool inclusive) { |
| - if (code == null) { |
| - return ''; |
| - } |
| - return inclusive ? '${code.inclusiveTicks}' : '${code.exclusiveTicks}'; |
| - } |
| - |
| - String codePercent(Code code, bool inclusive) { |
| - if (code == null) { |
| - return ''; |
| - } |
| - var isolateId = app.locationManager.currentIsolateId(); |
| - var isolate = app.isolateManager.getIsolate(isolateId); |
| - if (isolate == null) { |
| - return ''; |
| - } |
| - var ticks = inclusive ? code.inclusiveTicks : code.exclusiveTicks; |
| - var total = ticks / isolate.profile.totalSamples; |
| - return (total * 100.0).toStringAsFixed(2); |
| - } |
| - |
| - String codeName(Code code) { |
| - if ((code == null) || (code.name == null)) { |
| - return ''; |
| - } |
| - return code.name; |
| } |
| } |