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 code_view_element; | 5 library code_view_element; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:html'; | 8 import 'dart:html'; |
9 import 'package:observatory/cpu_profile.dart'; | 9 import 'package:observatory/cpu_profile.dart'; |
10 import 'package:observatory/service.dart' as S; | 10 import 'package:observatory/service.dart' as S; |
11 import 'package:observatory/models.dart' as M; | 11 import 'package:observatory/models.dart' as M; |
12 import 'package:observatory/app.dart' | 12 import 'package:observatory/app.dart' |
13 show SortedTable, SortedTableColumn, SortedTableRow; | 13 show SortedTable, SortedTableColumn, SortedTableRow; |
14 import 'package:observatory/src/elements/curly_block.dart'; | 14 import 'package:observatory/src/elements/curly_block.dart'; |
15 import 'package:observatory/src/elements/function_ref.dart'; | 15 import 'package:observatory/src/elements/function_ref.dart'; |
16 import 'package:observatory/src/elements/helpers/any_ref.dart'; | 16 import 'package:observatory/src/elements/helpers/any_ref.dart'; |
17 import 'package:observatory/src/elements/helpers/nav_bar.dart'; | 17 import 'package:observatory/src/elements/helpers/nav_bar.dart'; |
18 import 'package:observatory/src/elements/helpers/nav_menu.dart'; | 18 import 'package:observatory/src/elements/helpers/nav_menu.dart'; |
19 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | 19 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
20 import 'package:observatory/src/elements/helpers/tag.dart'; | 20 import 'package:observatory/src/elements/helpers/tag.dart'; |
21 import 'package:observatory/src/elements/nav/class_menu.dart'; | 21 import 'package:observatory/src/elements/nav/class_menu.dart'; |
22 import 'package:observatory/src/elements/nav/isolate_menu.dart'; | 22 import 'package:observatory/src/elements/nav/isolate_menu.dart'; |
23 import 'package:observatory/src/elements/nav/notify.dart'; | 23 import 'package:observatory/src/elements/nav/notify.dart'; |
24 import 'package:observatory/src/elements/nav/refresh.dart'; | 24 import 'package:observatory/src/elements/nav/refresh.dart'; |
25 import 'package:observatory/src/elements/nav/top_menu.dart'; | 25 import 'package:observatory/src/elements/nav/top_menu.dart'; |
26 import 'package:observatory/src/elements/nav/vm_menu.dart'; | 26 import 'package:observatory/src/elements/nav/vm_menu.dart'; |
27 import 'package:observatory/src/elements/object_common.dart'; | 27 import 'package:observatory/src/elements/object_common.dart'; |
28 import 'package:observatory/src/elements/objectpool_ref.dart'; | 28 import 'package:observatory/src/elements/objectpool_ref.dart'; |
29 import 'package:observatory/utils.dart'; | 29 import 'package:observatory/utils.dart'; |
30 | 30 |
31 class DisassemblyTable extends SortedTable { | 31 class DisassemblyTable extends SortedTable { |
32 DisassemblyTable(columns) : super(columns); | 32 DisassemblyTable(columns) : super(columns); |
33 } | 33 } |
34 | 34 |
35 class InlineTable extends SortedTable { | 35 class InlineTable extends SortedTable { |
36 InlineTable(columns) : super(columns); | 36 InlineTable(columns) : super(columns); |
37 } | 37 } |
38 | 38 |
39 class CodeViewElement extends HtmlElement implements Renderable { | 39 class CodeViewElement extends HtmlElement implements Renderable { |
40 static const tag = const Tag<CodeViewElement>('code-view', | 40 static const tag = |
41 dependencies: const [ | 41 const Tag<CodeViewElement>('code-view', dependencies: const [ |
42 CurlyBlockElement.tag, | 42 CurlyBlockElement.tag, |
43 FunctionRefElement.tag, | 43 FunctionRefElement.tag, |
44 NavClassMenuElement.tag, | 44 NavClassMenuElement.tag, |
45 NavTopMenuElement.tag, | 45 NavTopMenuElement.tag, |
46 NavVMMenuElement.tag, | 46 NavVMMenuElement.tag, |
47 NavIsolateMenuElement.tag, | 47 NavIsolateMenuElement.tag, |
48 NavRefreshElement.tag, | 48 NavRefreshElement.tag, |
49 NavNotifyElement.tag, | 49 NavNotifyElement.tag, |
50 ObjectCommonElement.tag, | 50 ObjectCommonElement.tag, |
51 ObjectPoolRefElement.tag, | 51 ObjectPoolRefElement.tag, |
52 ]); | 52 ]); |
53 | 53 |
54 RenderingScheduler<CodeViewElement> _r; | 54 RenderingScheduler<CodeViewElement> _r; |
55 | 55 |
56 Stream<RenderedEvent<CodeViewElement>> get onRendered => _r.onRendered; | 56 Stream<RenderedEvent<CodeViewElement>> get onRendered => _r.onRendered; |
57 | 57 |
58 M.VM _vm; | 58 M.VM _vm; |
59 M.IsolateRef _isolate; | 59 M.IsolateRef _isolate; |
60 M.EventRepository _events; | 60 M.EventRepository _events; |
61 M.NotificationRepository _notifications; | 61 M.NotificationRepository _notifications; |
62 M.Code _code; | 62 M.Code _code; |
63 M.RetainedSizeRepository _retainedSizes; | 63 M.RetainedSizeRepository _retainedSizes; |
64 M.ReachableSizeRepository _reachableSizes; | 64 M.ReachableSizeRepository _reachableSizes; |
65 M.InboundReferencesRepository _references; | 65 M.InboundReferencesRepository _references; |
66 M.RetainingPathRepository _retainingPaths; | 66 M.RetainingPathRepository _retainingPaths; |
67 M.InstanceRepository _instances; | 67 M.InstanceRepository _instances; |
68 DisassemblyTable disassemblyTable; | 68 DisassemblyTable disassemblyTable; |
69 InlineTable inlineTable; | 69 InlineTable inlineTable; |
70 | 70 |
71 static const kDisassemblyColumnIndex = 3; | 71 static const kDisassemblyColumnIndex = 3; |
72 | 72 |
73 | |
74 M.VMRef get vm => _vm; | 73 M.VMRef get vm => _vm; |
75 M.IsolateRef get isolate => _isolate; | 74 M.IsolateRef get isolate => _isolate; |
76 M.NotificationRepository get notifications => _notifications; | 75 M.NotificationRepository get notifications => _notifications; |
77 M.Code get context => _code; | 76 M.Code get context => _code; |
78 | 77 |
79 factory CodeViewElement(M.VM vm, M.IsolateRef isolate, M.Code code, | 78 factory CodeViewElement( |
80 M.EventRepository events, | 79 M.VM vm, |
81 M.NotificationRepository notifications, | 80 M.IsolateRef isolate, |
82 M.RetainedSizeRepository retainedSizes, | 81 M.Code code, |
83 M.ReachableSizeRepository reachableSizes, | 82 M.EventRepository events, |
84 M.InboundReferencesRepository references, | 83 M.NotificationRepository notifications, |
85 M.RetainingPathRepository retainingPaths, | 84 M.RetainedSizeRepository retainedSizes, |
86 M.InstanceRepository instances, | 85 M.ReachableSizeRepository reachableSizes, |
87 {RenderingQueue queue}) { | 86 M.InboundReferencesRepository references, |
| 87 M.RetainingPathRepository retainingPaths, |
| 88 M.InstanceRepository instances, |
| 89 {RenderingQueue queue}) { |
88 assert(vm != null); | 90 assert(vm != null); |
89 assert(isolate != null); | 91 assert(isolate != null); |
90 assert(events != null); | 92 assert(events != null); |
91 assert(notifications != null); | 93 assert(notifications != null); |
92 assert(code != null); | 94 assert(code != null); |
93 assert(instances != null); | 95 assert(instances != null); |
94 assert(retainedSizes != null); | 96 assert(retainedSizes != null); |
95 assert(reachableSizes != null); | 97 assert(reachableSizes != null); |
96 assert(references != null); | 98 assert(references != null); |
97 assert(retainingPaths != null); | 99 assert(retainingPaths != null); |
98 CodeViewElement e = document.createElement(tag.name); | 100 CodeViewElement e = document.createElement(tag.name); |
99 e._r = new RenderingScheduler(e, queue: queue); | 101 e._r = new RenderingScheduler(e, queue: queue); |
100 e._vm = vm; | 102 e._vm = vm; |
101 e._isolate = isolate; | 103 e._isolate = isolate; |
102 e._events = events; | 104 e._events = events; |
103 e._notifications = notifications; | 105 e._notifications = notifications; |
104 e._code = code; | 106 e._code = code; |
105 e._instances = instances; | 107 e._instances = instances; |
106 e._retainedSizes = retainedSizes; | 108 e._retainedSizes = retainedSizes; |
107 e._reachableSizes = reachableSizes; | 109 e._reachableSizes = reachableSizes; |
108 e._references = references; | 110 e._references = references; |
109 e._retainingPaths = retainingPaths; | 111 e._retainingPaths = retainingPaths; |
110 return e; | 112 return e; |
111 } | 113 } |
112 | 114 |
113 CodeViewElement.created() : super.created() { | 115 CodeViewElement.created() : super.created() { |
114 var columns = [ | 116 var columns = [ |
115 new SortedTableColumn('Address'), | 117 new SortedTableColumn('Address'), |
116 new SortedTableColumn('Inclusive'), | 118 new SortedTableColumn('Inclusive'), |
117 new SortedTableColumn('Exclusive'), | 119 new SortedTableColumn('Exclusive'), |
118 new SortedTableColumn('Disassembly'), | 120 new SortedTableColumn('Disassembly'), |
119 new SortedTableColumn('Objects'), | 121 new SortedTableColumn('Objects'), |
120 ]; | 122 ]; |
121 disassemblyTable = new DisassemblyTable(columns); | 123 disassemblyTable = new DisassemblyTable(columns); |
122 columns = [ | 124 columns = [ |
123 new SortedTableColumn('Address'), | 125 new SortedTableColumn('Address'), |
124 new SortedTableColumn('Inclusive'), | 126 new SortedTableColumn('Inclusive'), |
125 new SortedTableColumn('Exclusive'), | 127 new SortedTableColumn('Exclusive'), |
126 new SortedTableColumn('Functions'), | 128 new SortedTableColumn('Functions'), |
127 ]; | 129 ]; |
128 inlineTable = new InlineTable(columns); | 130 inlineTable = new InlineTable(columns); |
129 } | 131 } |
130 | 132 |
131 @override | 133 @override |
132 attached() { | 134 attached() { |
133 super.attached(); | 135 super.attached(); |
134 _r.enable(); | 136 _r.enable(); |
135 } | 137 } |
136 | 138 |
137 @override | 139 @override |
138 detached() { | 140 detached() { |
139 super.detached(); | 141 super.detached(); |
140 _r.disable(notify: true); | 142 _r.disable(notify: true); |
141 children = []; | 143 children = []; |
142 } | 144 } |
143 | 145 |
144 TableElement _disassemblyTable; | 146 TableElement _disassemblyTable; |
145 TableElement _inlineRangeTable; | 147 TableElement _inlineRangeTable; |
146 Element _disassemblyTableBody; | 148 Element _disassemblyTableBody; |
147 Element _inlineRangeTableBody; | 149 Element _inlineRangeTableBody; |
148 | 150 |
149 void render() { | 151 void render() { |
150 if (_inlineRangeTable == null) { | 152 if (_inlineRangeTable == null) { |
151 _inlineRangeTable = new TableElement()..classes = ['table']; | 153 _inlineRangeTable = new TableElement()..classes = ['table']; |
152 _inlineRangeTable.createTHead() | 154 _inlineRangeTable.createTHead().children = [ |
153 .children = [ | 155 new TableRowElement() |
154 new TableRowElement() | 156 ..children = [ |
155 ..children = [ | 157 document.createElement('th') |
156 document.createElement('th')..classes = ['address'] | 158 ..classes = ['address'] |
157 ..text = 'Address Range', | 159 ..text = 'Address Range', |
158 document.createElement('th')..classes = ['tick'] | 160 document.createElement('th') |
159 ..text = 'Inclusive', | 161 ..classes = ['tick'] |
160 document.createElement('th')..classes = ['tick'] | 162 ..text = 'Inclusive', |
161 ..text = 'Exclusive', | 163 document.createElement('th') |
162 document.createElement('th') | 164 ..classes = ['tick'] |
163 ..text = 'Functions', | 165 ..text = 'Exclusive', |
164 ] | 166 document.createElement('th')..text = 'Functions', |
165 ]; | 167 ] |
| 168 ]; |
166 _inlineRangeTableBody = _inlineRangeTable.createTBody(); | 169 _inlineRangeTableBody = _inlineRangeTable.createTBody(); |
167 _inlineRangeTableBody.classes = ['monospace']; | 170 _inlineRangeTableBody.classes = ['monospace']; |
168 } | 171 } |
169 if (_disassemblyTable == null) { | 172 if (_disassemblyTable == null) { |
170 _disassemblyTable = new TableElement()..classes = ['table']; | 173 _disassemblyTable = new TableElement()..classes = ['table']; |
171 _disassemblyTable.createTHead() | 174 _disassemblyTable.createTHead().children = [ |
172 .children = [ | 175 new TableRowElement() |
173 new TableRowElement() | 176 ..children = [ |
174 ..children = [ | 177 document.createElement('th') |
175 document.createElement('th')..classes = ['address'] | 178 ..classes = ['address'] |
176 ..text = 'Address Range', | 179 ..text = 'Address Range', |
177 document.createElement('th')..classes = ['tick'] | 180 document.createElement('th') |
178 ..title = 'Ticks with PC on the stack' | 181 ..classes = ['tick'] |
179 ..text = 'Inclusive', | 182 ..title = 'Ticks with PC on the stack' |
180 document.createElement('th')..classes = ['tick'] | 183 ..text = 'Inclusive', |
181 ..title = 'Ticks with PC at top of stack' | 184 document.createElement('th') |
182 ..text = 'Exclusive', | 185 ..classes = ['tick'] |
183 document.createElement('th')..classes = ['disassembly'] | 186 ..title = 'Ticks with PC at top of stack' |
184 ..text = 'Disassembly', | 187 ..text = 'Exclusive', |
185 document.createElement('th')..classes = ['object'] | 188 document.createElement('th') |
186 ..text = 'Object', | 189 ..classes = ['disassembly'] |
187 ] | 190 ..text = 'Disassembly', |
188 ]; | 191 document.createElement('th') |
| 192 ..classes = ['object'] |
| 193 ..text = 'Object', |
| 194 ] |
| 195 ]; |
189 _disassemblyTableBody = _disassemblyTable.createTBody(); | 196 _disassemblyTableBody = _disassemblyTable.createTBody(); |
190 _disassemblyTableBody.classes = ['monospace']; | 197 _disassemblyTableBody.classes = ['monospace']; |
191 } | 198 } |
192 final inlinedFunctions = _code.inlinedFunctions.toList(); | 199 final inlinedFunctions = _code.inlinedFunctions.toList(); |
193 final S.Code code = _code as S.Code; | 200 final S.Code code = _code as S.Code; |
194 children = [ | 201 children = [ |
195 navBar([ | 202 navBar([ |
196 new NavTopMenuElement(queue: _r.queue), | 203 new NavTopMenuElement(queue: _r.queue), |
197 new NavVMMenuElement(_vm, _events, queue: _r.queue), | 204 new NavVMMenuElement(_vm, _events, queue: _r.queue), |
198 new NavIsolateMenuElement(_isolate, _events, queue: _r.queue), | 205 new NavIsolateMenuElement(_isolate, _events, queue: _r.queue), |
199 navMenu(_code.name), | 206 navMenu(_code.name), |
200 new NavRefreshElement(queue: _r.queue) | 207 new NavRefreshElement(queue: _r.queue) |
201 ..onRefresh.listen((e) async { | 208 ..onRefresh.listen((e) async { |
202 e.element.disabled = true; | 209 e.element.disabled = true; |
203 _refresh(); | 210 _refresh(); |
204 }), | 211 }), |
205 new NavRefreshElement(label: 'refresh ticks', queue: _r.queue) | 212 new NavRefreshElement(label: 'refresh ticks', queue: _r.queue) |
206 ..onRefresh.listen((e) async { | 213 ..onRefresh.listen((e) async { |
207 e.element.disabled = true; | 214 e.element.disabled = true; |
208 _refreshTicks(); | 215 _refreshTicks(); |
209 }), | 216 }), |
210 new NavNotifyElement(_notifications, queue: _r.queue) | 217 new NavNotifyElement(_notifications, queue: _r.queue) |
211 ]), | 218 ]), |
212 new DivElement()..classes = ['content-centered-big'] | 219 new DivElement() |
| 220 ..classes = ['content-centered-big'] |
213 ..children = [ | 221 ..children = [ |
214 new HeadingElement.h1() | 222 new HeadingElement.h1() |
215 ..text = (M.isDartCode(_code.kind) && _code.isOptimized) | 223 ..text = (M.isDartCode(_code.kind) && _code.isOptimized) |
216 ? 'Optimized code for ${_code.name}' | 224 ? 'Optimized code for ${_code.name}' |
217 : 'Code for ${_code.name}', | 225 : 'Code for ${_code.name}', |
218 new HRElement(), | 226 new HRElement(), |
219 new ObjectCommonElement(_isolate, _code, _retainedSizes, | 227 new ObjectCommonElement(_isolate, _code, _retainedSizes, |
220 _reachableSizes, _references, _retainingPaths, | 228 _reachableSizes, _references, _retainingPaths, _instances, |
221 _instances, queue: _r.queue), | 229 queue: _r.queue), |
222 new BRElement(), | 230 new BRElement(), |
223 new DivElement()..classes = ['memberList'] | 231 new DivElement() |
| 232 ..classes = ['memberList'] |
224 ..children = [ | 233 ..children = [ |
225 new DivElement()..classes = ['memberItem'] | 234 new DivElement() |
| 235 ..classes = ['memberItem'] |
226 ..children = [ | 236 ..children = [ |
227 new DivElement()..classes = ['memberName'] | 237 new DivElement() |
228 ..text = 'Kind', | 238 ..classes = ['memberName'] |
229 new DivElement()..classes = ['memberValue'] | 239 ..text = 'Kind', |
230 ..text = _codeKindToString(_code.kind) | 240 new DivElement() |
| 241 ..classes = ['memberValue'] |
| 242 ..text = _codeKindToString(_code.kind) |
231 ], | 243 ], |
232 new DivElement()..classes = ['memberItem'] | 244 new DivElement() |
| 245 ..classes = ['memberItem'] |
233 ..children = M.isDartCode(_code.kind) | 246 ..children = M.isDartCode(_code.kind) |
234 ? const [] | 247 ? const [] |
235 : [ | 248 : [ |
236 new DivElement()..classes = ['memberName'] | 249 new DivElement() |
237 ..text = 'Optimized', | 250 ..classes = ['memberName'] |
238 new DivElement()..classes = ['memberValue'] | 251 ..text = 'Optimized', |
239 ..text = _code.isOptimized ? 'Yes' : 'No' | 252 new DivElement() |
240 ], | 253 ..classes = ['memberValue'] |
241 new DivElement()..classes = ['memberItem'] | 254 ..text = _code.isOptimized ? 'Yes' : 'No' |
| 255 ], |
| 256 new DivElement() |
| 257 ..classes = ['memberItem'] |
242 ..children = [ | 258 ..children = [ |
243 new DivElement()..classes = ['memberName'] | 259 new DivElement() |
244 ..text = 'Function', | 260 ..classes = ['memberName'] |
245 new DivElement()..classes = ['memberValue'] | 261 ..text = 'Function', |
246 ..children = [ | 262 new DivElement() |
247 new FunctionRefElement(_isolate, _code.function, | 263 ..classes = ['memberValue'] |
248 queue: _r.queue) | 264 ..children = [ |
| 265 new FunctionRefElement(_isolate, _code.function, |
| 266 queue: _r.queue) |
| 267 ] |
| 268 ], |
| 269 new DivElement() |
| 270 ..classes = ['memberItem'] |
| 271 ..children = code.profile == null |
| 272 ? const [] |
| 273 : [ |
| 274 new DivElement() |
| 275 ..classes = ['memberName'] |
| 276 ..text = 'Inclusive', |
| 277 new DivElement() |
| 278 ..classes = ['memberValue'] |
| 279 ..text = '${code.profile.formattedInclusiveTicks}' |
| 280 ], |
| 281 new DivElement() |
| 282 ..classes = ['memberItem'] |
| 283 ..children = code.profile == null |
| 284 ? const [] |
| 285 : [ |
| 286 new DivElement() |
| 287 ..classes = ['memberName'] |
| 288 ..text = 'Exclusive', |
| 289 new DivElement() |
| 290 ..classes = ['memberValue'] |
| 291 ..text = '${code.profile.formattedExclusiveTicks}' |
| 292 ], |
| 293 new DivElement() |
| 294 ..classes = ['memberItem'] |
| 295 ..children = [ |
| 296 new DivElement() |
| 297 ..classes = ['memberName'] |
| 298 ..text = 'Object pool', |
| 299 new DivElement() |
| 300 ..classes = ['memberValue'] |
| 301 ..children = [ |
| 302 new ObjectPoolRefElement(_isolate, _code.objectPool, |
| 303 queue: _r.queue) |
| 304 ] |
| 305 ], |
| 306 new DivElement() |
| 307 ..classes = ['memberItem'] |
| 308 ..children = inlinedFunctions.isNotEmpty |
| 309 ? const [] |
| 310 : [ |
| 311 new DivElement() |
| 312 ..classes = ['memberName'] |
| 313 ..text = |
| 314 'inlined functions (${inlinedFunctions.length})', |
| 315 new DivElement() |
| 316 ..classes = ['memberValue'] |
| 317 ..children = [ |
| 318 new CurlyBlockElement( |
| 319 expanded: inlinedFunctions.length < 8, |
| 320 queue: _r.queue) |
| 321 ..content = inlinedFunctions |
| 322 .map((f) => new FunctionRefElement( |
| 323 _isolate, f, |
| 324 queue: _r.queue)) |
| 325 .toList() |
| 326 ] |
249 ] | 327 ] |
250 ], | |
251 new DivElement()..classes = ['memberItem'] | |
252 ..children = code.profile == null | |
253 ? const [] | |
254 : [ | |
255 new DivElement()..classes = ['memberName'] | |
256 ..text = 'Inclusive', | |
257 new DivElement()..classes = ['memberValue'] | |
258 ..text = '${code.profile.formattedInclusiveTicks}' | |
259 ], | |
260 new DivElement()..classes = ['memberItem'] | |
261 ..children = code.profile == null | |
262 ? const [] | |
263 : [ | |
264 new DivElement()..classes = ['memberName'] | |
265 ..text = 'Exclusive', | |
266 new DivElement()..classes = ['memberValue'] | |
267 ..text = '${code.profile.formattedExclusiveTicks}' | |
268 ], | |
269 new DivElement()..classes = ['memberItem'] | |
270 ..children = [ | |
271 new DivElement()..classes = ['memberName'] | |
272 ..text = 'Object pool', | |
273 new DivElement()..classes = ['memberValue'] | |
274 ..children = [ | |
275 new ObjectPoolRefElement(_isolate, _code.objectPool, | |
276 queue: _r.queue) | |
277 ] | |
278 ], | |
279 new DivElement()..classes = ['memberItem'] | |
280 ..children = inlinedFunctions.isNotEmpty | |
281 ? const [] | |
282 : [ | |
283 new DivElement()..classes = ['memberName'] | |
284 ..text = 'inlined functions (${inlinedFunctions.length})', | |
285 new DivElement()..classes = ['memberValue'] | |
286 ..children = [ | |
287 new CurlyBlockElement( | |
288 expanded: inlinedFunctions.length < 8, | |
289 queue: _r.queue) | |
290 ..content = inlinedFunctions.map((f) => | |
291 new FunctionRefElement(_isolate, f, queue: _r.queue) | |
292 ).toList() | |
293 ] | |
294 ] | |
295 ], | 328 ], |
296 new HRElement(), | 329 new HRElement(), |
297 _inlineRangeTable, | 330 _inlineRangeTable, |
298 new HRElement(), | 331 new HRElement(), |
299 _disassemblyTable | 332 _disassemblyTable |
300 ], | 333 ], |
301 ]; | 334 ]; |
302 _updateDisassembly(); | 335 _updateDisassembly(); |
303 _updateInline(); | 336 _updateInline(); |
304 } | 337 } |
305 | 338 |
306 Future _refresh() async { | 339 Future _refresh() async { |
307 S.Code code = _code as S.Code; | 340 S.Code code = _code as S.Code; |
308 await code.reload(); | 341 await code.reload(); |
309 _r.dirty(); | 342 _r.dirty(); |
310 } | 343 } |
311 | 344 |
312 Future _refreshTicks() async { | 345 Future _refreshTicks() async { |
313 S.Code code = _code as S.Code; | 346 S.Code code = _code as S.Code; |
314 final isolate = code.isolate; | 347 final isolate = code.isolate; |
315 S.ServiceMap response = await isolate.invokeRpc('_getCpuProfile', | 348 S.ServiceMap response = |
316 { 'tags': 'None' }); | 349 await isolate.invokeRpc('_getCpuProfile', {'tags': 'None'}); |
317 final cpuProfile = new CpuProfile(); | 350 final cpuProfile = new CpuProfile(); |
318 await cpuProfile.load(isolate, response); | 351 await cpuProfile.load(isolate, response); |
319 _r.dirty(); | 352 _r.dirty(); |
320 } | 353 } |
321 | 354 |
322 String _formattedAddress(S.CodeInstruction instruction) { | 355 String _formattedAddress(S.CodeInstruction instruction) { |
323 if (instruction.address == 0) { | 356 if (instruction.address == 0) { |
324 return ''; | 357 return ''; |
325 } | 358 } |
326 return '0x${instruction.address.toRadixString(16)}'; | 359 return '0x${instruction.address.toRadixString(16)}'; |
(...skipping 11 matching lines...) Expand all Loading... |
338 return ''; | 371 return ''; |
339 } | 372 } |
340 var intervalTick = code.profile.intervalTicks[interval.start]; | 373 var intervalTick = code.profile.intervalTicks[interval.start]; |
341 if (intervalTick == null) { | 374 if (intervalTick == null) { |
342 return ''; | 375 return ''; |
343 } | 376 } |
344 // Don't show inclusive ticks if they are the same as exclusive ticks. | 377 // Don't show inclusive ticks if they are the same as exclusive ticks. |
345 if (intervalTick.inclusiveTicks == intervalTick.exclusiveTicks) { | 378 if (intervalTick.inclusiveTicks == intervalTick.exclusiveTicks) { |
346 return ''; | 379 return ''; |
347 } | 380 } |
348 var pcent = Utils.formatPercent(intervalTick.inclusiveTicks, | 381 var pcent = Utils.formatPercent( |
349 code.profile.profile.sampleCount); | 382 intervalTick.inclusiveTicks, code.profile.profile.sampleCount); |
350 return '$pcent (${intervalTick.inclusiveTicks})'; | 383 return '$pcent (${intervalTick.inclusiveTicks})'; |
351 } | 384 } |
352 | 385 |
353 String _formattedExclusiveInterval(S.CodeInlineInterval interval) { | 386 String _formattedExclusiveInterval(S.CodeInlineInterval interval) { |
354 S.Code code = _code as S.Code; | 387 S.Code code = _code as S.Code; |
355 if (code.profile == null) { | 388 if (code.profile == null) { |
356 return ''; | 389 return ''; |
357 } | 390 } |
358 var intervalTick = code.profile.intervalTicks[interval.start]; | 391 var intervalTick = code.profile.intervalTicks[interval.start]; |
359 if (intervalTick == null) { | 392 if (intervalTick == null) { |
360 return ''; | 393 return ''; |
361 } | 394 } |
362 var pcent = Utils.formatPercent(intervalTick.exclusiveTicks, | 395 var pcent = Utils.formatPercent( |
363 code.profile.profile.sampleCount); | 396 intervalTick.exclusiveTicks, code.profile.profile.sampleCount); |
364 return '$pcent (${intervalTick.exclusiveTicks})'; | 397 return '$pcent (${intervalTick.exclusiveTicks})'; |
365 } | 398 } |
366 | 399 |
367 | |
368 String _formattedInclusive(S.CodeInstruction instruction) { | 400 String _formattedInclusive(S.CodeInstruction instruction) { |
369 S.Code code = _code as S.Code; | 401 S.Code code = _code as S.Code; |
370 if (code.profile == null) { | 402 if (code.profile == null) { |
371 return ''; | 403 return ''; |
372 } | 404 } |
373 var tick = code.profile.addressTicks[instruction.address]; | 405 var tick = code.profile.addressTicks[instruction.address]; |
374 if (tick == null) { | 406 if (tick == null) { |
375 return ''; | 407 return ''; |
376 } | 408 } |
377 // Don't show inclusive ticks if they are the same as exclusive ticks. | 409 // Don't show inclusive ticks if they are the same as exclusive ticks. |
378 if (tick.inclusiveTicks == tick.exclusiveTicks) { | 410 if (tick.inclusiveTicks == tick.exclusiveTicks) { |
379 return ''; | 411 return ''; |
380 } | 412 } |
381 var pcent = Utils.formatPercent(tick.inclusiveTicks, | 413 var pcent = Utils.formatPercent( |
382 code.profile.profile.sampleCount); | 414 tick.inclusiveTicks, code.profile.profile.sampleCount); |
383 return '$pcent (${tick.inclusiveTicks})'; | 415 return '$pcent (${tick.inclusiveTicks})'; |
384 } | 416 } |
385 | 417 |
386 String _formattedExclusive(S.CodeInstruction instruction) { | 418 String _formattedExclusive(S.CodeInstruction instruction) { |
387 S.Code code = _code as S.Code; | 419 S.Code code = _code as S.Code; |
388 if (code.profile == null) { | 420 if (code.profile == null) { |
389 return ''; | 421 return ''; |
390 } | 422 } |
391 var tick = code.profile.addressTicks[instruction.address]; | 423 var tick = code.profile.addressTicks[instruction.address]; |
392 if (tick == null) { | 424 if (tick == null) { |
393 return ''; | 425 return ''; |
394 } | 426 } |
395 var pcent = Utils.formatPercent(tick.exclusiveTicks, | 427 var pcent = Utils.formatPercent( |
396 code.profile.profile.sampleCount); | 428 tick.exclusiveTicks, code.profile.profile.sampleCount); |
397 return '$pcent (${tick.exclusiveTicks})'; | 429 return '$pcent (${tick.exclusiveTicks})'; |
398 } | 430 } |
399 | 431 |
400 void _updateDiasssemblyTable() { | 432 void _updateDiasssemblyTable() { |
401 S.Code code = _code as S.Code; | 433 S.Code code = _code as S.Code; |
402 disassemblyTable.clearRows(); | 434 disassemblyTable.clearRows(); |
403 if (code == null) { | 435 if (code == null) { |
404 return; | 436 return; |
405 } | 437 } |
406 for (S.CodeInstruction instruction in code.instructions) { | 438 for (S.CodeInstruction instruction in code.instructions) { |
407 var row = [_formattedAddress(instruction), | 439 var row = [ |
408 _formattedInclusive(instruction), | 440 _formattedAddress(instruction), |
409 _formattedExclusive(instruction), | 441 _formattedInclusive(instruction), |
410 instruction.human, | 442 _formattedExclusive(instruction), |
411 instruction.object]; | 443 instruction.human, |
| 444 instruction.object |
| 445 ]; |
412 disassemblyTable.addRow(new SortedTableRow(row)); | 446 disassemblyTable.addRow(new SortedTableRow(row)); |
413 } | 447 } |
414 } | 448 } |
415 | 449 |
416 void _addDisassemblyDOMRow() { | 450 void _addDisassemblyDOMRow() { |
417 var tableBody = _disassemblyTableBody; | 451 var tableBody = _disassemblyTableBody; |
418 assert(tableBody != null); | 452 assert(tableBody != null); |
419 var tr = new TableRowElement(); | 453 var tr = new TableRowElement(); |
420 | 454 |
421 var cell; | 455 var cell; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 } | 498 } |
465 } | 499 } |
466 | 500 |
467 void _updateDisassemblyDOMTable() { | 501 void _updateDisassemblyDOMTable() { |
468 var tableBody = _disassemblyTableBody; | 502 var tableBody = _disassemblyTableBody; |
469 assert(tableBody != null); | 503 assert(tableBody != null); |
470 // Resize DOM table. | 504 // Resize DOM table. |
471 if (tableBody.children.length > disassemblyTable.sortedRows.length) { | 505 if (tableBody.children.length > disassemblyTable.sortedRows.length) { |
472 // Shrink the table. | 506 // Shrink the table. |
473 var deadRows = | 507 var deadRows = |
474 tableBody.children.length - disassemblyTable.sortedRows.length; | 508 tableBody.children.length - disassemblyTable.sortedRows.length; |
475 for (var i = 0; i < deadRows; i++) { | 509 for (var i = 0; i < deadRows; i++) { |
476 tableBody.children.removeLast(); | 510 tableBody.children.removeLast(); |
477 } | 511 } |
478 } else if (tableBody.children.length < disassemblyTable.sortedRows.length) { | 512 } else if (tableBody.children.length < disassemblyTable.sortedRows.length) { |
479 // Grow table. | 513 // Grow table. |
480 var newRows = | 514 var newRows = |
481 disassemblyTable.sortedRows.length - tableBody.children.length; | 515 disassemblyTable.sortedRows.length - tableBody.children.length; |
482 for (var i = 0; i < newRows; i++) { | 516 for (var i = 0; i < newRows; i++) { |
483 _addDisassemblyDOMRow(); | 517 _addDisassemblyDOMRow(); |
484 } | 518 } |
(...skipping 12 matching lines...) Expand all Loading... |
497 | 531 |
498 void _updateDisassembly() { | 532 void _updateDisassembly() { |
499 _updateDiasssemblyTable(); | 533 _updateDiasssemblyTable(); |
500 _updateDisassemblyDOMTable(); | 534 _updateDisassemblyDOMTable(); |
501 } | 535 } |
502 | 536 |
503 void _updateInlineTable() { | 537 void _updateInlineTable() { |
504 inlineTable.clearRows(); | 538 inlineTable.clearRows(); |
505 S.Code code = _code as S.Code; | 539 S.Code code = _code as S.Code; |
506 for (S.CodeInlineInterval interval in code.inlineIntervals) { | 540 for (S.CodeInlineInterval interval in code.inlineIntervals) { |
507 var row = [interval, | 541 var row = [ |
508 _formattedInclusiveInterval(interval), | 542 interval, |
509 _formattedExclusiveInterval(interval), | 543 _formattedInclusiveInterval(interval), |
510 interval.functions]; | 544 _formattedExclusiveInterval(interval), |
| 545 interval.functions |
| 546 ]; |
511 inlineTable.addRow(new SortedTableRow(row)); | 547 inlineTable.addRow(new SortedTableRow(row)); |
512 } | 548 } |
513 } | 549 } |
514 | 550 |
515 void _addInlineDOMRow() { | 551 void _addInlineDOMRow() { |
516 var tableBody = _inlineRangeTableBody; | 552 var tableBody = _inlineRangeTableBody; |
517 assert(tableBody != null); | 553 assert(tableBody != null); |
518 var tr = new TableRowElement(); | 554 var tr = new TableRowElement(); |
519 | 555 |
520 var cell; | 556 var cell; |
(...skipping 28 matching lines...) Expand all Loading... |
549 } | 585 } |
550 | 586 |
551 for (var i = addressRangeColumn + 1; i < columns - 1; i++) { | 587 for (var i = addressRangeColumn + 1; i < columns - 1; i++) { |
552 var cell = tr.children[i]; | 588 var cell = tr.children[i]; |
553 cell.text = row.values[i].toString(); | 589 cell.text = row.values[i].toString(); |
554 } | 590 } |
555 var functions = row.values[functionsColumn]; | 591 var functions = row.values[functionsColumn]; |
556 var functionsCell = tr.children[functionsColumn]; | 592 var functionsCell = tr.children[functionsColumn]; |
557 functionsCell.children.clear(); | 593 functionsCell.children.clear(); |
558 for (var func in functions) { | 594 for (var func in functions) { |
559 functionsCell.children.add( | 595 functionsCell.children |
560 new FunctionRefElement(_isolate, func, queue: _r.queue)); | 596 .add(new FunctionRefElement(_isolate, func, queue: _r.queue)); |
561 var gap = new SpanElement(); | 597 var gap = new SpanElement(); |
562 gap.style.minWidth = '1em'; | 598 gap.style.minWidth = '1em'; |
563 gap.text = ' '; | 599 gap.text = ' '; |
564 functionsCell.children.add(gap); | 600 functionsCell.children.add(gap); |
565 } | 601 } |
566 } | 602 } |
567 | 603 |
568 void _updateInlineDOMTable() { | 604 void _updateInlineDOMTable() { |
569 var tableBody = _inlineRangeTableBody; | 605 var tableBody = _inlineRangeTableBody; |
570 // Resize DOM table. | 606 // Resize DOM table. |
571 if (tableBody.children.length > inlineTable.sortedRows.length) { | 607 if (tableBody.children.length > inlineTable.sortedRows.length) { |
572 // Shrink the table. | 608 // Shrink the table. |
573 var deadRows = | 609 var deadRows = tableBody.children.length - inlineTable.sortedRows.length; |
574 tableBody.children.length - inlineTable.sortedRows.length; | |
575 for (var i = 0; i < deadRows; i++) { | 610 for (var i = 0; i < deadRows; i++) { |
576 tableBody.children.removeLast(); | 611 tableBody.children.removeLast(); |
577 } | 612 } |
578 } else if (tableBody.children.length < inlineTable.sortedRows.length) { | 613 } else if (tableBody.children.length < inlineTable.sortedRows.length) { |
579 // Grow table. | 614 // Grow table. |
580 var newRows = inlineTable.sortedRows.length - tableBody.children.length; | 615 var newRows = inlineTable.sortedRows.length - tableBody.children.length; |
581 for (var i = 0; i < newRows; i++) { | 616 for (var i = 0; i < newRows; i++) { |
582 _addInlineDOMRow(); | 617 _addInlineDOMRow(); |
583 } | 618 } |
584 } | 619 } |
585 assert(tableBody.children.length == inlineTable.sortedRows.length); | 620 assert(tableBody.children.length == inlineTable.sortedRows.length); |
586 // Fill table. | 621 // Fill table. |
587 for (var i = 0; i < inlineTable.sortedRows.length; i++) { | 622 for (var i = 0; i < inlineTable.sortedRows.length; i++) { |
588 var rowIndex = inlineTable.sortedRows[i]; | 623 var rowIndex = inlineTable.sortedRows[i]; |
589 var tr = tableBody.children[i]; | 624 var tr = tableBody.children[i]; |
590 _fillInlineDOMRow(tr, rowIndex); | 625 _fillInlineDOMRow(tr, rowIndex); |
591 } | 626 } |
592 } | 627 } |
593 | 628 |
594 void _updateInline() { | 629 void _updateInline() { |
595 _updateInlineTable(); | 630 _updateInlineTable(); |
596 _updateInlineDOMTable(); | 631 _updateInlineDOMTable(); |
597 } | 632 } |
598 | 633 |
599 static String _codeKindToString(M.CodeKind kind) { | 634 static String _codeKindToString(M.CodeKind kind) { |
600 switch (kind) { | 635 switch (kind) { |
601 case M.CodeKind.dart: return 'dart'; | 636 case M.CodeKind.dart: |
602 case M.CodeKind.native: return 'native'; | 637 return 'dart'; |
603 case M.CodeKind.stub: return 'stub'; | 638 case M.CodeKind.native: |
604 case M.CodeKind.tag: return 'tag'; | 639 return 'native'; |
605 case M.CodeKind.collected: return 'collected'; | 640 case M.CodeKind.stub: |
| 641 return 'stub'; |
| 642 case M.CodeKind.tag: |
| 643 return 'tag'; |
| 644 case M.CodeKind.collected: |
| 645 return 'collected'; |
606 } | 646 } |
607 throw new Exception('Unkown CodeKind ($kind)'); | 647 throw new Exception('Unkown CodeKind ($kind)'); |
608 } | 648 } |
609 } | 649 } |
OLD | NEW |