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 function_view_element; | 5 library function_view_element; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'observatory_element.dart'; | 8 import 'dart:html'; |
9 import 'package:observatory/service.dart'; | 9 import 'package:observatory/models.dart' as M; |
10 | 10 import 'package:observatory/src/elements/class_ref.dart'; |
11 import 'package:polymer/polymer.dart'; | 11 import 'package:observatory/src/elements/code_ref.dart'; |
12 | 12 import 'package:observatory/src/elements/curly_block.dart'; |
13 @CustomTag('function-view') | 13 import 'package:observatory/src/elements/field_ref.dart'; |
14 class FunctionViewElement extends ObservatoryElement { | 14 import 'package:observatory/src/elements/instance_ref.dart'; |
15 @published ServiceFunction function; | 15 import 'package:observatory/src/elements/helpers/any_ref.dart'; |
16 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | |
17 import 'package:observatory/src/elements/helpers/tag.dart'; | |
18 import 'package:observatory/src/elements/nav/bar.dart'; | |
19 import 'package:observatory/src/elements/nav/class_menu.dart'; | |
20 import 'package:observatory/src/elements/nav/isolate_menu.dart'; | |
21 import 'package:observatory/src/elements/nav/library_menu.dart'; | |
22 import 'package:observatory/src/elements/nav/menu.dart'; | |
23 import 'package:observatory/src/elements/nav/notify.dart'; | |
24 import 'package:observatory/src/elements/nav/refresh.dart'; | |
25 import 'package:observatory/src/elements/nav/top_menu.dart'; | |
26 import 'package:observatory/src/elements/nav/vm_menu.dart'; | |
27 import 'package:observatory/src/elements/object_common.dart'; | |
28 import 'package:observatory/src/elements/source_inset.dart'; | |
29 import 'package:observatory/src/elements/source_link.dart'; | |
30 import 'package:observatory/src/elements/view_footer.dart'; | |
31 | |
32 class FunctionViewElement extends HtmlElement implements Renderable { | |
33 static const tag = const Tag<FunctionViewElement>('function-view', | |
34 dependencies: const [ | |
35 ClassRefElement.tag, | |
36 CodeRefElement.tag, | |
37 CurlyBlockElement.tag, | |
38 FieldRefElement.tag, | |
39 InstanceRefElement.tag, | |
40 NavBarElement.tag, | |
41 NavClassMenuElement.tag, | |
42 NavLibraryMenuElement.tag, | |
43 NavTopMenuElement.tag, | |
44 NavVMMenuElement.tag, | |
45 NavIsolateMenuElement.tag, | |
46 NavMenuElement.tag, | |
47 NavRefreshElement.tag, | |
48 NavNotifyElement.tag, | |
49 ObjectCommonElement.tag, | |
50 SourceLinkElement.tag, | |
51 SourceInsetElement.tag, | |
52 ViewFooterElement.tag | |
53 ]); | |
54 | |
55 RenderingScheduler<FunctionViewElement> _r; | |
56 | |
57 Stream<RenderedEvent<FunctionViewElement>> get onRendered => _r.onRendered; | |
58 | |
59 M.VM _vm; | |
60 M.IsolateRef _isolate; | |
61 M.EventRepository _events; | |
62 M.NotificationRepository _notifications; | |
63 M.Function _function; | |
64 M.LibraryRef _library; | |
65 M.FunctionRepository _functions; | |
66 M.ClassRepository _classes; | |
67 M.RetainedSizeRepository _retainedSizes; | |
68 M.ReachableSizeRepository _reachableSizes; | |
69 M.InboundReferencesRepository _references; | |
70 M.RetainingPathRepository _retainingPaths; | |
71 M.ScriptRepository _scripts; | |
72 M.InstanceRepository _instances; | |
73 | |
74 | |
75 M.VMRef get vm => _vm; | |
76 M.IsolateRef get isolate => _isolate; | |
77 M.NotificationRepository get notifications => _notifications; | |
78 M.Function get function => _function; | |
79 | |
80 factory FunctionViewElement(M.VM vm, M.IsolateRef isolate, M.Function function , | |
81 M.EventRepository events, | |
82 M.NotificationRepository notifications, | |
83 M.FunctionRepository functions, | |
84 M.ClassRepository classes, | |
85 M.RetainedSizeRepository retainedSizes, | |
86 M.ReachableSizeRepository reachableSizes, | |
87 M.InboundReferencesRepository references, | |
88 M.RetainingPathRepository retainingPaths, | |
89 M.ScriptRepository scripts, | |
90 M.InstanceRepository instances, | |
91 {RenderingQueue queue}) { | |
92 assert(vm != null); | |
93 assert(isolate != null); | |
94 assert(events != null); | |
95 assert(notifications != null); | |
96 assert(function != null); | |
97 assert(functions != null); | |
98 assert(classes != null); | |
99 assert(retainedSizes != null); | |
100 assert(reachableSizes != null); | |
101 assert(references != null); | |
102 assert(retainingPaths != null); | |
103 assert(scripts != null); | |
104 assert(instances != null); | |
105 FunctionViewElement e = document.createElement(tag.name); | |
106 e._r = new RenderingScheduler(e, queue: queue); | |
107 e._vm = vm; | |
108 e._isolate = isolate; | |
109 e._events = events; | |
110 e._notifications = notifications; | |
111 e._function = function; | |
112 e._functions = functions; | |
113 e._classes = classes; | |
114 e._retainedSizes = retainedSizes; | |
115 e._reachableSizes = reachableSizes; | |
116 e._references = references; | |
117 e._retainingPaths = retainingPaths; | |
118 e._scripts = scripts; | |
119 e._instances = instances; | |
120 if (function.dartOwner is M.LibraryRef) { | |
121 e._library = function.dartOwner; | |
122 } | |
123 return e; | |
124 } | |
125 | |
16 FunctionViewElement.created() : super.created(); | 126 FunctionViewElement.created() : super.created(); |
17 | 127 |
18 Future refresh() { | 128 @override |
19 return function.reload(); | 129 attached() { |
130 super.attached(); | |
131 _r.enable(); | |
132 _refresh(); | |
133 } | |
134 | |
135 @override | |
136 detached() { | |
137 super.detached(); | |
138 _r.disable(notify: true); | |
139 children = []; | |
140 } | |
141 | |
142 void render() { | |
143 children = [ | |
144 new NavBarElement(queue: _r.queue) | |
145 ..children = _createMenu(), | |
146 new DivElement()..classes = const ['content-centered-big'] | |
147 ..children = [ | |
148 new HeadingElement.h2()..text = 'Function ${_function.name}', | |
149 new HRElement(), | |
150 new ObjectCommonElement(_isolate, _function, _retainedSizes, | |
151 _reachableSizes, _references, _retainingPaths, | |
152 _instances, queue: _r.queue), | |
153 new BRElement(), | |
154 new DivElement()..classes = ['memberList'] | |
155 ..children = _createMembers(), | |
156 new HRElement(), | |
157 new DivElement() | |
158 ..children = _function.location == null ? const [] | |
159 : [ | |
160 new SourceInsetElement(_isolate, _function.location, _scripts, | |
161 _instances, _events, queue: _r.queue) | |
162 ], | |
163 new ViewFooterElement(queue: _r.queue) | |
164 ] | |
165 ]; | |
166 } | |
167 | |
168 List<Element> _createMenu() { | |
169 final menu = [ | |
170 new NavTopMenuElement(queue: _r.queue), | |
171 new NavVMMenuElement(_vm, _events, queue: _r.queue), | |
172 new NavIsolateMenuElement(_isolate, _events, queue: _r.queue) | |
173 ]; | |
174 if (_library != null) { | |
175 menu.add(new NavLibraryMenuElement(_isolate, _function.dartOwner, | |
176 queue: _r.queue)); | |
177 } else if (_function.dartOwner is M.ClassRef) { | |
178 menu.add( | |
179 new NavClassMenuElement(_isolate, _function.dartOwner, queue: _r.queue), | |
rmacnak
2016/08/29 23:34:35
stray trailing comma
cbernaschina
2016/08/29 23:36:16
Done.
| |
180 ); | |
181 } | |
182 menu.addAll([ | |
183 new NavMenuElement(_function.name, last: true, queue: _r.queue), | |
184 new NavRefreshElement(queue: _r.queue) | |
185 ..onRefresh.listen((e) { | |
186 e.element.disabled = true; | |
187 _refresh(); | |
188 }), | |
189 new NavNotifyElement(_notifications, queue: _r.queue) | |
190 ]); | |
191 return menu; | |
192 } | |
193 | |
194 List<Element> _createMembers() { | |
195 final members = <Element>[ | |
196 new DivElement()..classes = ['memberItem'] | |
197 ..children = [ | |
198 new DivElement()..classes = ['memberName'] | |
199 ..text = 'kind', | |
200 new DivElement()..classes = ['memberName'] | |
201 ..children = [ | |
202 new SpanElement() | |
203 ..text = '${_function.isStatic ? "static ": ""}' | |
204 '${_function.isConst ? "const ": ""}' | |
205 '${_functionKindToString(_function.kind)}' | |
206 ] | |
207 ], | |
208 new DivElement()..classes = ['memberItem'] | |
209 ..children = [ | |
210 new DivElement()..classes = ['memberName'] | |
211 ..text = 'owner', | |
212 new DivElement()..classes = ['memberName'] | |
213 ..children = [ | |
214 _function.dartOwner == null | |
215 ? (new SpanElement()..text = '...') | |
216 : anyRef(_isolate, _function.dartOwner, _instances, | |
217 queue: _r.queue) | |
218 ] | |
219 ] | |
220 ]; | |
221 if (_function.field != null) { | |
222 members.add( | |
223 new DivElement()..classes = ['memberItem'] | |
224 ..children = [ | |
225 new DivElement()..classes = ['memberName'] | |
226 ..text = 'script', | |
227 new DivElement()..classes = ['memberName'] | |
228 ..children = [ | |
229 new FieldRefElement(_isolate, _function.field, _instances, | |
230 queue: _r.queue) | |
231 ] | |
232 ] | |
233 ); | |
234 } | |
235 members.add( | |
236 new DivElement()..classes = ['memberItem'] | |
237 ..children = [ | |
238 new DivElement()..classes = ['memberName'] | |
239 ..text = 'script', | |
240 new DivElement()..classes = ['memberName'] | |
241 ..children = [ | |
242 new SourceLinkElement(_isolate, _function.location, _scripts, | |
243 queue: _r.queue) | |
244 ] | |
245 ] | |
246 ); | |
247 if (_function.code != null) { | |
248 members.add( | |
249 new DivElement()..classes = ['memberItem'] | |
250 ..children = [ | |
251 new DivElement()..classes = ['memberName'] | |
252 ..text = 'current code', | |
253 new DivElement()..classes = ['memberName'] | |
254 ..children = [ | |
255 new CodeRefElement(_isolate, _function.code, queue: _r.queue) | |
256 ] | |
257 ] | |
258 ); | |
259 } | |
260 if (_function.unoptimizedCode != null) { | |
261 members.add( | |
262 new DivElement()..classes = ['memberItem'] | |
263 ..children = [ | |
264 new DivElement()..classes = ['memberName'] | |
265 ..text = 'unoptimized code', | |
266 new DivElement()..classes = ['memberName'] | |
267 ..children = [ | |
268 new CodeRefElement(_isolate, _function.unoptimizedCode, | |
269 queue: _r.queue), | |
270 new SpanElement() | |
271 ..title = 'This count is used to determine when a function ' | |
272 'will be optimized. It is a combination of call ' | |
273 'counts and other factors.' | |
274 ..text = ' (usage count: ${function.usageCounter })' | |
275 ] | |
276 ] | |
277 ); | |
278 } | |
279 members.addAll([ | |
280 new DivElement()..classes = ['memberItem'] | |
281 ..text = ' ', | |
282 new DivElement()..classes = ['memberItem'] | |
283 ..children = [ | |
284 new DivElement()..classes = ['memberName'] | |
285 ..text = 'ic data array', | |
286 new DivElement()..classes = ['memberName'] | |
287 ..children = [ | |
288 new InstanceRefElement(_isolate, _function.icDataArray, | |
289 _instances, queue: _r.queue) | |
290 ] | |
291 ], | |
292 new DivElement()..classes = ['memberItem'] | |
293 ..children = [ | |
294 new DivElement()..classes = ['memberName'] | |
295 ..text = 'deoptimizations', | |
296 new DivElement()..classes = ['memberName'] | |
297 ..text = '${_function.deoptimizations}' | |
298 ], | |
299 new DivElement()..classes = ['memberItem'] | |
300 ..children = [ | |
301 new DivElement()..classes = ['memberName'] | |
302 ..text = 'optimizable', | |
303 new DivElement()..classes = ['memberName'] | |
304 ..text = _function.isOptimizable ? 'yes' : 'no' | |
305 ], | |
306 new DivElement()..classes = ['memberItem'] | |
307 ..children = [ | |
308 new DivElement()..classes = ['memberName'] | |
309 ..text = 'inlinable', | |
310 new DivElement()..classes = ['memberName'] | |
311 ..text = _function.isInlinable ? 'yes' : 'no' | |
312 ], | |
313 new DivElement()..classes = ['memberItem'] | |
314 ..children = [ | |
315 new DivElement()..classes = ['memberName'] | |
316 ..text = 'intrinsic', | |
317 new DivElement()..classes = ['memberName'] | |
318 ..text = _function.hasIntrinsic ? 'yes' : 'no' | |
319 ], | |
320 new DivElement()..classes = ['memberItem'] | |
321 ..children = [ | |
322 new DivElement()..classes = ['memberName'] | |
323 ..text = 'recognized', | |
324 new DivElement()..classes = ['memberName'] | |
325 ..text = _function.isRecognized ? 'yes' : 'no' | |
326 ], | |
327 new DivElement()..classes = ['memberItem'] | |
328 ..children = [ | |
329 new DivElement()..classes = ['memberName'] | |
330 ..text = 'native', | |
331 new DivElement()..classes = ['memberName'] | |
332 ..text = _function.isNative ? 'yes' : 'no' | |
333 ], | |
334 new DivElement()..classes = ['memberItem'] | |
335 ..children = [ | |
336 new DivElement()..classes = ['memberName'] | |
337 ..text = 'vm name', | |
338 new DivElement()..classes = ['memberName'] | |
339 ..text = _function.vmName | |
340 ] | |
341 ]); | |
342 return members; | |
343 } | |
344 | |
345 Future _refresh() async { | |
346 _function = await _functions.get(_isolate, _function.id); | |
347 if (_function.dartOwner is M.LibraryRef) { | |
348 _library = _function.dartOwner; | |
349 } else if (_function.dartOwner is M.ClassRef) { | |
350 _library = (await _classes.get(_isolate, _function.dartOwner.id)).library; | |
351 } | |
352 _r.dirty(); | |
353 } | |
354 | |
355 static String _functionKindToString(M.FunctionKind kind) { | |
356 switch(kind) { | |
357 case M.FunctionKind.regular: | |
358 return 'regular'; | |
359 case M.FunctionKind.closure: | |
360 return 'closure'; | |
361 case M.FunctionKind.getter: | |
362 return 'getter'; | |
363 case M.FunctionKind.setter: | |
364 return 'setter'; | |
365 case M.FunctionKind.constructor: | |
366 return 'constructor'; | |
367 case M.FunctionKind.implicitGetter: | |
368 return 'implicit getter'; | |
369 case M.FunctionKind.implicitSetter: | |
370 return 'implicit setter'; | |
371 case M.FunctionKind.implicitStaticFinalGetter: | |
372 return 'implicit static final getter'; | |
373 case M.FunctionKind.irregexpFunction: | |
374 return 'irregexp function'; | |
375 case M.FunctionKind.staticInitializer: | |
376 return 'static initializer'; | |
377 case M.FunctionKind.methodExtractor: | |
378 return 'method extractor'; | |
379 case M.FunctionKind.noSuchMethodDispatcher: | |
380 return 'noSuchMethod dispatcher'; | |
381 case M.FunctionKind.invokeFieldDispatcher: | |
382 return 'invokeField dispatcher'; | |
383 case M.FunctionKind.collected: | |
384 return 'collected'; | |
385 case M.FunctionKind.native: | |
386 return 'native'; | |
387 case M.FunctionKind.stub: | |
388 return 'stub'; | |
389 case M.FunctionKind.tag: | |
390 return 'tag'; | |
391 case M.FunctionKind.signatureFunction: | |
392 return 'signature function'; | |
393 } | |
394 throw new Exception('Unknown Functionkind ($kind)'); | |
20 } | 395 } |
21 } | 396 } |
OLD | NEW |