OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 'package:charted/charted.dart'; | |
8 import "package:charted/charts/charts.dart"; | |
9 import 'package:observatory/models.dart' as M; | |
10 import 'package:observatory/src/elements/class_ref.dart'; | |
11 import 'package:observatory/src/elements/containers/virtual_collection.dart'; | |
12 import 'package:observatory/src/elements/helpers/nav_bar.dart'; | |
13 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | |
14 import 'package:observatory/src/elements/helpers/tag.dart'; | |
15 import 'package:observatory/src/elements/nav/isolate_menu.dart'; | |
16 import 'package:observatory/src/elements/nav/notify.dart'; | |
17 import 'package:observatory/src/elements/nav/refresh.dart'; | |
18 import 'package:observatory/src/elements/nav/top_menu.dart'; | |
19 import 'package:observatory/src/elements/nav/vm_menu.dart'; | |
20 import 'package:observatory/utils.dart'; | |
21 | |
22 enum _SortingField { | |
23 accumulatedSize, | |
24 accumulatedInstances, | |
25 currentSize, | |
26 currentInstances, | |
27 newAccumulatedSize, | |
28 newAccumulatedInstances, | |
29 newCurrentSize, | |
30 newCurrentInstances, | |
31 oldAccumulatedSize, | |
32 oldAccumulatedInstances, | |
33 oldCurrentSize, | |
34 oldCurrentInstances, | |
35 className, | |
36 } | |
37 | |
38 enum _SortingDirection { ascending, descending } | |
39 | |
40 class MemoryDashboardElement extends HtmlElement implements Renderable { | |
41 static const tag = const Tag<MemoryDashboardElement>('memory-dashboard', | |
42 dependencies: const [ | |
43 ClassRefElement.tag, | |
44 NavTopMenuElement.tag, | |
45 NavVMMenuElement.tag, | |
46 NavIsolateMenuElement.tag, | |
47 NavRefreshElement.tag, | |
48 NavNotifyElement.tag, | |
49 VirtualCollectionElement.tag | |
50 ]); | |
51 | |
52 RenderingScheduler<MemoryDashboardElement> _r; | |
53 | |
54 Stream<RenderedEvent<MemoryDashboardElement>> get onRendered => _r.onRendered; | |
55 | |
56 M.VM _vm; | |
57 M.IsolateRef _isolate; | |
58 M.EventRepository _events; | |
59 M.NotificationRepository _notifications; | |
60 M.AllocationProfileRepository _repository; | |
61 M.AllocationProfile _profile; | |
62 M.EditorRepository _editor; | |
63 bool _autoRefresh = false; | |
64 bool _isCompacted = false; | |
65 StreamSubscription _gcSubscription; | |
66 _SortingField _sortingField = _SortingField.className; | |
67 _SortingDirection _sortingDirection = _SortingDirection.ascending; | |
68 | |
69 M.VMRef get vm => _vm; | |
70 M.IsolateRef get isolate => _isolate; | |
71 M.NotificationRepository get notifications => _notifications; | |
72 | |
73 factory MemoryDashboardElement( | |
74 M.VM vm, | |
75 M.IsolateRef isolate, | |
76 M.EventRepository events, | |
77 M.NotificationRepository notifications, | |
78 M.AllocationProfileRepository repository, | |
79 M.EditorRepository editor, | |
80 {RenderingQueue queue}) { | |
81 assert(vm != null); | |
82 assert(isolate != null); | |
83 assert(events != null); | |
84 assert(notifications != null); | |
85 assert(repository != null); | |
86 assert(editor != null); | |
87 MemoryDashboardElement e = document.createElement(tag.name); | |
88 e._r = new RenderingScheduler(e, queue: queue); | |
89 e._vm = vm; | |
90 e._isolate = isolate; | |
91 e._events = events; | |
92 e._notifications = notifications; | |
93 e._repository = repository; | |
94 e._editor = editor; | |
95 return e; | |
96 } | |
97 | |
98 MemoryDashboardElement.created() : super.created(); | |
99 | |
100 @override | |
101 attached() { | |
102 super.attached(); | |
103 _r.enable(); | |
104 _refresh(); | |
105 _gcSubscription = _events.onGCEvent.listen((e) { | |
106 if (_autoRefresh && (e.isolate.id == _isolate.id)) { | |
107 _refresh(); | |
108 } | |
109 }); | |
110 } | |
111 | |
112 @override | |
113 detached() { | |
114 super.detached(); | |
115 _r.disable(notify: true); | |
116 children = []; | |
117 _gcSubscription.cancel(); | |
118 } | |
119 | |
120 void render() { | |
121 children = [ | |
122 navBar([ | |
123 new NavRefreshElement( | |
124 label: 'Download', disabled: _profile == null, queue: _r.queue) | |
125 ..onRefresh.listen((_) => _downloadCSV()), | |
126 new NavRefreshElement(label: 'Reset Accumulator', queue: _r.queue) | |
127 ..onRefresh.listen((_) => _refresh(reset: true)), | |
128 new NavRefreshElement(label: 'GC', queue: _r.queue) | |
129 ..onRefresh.listen((_) => _refresh(gc: true)), | |
130 new NavRefreshElement(queue: _r.queue) | |
131 ..onRefresh.listen((_) => _refresh()), | |
132 new DivElement() | |
133 ..classes = ['nav-option'] | |
134 ..children = [ | |
135 new CheckboxInputElement() | |
136 ..id = 'allocation-profile-auto-refresh' | |
137 ..checked = _autoRefresh | |
138 ..onChange.listen((_) => _autoRefresh = !_autoRefresh), | |
139 new LabelElement() | |
140 ..htmlFor = 'allocation-profile-auto-refresh' | |
141 ..text = 'Auto-refresh on GC' | |
142 ], | |
143 new NavNotifyElement(_notifications, queue: _r.queue) | |
144 ]), | |
145 new DivElement() | |
146 ..classes = ['content-centered-big'] | |
147 ..children = [ | |
148 new HeadingElement.h2()..text = 'Allocation Profile', | |
149 new HRElement() | |
150 ] | |
151 ]; | |
152 if (_profile == null) { | |
153 children.addAll([ | |
154 new DivElement() | |
155 ..classes = ['content-centered-big'] | |
156 ..children = [new HeadingElement.h2()..text = 'Loading...'] | |
157 ]); | |
158 } else { | |
159 final newChartHost = new DivElement()..classes = ['host']; | |
160 final newChartLegend = new DivElement()..classes = ['legend']; | |
161 final oldChartHost = new DivElement()..classes = ['host']; | |
162 final oldChartLegend = new DivElement()..classes = ['legend']; | |
163 children.addAll([ | |
164 new DivElement() | |
165 ..classes = ['content-centered-big'] | |
166 ..children = _isCompacted | |
167 ? [] | |
168 : [ | |
169 new DivElement() | |
170 ..classes = ['memberList'] | |
171 ..children = [ | |
172 new DivElement() | |
173 ..classes = ['memberItem'] | |
174 ..children = [ | |
175 new DivElement() | |
176 ..classes = ['memberName'] | |
177 ..text = 'last forced GC at', | |
178 new DivElement() | |
179 ..classes = ['memberValue'] | |
180 ..text = _profile.lastServiceGC == null | |
181 ? '---' | |
182 : '${_profile.lastServiceGC}', | |
183 ], | |
184 new DivElement() | |
185 ..classes = ['memberItem'] | |
186 ..children = [ | |
187 new DivElement() | |
188 ..classes = ['memberName'] | |
189 ..text = 'last accumulator reset at', | |
190 new DivElement() | |
191 ..classes = ['memberValue'] | |
192 ..text = _profile.lastAccumulatorReset == null | |
193 ? '---' | |
194 : '${_profile.lastAccumulatorReset}', | |
195 ] | |
196 ], | |
197 new HRElement(), | |
198 ], | |
199 new DivElement() | |
200 ..classes = ['content-centered-big', 'compactable'] | |
201 ..children = [ | |
202 new DivElement() | |
203 ..classes = ['heap-space', 'left'] | |
204 ..children = _isCompacted | |
205 ? [ | |
206 new HeadingElement.h2() | |
207 ..text = 'New Generation ' | |
208 '(${_usedCaption(_profile.newSpace)})', | |
209 ] | |
210 : [ | |
211 new HeadingElement.h2()..text = 'New Generation', | |
212 new BRElement(), | |
213 new DivElement() | |
214 ..classes = ['memberList'] | |
215 ..children = _createSpaceMembers(_profile.newSpace), | |
216 new BRElement(), | |
217 new DivElement() | |
218 ..classes = ['chart'] | |
219 ..children = [newChartLegend, newChartHost] | |
220 ], | |
221 new DivElement() | |
222 ..classes = ['heap-space', 'right'] | |
223 ..children = _isCompacted | |
224 ? [ | |
225 new HeadingElement.h2() | |
226 ..text = '(${_usedCaption(_profile.oldSpace)}) ' | |
227 'Old Generation', | |
228 ] | |
229 : [ | |
230 new HeadingElement.h2()..text = 'Old Generation', | |
231 new BRElement(), | |
232 new DivElement() | |
233 ..classes = ['memberList'] | |
234 ..children = _createSpaceMembers(_profile.oldSpace), | |
235 new BRElement(), | |
236 new DivElement() | |
237 ..classes = ['chart'] | |
238 ..children = [oldChartLegend, oldChartHost] | |
239 ], | |
240 new ButtonElement() | |
241 ..classes = ['compact'] | |
242 ..text = _isCompacted ? 'expand ▼' : 'compact ▲' | |
243 ..onClick.listen((_) { | |
244 _isCompacted = !_isCompacted; | |
245 _r.dirty(); | |
246 }), | |
247 new HRElement() | |
248 ], | |
249 new DivElement() | |
250 ..classes = _isCompacted ? ['collection', 'expanded'] : ['collection'] | |
251 ..children = [ | |
252 new VirtualCollectionElement( | |
253 _createCollectionLine, _updateCollectionLine, | |
254 createHeader: _createCollectionHeader, | |
255 items: _profile.members.toList()..sort(_createSorter()), | |
256 queue: _r.queue) | |
257 ] | |
258 ]); | |
259 _renderGraph(newChartHost, newChartLegend, _profile.newSpace); | |
260 _renderGraph(oldChartHost, oldChartLegend, _profile.oldSpace); | |
261 } | |
262 } | |
263 | |
264 _createSorter() { | |
265 var getter; | |
266 switch (_sortingField) { | |
267 case _SortingField.accumulatedSize: | |
268 getter = _getAccumulatedSize; | |
269 break; | |
270 case _SortingField.accumulatedInstances: | |
271 getter = _getAccumulatedInstances; | |
272 break; | |
273 case _SortingField.currentSize: | |
274 getter = _getCurrentSize; | |
275 break; | |
276 case _SortingField.currentInstances: | |
277 getter = _getCurrentInstances; | |
278 break; | |
279 case _SortingField.newAccumulatedSize: | |
280 getter = _getNewAccumulatedSize; | |
281 break; | |
282 case _SortingField.newAccumulatedInstances: | |
283 getter = _getNewAccumulatedInstances; | |
284 break; | |
285 case _SortingField.newCurrentSize: | |
286 getter = _getNewCurrentSize; | |
287 break; | |
288 case _SortingField.newCurrentInstances: | |
289 getter = _getNewCurrentInstances; | |
290 break; | |
291 case _SortingField.oldAccumulatedSize: | |
292 getter = _getOldAccumulatedSize; | |
293 break; | |
294 case _SortingField.oldAccumulatedInstances: | |
295 getter = _getOldAccumulatedInstances; | |
296 break; | |
297 case _SortingField.oldCurrentSize: | |
298 getter = _getOldCurrentSize; | |
299 break; | |
300 case _SortingField.oldCurrentInstances: | |
301 getter = _getOldCurrentInstances; | |
302 break; | |
303 case _SortingField.className: | |
304 getter = (M.ClassHeapStats s) => s.clazz.name; | |
305 break; | |
306 } | |
307 switch (_sortingDirection) { | |
308 case _SortingDirection.ascending: | |
309 return (a, b) => getter(a).compareTo(getter(b)); | |
310 case _SortingDirection.descending: | |
311 return (a, b) => getter(b).compareTo(getter(a)); | |
312 } | |
313 } | |
314 | |
315 static Element _createCollectionLine() => new DivElement() | |
316 ..classes = ['collection-item'] | |
317 ..children = [ | |
318 new SpanElement() | |
319 ..classes = ['bytes'] | |
320 ..text = '0B', | |
321 new SpanElement() | |
322 ..classes = ['instances'] | |
323 ..text = '0', | |
324 new SpanElement() | |
325 ..classes = ['bytes'] | |
326 ..text = '0B', | |
327 new SpanElement() | |
328 ..classes = ['instances'] | |
329 ..text = '0', | |
330 new SpanElement() | |
331 ..classes = ['bytes'] | |
332 ..text = '0B', | |
333 new SpanElement() | |
334 ..classes = ['instances'] | |
335 ..text = '0', | |
336 new SpanElement() | |
337 ..classes = ['bytes'] | |
338 ..text = '0B', | |
339 new SpanElement() | |
340 ..classes = ['instances'] | |
341 ..text = '0', | |
342 new SpanElement() | |
343 ..classes = ['bytes'] | |
344 ..text = '0B', | |
345 new SpanElement() | |
346 ..classes = ['instances'] | |
347 ..text = '0', | |
348 new SpanElement() | |
349 ..classes = ['bytes'] | |
350 ..text = '0B', | |
351 new SpanElement() | |
352 ..classes = ['instances'] | |
353 ..text = '0', | |
354 new SpanElement()..classes = ['name'] | |
355 ]; | |
356 | |
357 List<HtmlElement> _createCollectionHeader() => [ | |
358 new DivElement() | |
359 ..classes = ['collection-item'] | |
360 ..children = [ | |
361 new SpanElement() | |
362 ..classes = ['group'] | |
363 ..text = 'Accumulated', | |
364 new SpanElement() | |
365 ..classes = ['group'] | |
366 ..text = 'Current', | |
367 new SpanElement() | |
368 ..classes = ['group'] | |
369 ..text = '(NEW) Accumulated', | |
370 new SpanElement() | |
371 ..classes = ['group'] | |
372 ..text = '(NEW) Current', | |
373 new SpanElement() | |
374 ..classes = ['group'] | |
375 ..text = '(OLD) Accumulated', | |
376 new SpanElement() | |
377 ..classes = ['group'] | |
378 ..text = '(OLD) Current', | |
379 ], | |
380 new DivElement() | |
381 ..classes = ['collection-item'] | |
382 ..children = [ | |
383 _createHeaderButton(const ['bytes'], 'Size', | |
384 _SortingField.accumulatedSize, _SortingDirection.descending), | |
385 _createHeaderButton( | |
386 const ['instances'], | |
387 'Instances', | |
388 _SortingField.accumulatedInstances, | |
389 _SortingDirection.descending), | |
390 _createHeaderButton(const ['bytes'], 'Size', | |
391 _SortingField.currentSize, _SortingDirection.descending), | |
392 _createHeaderButton(const ['instances'], 'Instances', | |
393 _SortingField.currentInstances, _SortingDirection.descending), | |
394 _createHeaderButton(const ['bytes'], 'Size', | |
395 _SortingField.newAccumulatedSize, _SortingDirection.descending), | |
396 _createHeaderButton( | |
397 const ['instances'], | |
398 'Instances', | |
399 _SortingField.newAccumulatedInstances, | |
400 _SortingDirection.descending), | |
401 _createHeaderButton(const ['bytes'], 'Size', | |
402 _SortingField.newCurrentSize, _SortingDirection.descending), | |
403 _createHeaderButton( | |
404 const ['instances'], | |
405 'Instances', | |
406 _SortingField.newCurrentInstances, | |
407 _SortingDirection.descending), | |
408 _createHeaderButton(const ['bytes'], 'Size', | |
409 _SortingField.oldAccumulatedSize, _SortingDirection.descending), | |
410 _createHeaderButton( | |
411 const ['instances'], | |
412 'Instances', | |
413 _SortingField.oldAccumulatedInstances, | |
414 _SortingDirection.descending), | |
415 _createHeaderButton(const ['bytes'], 'Size', | |
416 _SortingField.oldCurrentSize, _SortingDirection.descending), | |
417 _createHeaderButton( | |
418 const ['instances'], | |
419 'Instances', | |
420 _SortingField.oldCurrentInstances, | |
421 _SortingDirection.descending), | |
422 _createHeaderButton(const ['name'], 'Class', | |
423 _SortingField.className, _SortingDirection.ascending) | |
424 ], | |
425 ]; | |
426 | |
427 ButtonElement _createHeaderButton(List<String> classes, String text, | |
428 _SortingField field, _SortingDirection direction) => | |
429 new ButtonElement() | |
430 ..classes = classes | |
431 ..text = _sortingField != field | |
432 ? text | |
433 : _sortingDirection == _SortingDirection.ascending | |
434 ? '$text▼' | |
435 : '$text▲' | |
436 ..onClick.listen((_) => _setSorting(field, direction)); | |
437 | |
438 void _setSorting(_SortingField field, _SortingDirection defaultDirection) { | |
439 if (_sortingField == field) { | |
440 switch (_sortingDirection) { | |
441 case _SortingDirection.descending: | |
442 _sortingDirection = _SortingDirection.ascending; | |
443 break; | |
444 case _SortingDirection.ascending: | |
445 _sortingDirection = _SortingDirection.descending; | |
446 break; | |
447 } | |
448 } else { | |
449 _sortingDirection = defaultDirection; | |
450 _sortingField = field; | |
451 } | |
452 _r.dirty(); | |
453 } | |
454 | |
455 void _updateCollectionLine(Element e, M.ClassHeapStats item, index) { | |
456 e.children[0].text = Utils.formatSize(_getAccumulatedSize(item)); | |
457 e.children[1].text = '${_getAccumulatedInstances(item)}'; | |
458 e.children[2].text = Utils.formatSize(_getCurrentSize(item)); | |
459 e.children[3].text = '${_getCurrentInstances(item)}'; | |
460 e.children[4].text = Utils.formatSize(_getNewAccumulatedSize(item)); | |
461 e.children[5].text = '${_getNewAccumulatedInstances(item)}'; | |
462 e.children[6].text = Utils.formatSize(_getNewCurrentSize(item)); | |
463 e.children[7].text = '${_getNewCurrentInstances(item)}'; | |
464 e.children[8].text = Utils.formatSize(_getOldAccumulatedSize(item)); | |
465 e.children[9].text = '${_getOldAccumulatedInstances(item)}'; | |
466 e.children[10].text = Utils.formatSize(_getOldCurrentSize(item)); | |
467 e.children[11].text = '${_getOldCurrentInstances(item)}'; | |
468 e.children[12] = new ClassRefElement(_isolate, item.clazz, queue: _r.queue) | |
469 ..classes = ['name']; | |
470 Element.clickEvent.forTarget(e.children[12], useCapture: true).listen((e) { | |
471 e.preventDefault(); | |
472 _editor.sendObject(isolate, item.clazz); | |
473 window.close(); | |
474 }); | |
475 } | |
476 | |
477 static String _usedCaption(M.HeapSpace space) => | |
478 '${Utils.formatSize(space.used)}' | |
479 ' of ' | |
480 '${Utils.formatSize(space.capacity)}'; | |
481 | |
482 static List<Element> _createSpaceMembers(M.HeapSpace space) { | |
483 final used = _usedCaption(space); | |
484 final ext = '${Utils.formatSize(space.external)}'; | |
485 final collections = '${space.collections}'; | |
486 final avgCollectionTime = | |
487 '${Utils.formatDurationInMilliseconds(space.avgCollectionTime)} ms'; | |
488 final totalCollectionTime = | |
489 '${Utils.formatDurationInSeconds(space.totalCollectionTime)} secs'; | |
490 final avgCollectionPeriod = | |
491 '${Utils.formatDurationInMilliseconds(space.avgCollectionPeriod)} ms'; | |
492 return [ | |
493 new DivElement() | |
494 ..classes = ['memberItem'] | |
495 ..children = [ | |
496 new DivElement() | |
497 ..classes = ['memberName'] | |
498 ..text = 'used', | |
499 new DivElement() | |
500 ..classes = ['memberValue'] | |
501 ..text = used | |
502 ], | |
503 new DivElement() | |
504 ..classes = ['memberItem'] | |
505 ..children = [ | |
506 new DivElement() | |
507 ..classes = ['memberName'] | |
508 ..text = 'external', | |
509 new DivElement() | |
510 ..classes = ['memberValue'] | |
511 ..text = ext | |
512 ], | |
513 new DivElement() | |
514 ..classes = ['memberItem'] | |
515 ..children = [ | |
516 new DivElement() | |
517 ..classes = ['memberName'] | |
518 ..text = 'collections', | |
519 new DivElement() | |
520 ..classes = ['memberValue'] | |
521 ..text = collections | |
522 ], | |
523 new DivElement() | |
524 ..classes = ['memberItem'] | |
525 ..children = [ | |
526 new DivElement() | |
527 ..classes = ['memberName'] | |
528 ..text = 'average collection time', | |
529 new DivElement() | |
530 ..classes = ['memberValue'] | |
531 ..text = avgCollectionTime | |
532 ], | |
533 new DivElement() | |
534 ..classes = ['memberItem'] | |
535 ..children = [ | |
536 new DivElement() | |
537 ..classes = ['memberName'] | |
538 ..text = 'cumulative collection time', | |
539 new DivElement() | |
540 ..classes = ['memberValue'] | |
541 ..text = totalCollectionTime | |
542 ], | |
543 new DivElement() | |
544 ..classes = ['memberItem'] | |
545 ..children = [ | |
546 new DivElement() | |
547 ..classes = ['memberName'] | |
548 ..text = 'average time between collections', | |
549 new DivElement() | |
550 ..classes = ['memberValue'] | |
551 ..text = avgCollectionPeriod | |
552 ] | |
553 ]; | |
554 } | |
555 | |
556 static final _columns = [ | |
557 new ChartColumnSpec(label: 'Type', type: ChartColumnSpec.TYPE_STRING), | |
558 new ChartColumnSpec(label: 'Size', formatter: (v) => v.toString()) | |
559 ]; | |
560 | |
561 static void _renderGraph(Element host, Element legend, M.HeapSpace space) { | |
562 final series = [ | |
563 new ChartSeries("Work", [1], new PieChartRenderer(sortDataByValue: false)) | |
564 ]; | |
565 final rect = host.getBoundingClientRect(); | |
566 final minSize = new Rect.size(rect.width, rect.height); | |
567 final config = new ChartConfig(series, [0]) | |
568 ..minimumSize = minSize | |
569 ..legend = new ChartLegend(legend, showValues: true); | |
570 final data = new ChartData(_columns, [ | |
571 ['Used', space.used], | |
572 ['Free', space.capacity - space.used], | |
573 ['External', space.external] | |
574 ]); | |
575 | |
576 new LayoutArea(host, data, config, | |
577 state: new ChartState(), autoUpdate: true) | |
578 ..draw(); | |
579 } | |
580 | |
581 Future _refresh({bool gc: false, bool reset: false}) async { | |
582 _profile = null; | |
583 _r.dirty(); | |
584 _profile = await _repository.get(_isolate, gc: gc, reset: reset); | |
585 _r.dirty(); | |
586 } | |
587 | |
588 void _downloadCSV() { | |
589 assert(_profile != null); | |
590 final header = [ | |
591 '"Accumulator Size"', | |
592 '"Accumulator Instances"', | |
593 '"Current Size"', | |
594 '"Current Instances"', | |
595 '"(NEW) Accumulator Size"', | |
596 '"(NEW) Accumulator Instances"', | |
597 '"(NEW) Current Size"', | |
598 '"(NEW) Current Instances"', | |
599 '"(OLD) Accumulator Size"', | |
600 '"(OLD) Accumulator Instances"', | |
601 '"(OLD) Current Size"', | |
602 '"(OLD) Current Instances"', | |
603 'Class' | |
604 ].join(',') + | |
605 '\n'; | |
606 AnchorElement tl = document.createElement('a'); | |
607 tl | |
608 ..attributes['href'] = 'data:text/plain;charset=utf-8,' + | |
609 Uri.encodeComponent(header + | |
610 (_profile.members.toList()..sort(_createSorter())) | |
611 .map(_csvOut) | |
612 .join('\n')) | |
613 ..attributes['download'] = 'heap-profile.csv' | |
614 ..click(); | |
615 } | |
616 | |
617 static _csvOut(M.ClassHeapStats s) { | |
618 return [ | |
619 _getAccumulatedSize(s), | |
620 _getAccumulatedInstances(s), | |
621 _getCurrentSize(s), | |
622 _getCurrentInstances(s), | |
623 _getNewAccumulatedSize(s), | |
624 _getNewAccumulatedInstances(s), | |
625 _getNewCurrentSize(s), | |
626 _getNewCurrentInstances(s), | |
627 _getOldAccumulatedSize(s), | |
628 _getOldAccumulatedInstances(s), | |
629 _getOldCurrentSize(s), | |
630 _getOldCurrentInstances(s), | |
631 s.clazz.name | |
632 ].join(','); | |
633 } | |
634 | |
635 static int _getAccumulatedSize(M.ClassHeapStats s) => | |
636 s.newSpace.accumulated.bytes + s.oldSpace.accumulated.bytes; | |
637 static int _getAccumulatedInstances(M.ClassHeapStats s) => | |
638 s.newSpace.accumulated.instances + s.oldSpace.accumulated.instances; | |
639 static int _getCurrentSize(M.ClassHeapStats s) => | |
640 s.newSpace.current.bytes + s.oldSpace.current.bytes; | |
641 static int _getCurrentInstances(M.ClassHeapStats s) => | |
642 s.newSpace.current.instances + s.oldSpace.current.instances; | |
643 static int _getNewAccumulatedSize(M.ClassHeapStats s) => | |
644 s.newSpace.accumulated.bytes; | |
645 static int _getNewAccumulatedInstances(M.ClassHeapStats s) => | |
646 s.newSpace.accumulated.instances; | |
647 static int _getNewCurrentSize(M.ClassHeapStats s) => s.newSpace.current.bytes; | |
648 static int _getNewCurrentInstances(M.ClassHeapStats s) => | |
649 s.newSpace.current.instances; | |
650 static int _getOldAccumulatedSize(M.ClassHeapStats s) => | |
651 s.oldSpace.accumulated.bytes; | |
652 static int _getOldAccumulatedInstances(M.ClassHeapStats s) => | |
653 s.oldSpace.accumulated.instances; | |
654 static int _getOldCurrentSize(M.ClassHeapStats s) => s.oldSpace.current.bytes; | |
655 static int _getOldCurrentInstances(M.ClassHeapStats s) => | |
656 s.oldSpace.current.instances; | |
657 } | |
OLD | NEW |