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

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

Issue 2502283003: Add a version of heap snapshots that use only fields and stack frames as roots and only include ins… (Closed)
Patch Set: . Created 4 years 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
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 5 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
6 // for details. All rights reserved. Use of this source code is governed by a 6 // for details. All rights reserved. Use of this source code is governed by a
7 // BSD-style license that can be found in the LICENSE file. 7 // BSD-style license that can be found in the LICENSE file.
8 8
9 import 'dart:async'; 9 import 'dart:async';
10 import 'dart:html'; 10 import 'dart:html';
11 import 'dart:math' as Math; 11 import 'dart:math' as Math;
12 import 'package:observatory/models.dart' as M; 12 import 'package:observatory/models.dart' as M;
13 import 'package:observatory/src/elements/class_ref.dart'; 13 import 'package:observatory/src/elements/class_ref.dart';
14 import 'package:observatory/src/elements/containers/virtual_tree.dart'; 14 import 'package:observatory/src/elements/containers/virtual_tree.dart';
15 import 'package:observatory/src/elements/helpers/any_ref.dart'; 15 import 'package:observatory/src/elements/helpers/any_ref.dart';
16 import 'package:observatory/src/elements/helpers/nav_bar.dart'; 16 import 'package:observatory/src/elements/helpers/nav_bar.dart';
17 import 'package:observatory/src/elements/helpers/nav_menu.dart'; 17 import 'package:observatory/src/elements/helpers/nav_menu.dart';
18 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; 18 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
19 import 'package:observatory/src/elements/helpers/tag.dart'; 19 import 'package:observatory/src/elements/helpers/tag.dart';
20 import 'package:observatory/src/elements/helpers/uris.dart';
20 import 'package:observatory/src/elements/nav/isolate_menu.dart'; 21 import 'package:observatory/src/elements/nav/isolate_menu.dart';
21 import 'package:observatory/src/elements/nav/notify.dart'; 22 import 'package:observatory/src/elements/nav/notify.dart';
22 import 'package:observatory/src/elements/nav/refresh.dart'; 23 import 'package:observatory/src/elements/nav/refresh.dart';
23 import 'package:observatory/src/elements/nav/top_menu.dart'; 24 import 'package:observatory/src/elements/nav/top_menu.dart';
24 import 'package:observatory/src/elements/nav/vm_menu.dart'; 25 import 'package:observatory/src/elements/nav/vm_menu.dart';
25 import 'package:observatory/utils.dart'; 26 import 'package:observatory/utils.dart';
26 27
27 enum HeapSnapshotTreeMode { dominatorTree, mergedDominatorTree, groupByClass } 28 enum HeapSnapshotTreeMode { dominatorTree, mergedDominatorTree, groupByClass }
28 29
29 class HeapSnapshotElement extends HtmlElement implements Renderable { 30 class HeapSnapshotElement extends HtmlElement implements Renderable {
(...skipping 14 matching lines...) Expand all
44 45
45 M.VM _vm; 46 M.VM _vm;
46 M.IsolateRef _isolate; 47 M.IsolateRef _isolate;
47 M.EventRepository _events; 48 M.EventRepository _events;
48 M.NotificationRepository _notifications; 49 M.NotificationRepository _notifications;
49 M.HeapSnapshotRepository _snapshots; 50 M.HeapSnapshotRepository _snapshots;
50 M.InstanceRepository _instances; 51 M.InstanceRepository _instances;
51 M.HeapSnapshot _snapshot; 52 M.HeapSnapshot _snapshot;
52 Stream<M.HeapSnapshotLoadingProgressEvent> _progressStream; 53 Stream<M.HeapSnapshotLoadingProgressEvent> _progressStream;
53 M.HeapSnapshotLoadingProgress _progress; 54 M.HeapSnapshotLoadingProgress _progress;
55 M.HeapSnapshotRoots _roots = M.HeapSnapshotRoots.user;
54 HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.dominatorTree; 56 HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.dominatorTree;
55 57
56 M.IsolateRef get isolate => _isolate; 58 M.IsolateRef get isolate => _isolate;
57 M.NotificationRepository get notifications => _notifications; 59 M.NotificationRepository get notifications => _notifications;
58 M.HeapSnapshotRepository get profiles => _snapshots; 60 M.HeapSnapshotRepository get profiles => _snapshots;
59 M.VMRef get vm => _vm; 61 M.VMRef get vm => _vm;
60 62
61 factory HeapSnapshotElement( 63 factory HeapSnapshotElement(
62 M.VM vm, 64 M.VM vm,
63 M.IsolateRef isolate, 65 M.IsolateRef isolate,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 break; 133 break;
132 case M.HeapSnapshotLoadingStatus.loaded: 134 case M.HeapSnapshotLoadingStatus.loaded:
133 content.addAll(_createReport()); 135 content.addAll(_createReport());
134 break; 136 break;
135 } 137 }
136 children = content; 138 children = content;
137 } 139 }
138 140
139 Future _refresh() async { 141 Future _refresh() async {
140 _progress = null; 142 _progress = null;
141 _progressStream = _snapshots.get(isolate); 143 _progressStream = _snapshots.get(isolate,
144 roots: _roots,
145 gc: true);
142 _r.dirty(); 146 _r.dirty();
143 _progressStream.listen((e) { 147 _progressStream.listen((e) {
144 _progress = e.progress; 148 _progress = e.progress;
145 _r.dirty(); 149 _r.dirty();
146 }); 150 });
147 _progress = (await _progressStream.first).progress; 151 _progress = (await _progressStream.first).progress;
148 _r.dirty(); 152 _r.dirty();
149 if (M.isHeapSnapshotProgressRunning(_progress.status)) { 153 if (M.isHeapSnapshotProgressRunning(_progress.status)) {
150 _progress = (await _progressStream.last).progress; 154 _progress = (await _progressStream.last).progress;
151 _snapshot = _progress.snapshot; 155 _snapshot = _progress.snapshot;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 ..text = 'Size ', 230 ..text = 'Size ',
227 new DivElement() 231 new DivElement()
228 ..classes = ['memberName'] 232 ..classes = ['memberName']
229 ..text = Utils.formatSize(_snapshot.size) 233 ..text = Utils.formatSize(_snapshot.size)
230 ], 234 ],
231 new DivElement() 235 new DivElement()
232 ..classes = ['memberItem'] 236 ..classes = ['memberItem']
233 ..children = [ 237 ..children = [
234 new DivElement() 238 new DivElement()
235 ..classes = ['memberName'] 239 ..classes = ['memberName']
240 ..text = 'Roots ',
241 new DivElement()
242 ..classes = ['memberName']
243 ..children = _createRootsSelect()
244 ],
245 new DivElement()
246 ..classes = ['memberItem']
247 ..children = [
248 new DivElement()
249 ..classes = ['memberName']
236 ..text = 'Analysis ', 250 ..text = 'Analysis ',
237 new DivElement() 251 new DivElement()
238 ..classes = ['memberName'] 252 ..classes = ['memberName']
239 ..children = _createModeSelect() 253 ..children = _createModeSelect()
240 ] 254 ]
241 ] 255 ]
242 ], 256 ],
243 ]; 257 ];
244 switch (_mode) { 258 switch (_mode) {
245 case HeapSnapshotTreeMode.dominatorTree: 259 case HeapSnapshotTreeMode.dominatorTree:
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 element.children[2].text = _tree.isExpanded(node) ? '▼' : '►'; 403 element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
390 } else { 404 } else {
391 element.children[2].text = ''; 405 element.children[2].text = '';
392 } 406 }
393 element.children[3].text = 407 element.children[3].text =
394 Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size); 408 Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
395 final wrapper = new SpanElement() 409 final wrapper = new SpanElement()
396 ..classes = ['name'] 410 ..classes = ['name']
397 ..text = 'Loading...'; 411 ..text = 'Loading...';
398 element.children[4] = wrapper; 412 element.children[4] = wrapper;
399 node.object.then((object) { 413 if (node.isStack) {
400 wrapper 414 wrapper
401 ..text = '' 415 ..text = ''
402 ..children = [anyRef(_isolate, object, _instances, queue: _r.queue)]; 416 ..children = [
403 }); 417 new AnchorElement(href: Uris.debugger(isolate))
418 ..text = 'stack frames'
419 ];
420 } else {
421 node.object.then((object) {
422 wrapper
423 ..text = ''
424 ..children = [anyRef(_isolate, object, _instances, queue: _r.queue)];
425 });
426 }
404 } 427 }
405 428
406 void _updateMergedDominator( 429 void _updateMergedDominator(
407 HtmlElement element, M.HeapSnapshotMergedDominatorNode node, int depth) { 430 HtmlElement element, M.HeapSnapshotMergedDominatorNode node, int depth) {
408 element.children[0].text = Utils.formatSize(node.retainedSize); 431 element.children[0].text = Utils.formatSize(node.retainedSize);
409 _updateLines(element.children[1].children, depth); 432 _updateLines(element.children[1].children, depth);
410 if (_getChildrenMergedDominator(node).isNotEmpty) { 433 if (_getChildrenMergedDominator(node).isNotEmpty) {
411 element.children[2].text = _tree.isExpanded(node) ? '▼' : '►'; 434 element.children[2].text = _tree.isExpanded(node) ? '▼' : '►';
412 } else { 435 } else {
413 element.children[2].text = ''; 436 element.children[2].text = '';
414 } 437 }
415 element.children[3].text = 438 element.children[3].text =
416 Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size); 439 Utils.formatPercentNormalized(node.retainedSize * 1.0 / _snapshot.size);
417 final wrapper = new SpanElement() 440 final wrapper = new SpanElement()
418 ..classes = ['name'] 441 ..classes = ['name']
419 ..text = 'Loading...'; 442 ..text = 'Loading...';
420 element.children[4] = wrapper; 443 element.children[4] = wrapper;
421 node.klass.then((klass) { 444 if (node.isStack) {
422 wrapper 445 wrapper
423 ..text = '' 446 ..text = ''
424 ..children = [ 447 ..children = [
425 new SpanElement()..text = '${node.instanceCount} instances of ', 448 new AnchorElement(href: Uris.debugger(isolate))
426 anyRef(_isolate, klass, _instances, queue: _r.queue) 449 ..text = 'stack frames'
427 ]; 450 ];
428 }); 451 } else {
452 node.klass.then((klass) {
453 wrapper
454 ..text = ''
455 ..children = [
456 new SpanElement()..text = '${node.instanceCount} instances of ',
457 anyRef(_isolate, klass, _instances, queue: _r.queue)
458 ];
459 });
460 }
429 } 461 }
430 462
431 void _updateGroup(HtmlElement element, item, int depth) { 463 void _updateGroup(HtmlElement element, item, int depth) {
432 _updateLines(element.children[1].children, depth); 464 _updateLines(element.children[1].children, depth);
433 if (item is M.HeapSnapshotClassReferences) { 465 if (item is M.HeapSnapshotClassReferences) {
434 element.children[0].text = Utils.formatSize(item.shallowSize); 466 element.children[0].text = Utils.formatSize(item.shallowSize);
435 element.children[2].text = _tree.isExpanded(item) ? '▼' : '►'; 467 element.children[2].text = _tree.isExpanded(item) ? '▼' : '►';
436 element.children[3].text = '${item.instances} instances of '; 468 element.children[3].text = '${item.instances} instances of ';
437 element.children[4] = new ClassRefElement(_isolate, item.clazz, 469 element.children[4] = new ClassRefElement(_isolate, item.clazz,
438 queue: _r.queue)..classes = ['name']; 470 queue: _r.queue)..classes = ['name'];
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 static _updateLines(List<Element> lines, int n) { 512 static _updateLines(List<Element> lines, int n) {
481 n = Math.max(0, n); 513 n = Math.max(0, n);
482 while (lines.length > n) { 514 while (lines.length > n) {
483 lines.removeLast(); 515 lines.removeLast();
484 } 516 }
485 while (lines.length < n) { 517 while (lines.length < n) {
486 lines.add(new SpanElement()); 518 lines.add(new SpanElement());
487 } 519 }
488 } 520 }
489 521
522 static String rootsToString(M.HeapSnapshotRoots roots) {
523 switch (roots) {
524 case M.HeapSnapshotRoots.user:
525 return 'User';
526 case M.HeapSnapshotRoots.vm:
527 return 'VM';
528 }
529 throw new Exception('Unknown HeapSnapshotRoots');
530 }
531
532 List<Element> _createRootsSelect() {
533 var s;
534 return [
535 s = new SelectElement()
536 ..classes = ['roots-select']
537 ..value = rootsToString(_roots)
538 ..children = M.HeapSnapshotRoots.values.map((roots) {
539 return new OptionElement(
540 value: rootsToString(roots),
541 selected: _roots == roots)..text = rootsToString(roots);
542 }).toList(growable: false)
543 ..onChange.listen((_) {
544 _roots = M.HeapSnapshotRoots.values[s.selectedIndex];
545 _refresh();
546 })
547 ];
548 }
549
490 static String modeToString(HeapSnapshotTreeMode mode) { 550 static String modeToString(HeapSnapshotTreeMode mode) {
491 switch (mode) { 551 switch (mode) {
492 case HeapSnapshotTreeMode.dominatorTree: 552 case HeapSnapshotTreeMode.dominatorTree:
493 return 'Dominator tree'; 553 return 'Dominator tree';
494 case HeapSnapshotTreeMode.mergedDominatorTree: 554 case HeapSnapshotTreeMode.mergedDominatorTree:
495 return 'Dominator tree (merged siblings by class)'; 555 return 'Dominator tree (merged siblings by class)';
496 case HeapSnapshotTreeMode.groupByClass: 556 case HeapSnapshotTreeMode.groupByClass:
497 return 'Group by class'; 557 return 'Group by class';
498 } 558 }
499 throw new Exception('Unknown ProfileTreeMode'); 559 throw new Exception('Unknown HeapSnapshotTreeMode');
500 } 560 }
501 561
502 List<Element> _createModeSelect() { 562 List<Element> _createModeSelect() {
503 var s; 563 var s;
504 return [ 564 return [
505 s = new SelectElement() 565 s = new SelectElement()
506 ..classes = ['analysis-select'] 566 ..classes = ['analysis-select']
507 ..value = modeToString(_mode) 567 ..value = modeToString(_mode)
508 ..children = HeapSnapshotTreeMode.values.map((mode) { 568 ..children = HeapSnapshotTreeMode.values.map((mode) {
509 return new OptionElement( 569 return new OptionElement(
510 value: modeToString(mode), 570 value: modeToString(mode),
511 selected: _mode == mode)..text = modeToString(mode); 571 selected: _mode == mode)..text = modeToString(mode);
512 }).toList(growable: false) 572 }).toList(growable: false)
513 ..onChange.listen((_) { 573 ..onChange.listen((_) {
514 _mode = HeapSnapshotTreeMode.values[s.selectedIndex]; 574 _mode = HeapSnapshotTreeMode.values[s.selectedIndex];
515 _r.dirty(); 575 _r.dirty();
516 }) 576 })
517 ]; 577 ];
518 } 578 }
519 } 579 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/object_graph.dart ('k') | runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698