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

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

Issue 2204563003: Converted Observatory cpu-profile element (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Removed tmp files Created 4 years, 4 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:async';
6 import 'dart:html';
7 import 'dart:math' as Math;
8 import 'package:observatory/models.dart' as M;
9 import 'package:observatory/src/elements/stack_trace_tree_config.dart'
10 show ProfileTreeMode, ProfileTreeDirection;
11 import 'package:observatory/src/elements/code_ref.dart';
12 import 'package:observatory/src/elements/containers/virtual_tree.dart';
13 import 'package:observatory/src/elements/function_ref.dart';
14 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
15 import 'package:observatory/src/elements/helpers/tag.dart';
16 import 'package:observatory/utils.dart';
17
18 class CpuProfileVirtualTreeElement extends HtmlElement implements Renderable {
19 static const tag =
20 const Tag<CpuProfileVirtualTreeElement>('cpu-profile-virtual-tree');
21
22 RenderingScheduler<CpuProfileVirtualTreeElement> _r;
23
24 Stream<RenderedEvent<CpuProfileVirtualTreeElement>> get onRendered =>
25 _r.onRendered;
26
27 ProfileTreeDirection _direction;
28 ProfileTreeMode _mode;
29 M.Isolate _isolate;
30 M.SampleProfile _profile;
31 M.CallTreeNodeFilter _filter;
32
33 ProfileTreeDirection get direction => _direction;
34 ProfileTreeMode get mode => _mode;
35 M.Isolate get isolate => _isolate;
36 M.SampleProfile get profile => _profile;
37 M.CallTreeNodeFilter get filter => _filter;
38
39 set direction(ProfileTreeDirection value) =>
40 _direction = _r.checkAndReact(_direction, value);
41 set mode(ProfileTreeMode value) => _mode = _r.checkAndReact(_mode, value);
42 set filter(M.CallTreeNodeFilter value) =>
43 _filter = _r.checkAndReact(_filter, value);
44
45 factory CpuProfileVirtualTreeElement(M.IsolateRef isolate,
46 M.SampleProfile profile, {ProfileTreeMode mode: ProfileTreeMode.Function,
47 ProfileTreeDirection direction: ProfileTreeDirection.Exclusive,
48 RenderingQueue queue}) {
49 assert(isolate != null);
50 assert(profile != null);
51 assert(mode != null);
52 assert(direction != null);
53 CpuProfileVirtualTreeElement e = document.createElement(tag.name);
54 e._r = new RenderingScheduler(e, queue: queue);
55 e._isolate = isolate;
56 e._profile = profile;
57 e._mode = mode;
58 e._direction = direction;
59 return e;
60 }
61
62
63 CpuProfileVirtualTreeElement.created() : super.created();
64
65 @override
66 attached() {
67 super.attached();
68 _r.enable();
69 }
70
71 @override
72 detached() {
73 super.detached(); _r.disable(notify: true);
74 children = [];
75 }
76
77 void render() {
78 children = const [];
79 bool exclusive = direction == ProfileTreeDirection.Exclusive;
80 switch (mode) {
81 case ProfileTreeMode.Code:
82 _buildCodeTree(exclusive);
83 break;
84 case ProfileTreeMode.Function:
85 _buildFunctionTree(exclusive);
86 break;
87 default:
88 throw new Exception('Unknown ProfileTreeMode');
89 }
90 }
91
92 static const kHotThreshold = 0.05; // 5%.
93 static const kMediumThreshold = 0.02; // 2%.
94
95 void _buildFunctionTree(bool exclusive) {
96 var tree = _profile.loadFunctionTree(exclusive ? 'exclusive' : 'inclusive');
97 if (tree == null) {
98 return;
99 }
100 if (filter != null) {
101 tree = tree.filtered(filter);
102 }
103 var t;
104 children = [
105 t = new VirtualTreeElement((toggle) {
Cutch 2016/08/02 15:52:20 could this closure be turned into a named method?
cbernaschina 2016/08/02 17:40:24 Done.
106 return new DivElement()
107 ..classes = const ['tmp-collection-item']
108 ..children = [
109 new SpanElement()..classes = const ['inclusive']
110 ..title = 'global % on stack',
111 new SpanElement()..classes = const ['exclusive']
112 ..title = 'global % executing',
113 new SpanElement()..classes = const ['lines'],
114 new SpanElement()..classes = const ['expander']
115 ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
116 new SpanElement()..classes = const ['percentage']
117 ..title = 'tree node %',
118 new SpanElement()..classes = const ['name']
119 ];
120 }, (HtmlElement element, M.FunctionCallTreeNode item, int depth) {
121 element.children[0].text = Utils.formatPercentNormalized(
122 item.profileFunction.normalizedInclusiveTicks);
123 element.children[1].text = Utils.formatPercentNormalized(
124 item.profileFunction.normalizedExclusiveTicks);
125 _updateLines(element.children[2].children, depth);
126 if (item.children.isNotEmpty) {
127 element.children[3].text = t.isExpanded(item) ? '▼' : '►';
128 } else {
129 element.children[3].text = '';
130 }
131 element.children[4].text = Utils.formatPercentNormalized(
132 item.percentage);
133 element.children[5] = new FunctionRefElement(_isolate,
134 item.profileFunction.function, queue: _r.queue)
135 ..classes = const ['name'];
136 }, (M.FunctionCallTreeNode node) => node.children,
137 items: tree.root.children, queue: _r.queue)
138 ];
139 if (tree.root.children.length == 1) {
140 t.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
141 }
142 }
143
144
145
146 void _buildCodeTree(bool exclusive) {
147 var tree = _profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive');
148 if (tree == null) {
149 return;
150 }
151 if (filter != null) {
152 tree = tree.filtered(filter);
153 }
154 var t;
155 children = [
156 t = new VirtualTreeElement((toggle) {
Cutch 2016/08/02 15:52:20 could this closure be turned into a named method?
cbernaschina 2016/08/02 17:40:24 Done.
157 return new DivElement()
158 ..classes = const ['tmp-collection-item']
159 ..children = [
160 new SpanElement()..classes = const ['inclusive']
161 ..title = 'global % on stack',
162 new SpanElement()..classes = const ['exclusive']
163 ..title = 'global % executing',
164 new SpanElement()..classes = const ['lines'],
165 new SpanElement()..classes = const ['expander']
166 ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
167 new SpanElement()..classes = const ['percentage']
168 ..title = 'tree node %',
169 new AnchorElement()..classes = const ['name']
170 ];
171 }, (HtmlElement element, M.CodeCallTreeNode item, int depth) {
172 element.children[0].text = Utils.formatPercentNormalized(
173 item.profileCode.normalizedInclusiveTicks);
174 element.children[1].text = Utils.formatPercentNormalized(
175 item.profileCode.normalizedExclusiveTicks);
176 _updateLines(element.children[2].children, depth);
177 if (item.children.isNotEmpty) {
178 element.children[3].text = t.isExpanded(item) ? '▼' : '►';
179 } else {
180 element.children[3].text = '';
181 }
182 element.children[4].text = Utils.formatPercentNormalized(
183 item.percentage);
184 element.children[5] = new CodeRefElement(_isolate,
185 item.profileCode.code, queue: _r.queue)
186 ..classes = const ['name'];
187 }, (M.CodeCallTreeNode node) => node.children,
188 items: tree.root.children, queue: _r.queue)
189 ];
190 if (tree.root.children.length == 1) {
191 t.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
192 }
193 }
194
195 static _updateLines(List<Element> lines, int n) {
196 n = Math.max(0, n);
197 while (lines.length > n) {
198 lines.removeLast();
199 }
200 while (lines.length < n) {
201 lines.add(new SpanElement());
202 }
203 }
204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698