Index: runtime/observatory/lib/src/elements/heap_snapshot.dart |
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart |
index 7389daa2aaea72ea8b4da9e9362cce68612f9534..830e1a0b7229551cb0b4827237d7011df01a20d3 100644 |
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart |
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart |
@@ -17,6 +17,7 @@ import 'package:observatory/src/elements/helpers/nav_bar.dart'; |
import 'package:observatory/src/elements/helpers/nav_menu.dart'; |
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
import 'package:observatory/src/elements/helpers/tag.dart'; |
+import 'package:observatory/src/elements/helpers/uris.dart'; |
import 'package:observatory/src/elements/nav/isolate_menu.dart'; |
import 'package:observatory/src/elements/nav/notify.dart'; |
import 'package:observatory/src/elements/nav/refresh.dart'; |
@@ -51,6 +52,7 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
M.HeapSnapshot _snapshot; |
Stream<M.HeapSnapshotLoadingProgressEvent> _progressStream; |
M.HeapSnapshotLoadingProgress _progress; |
+ M.HeapSnapshotRoots _roots = M.HeapSnapshotRoots.user; |
HeapSnapshotTreeMode _mode = HeapSnapshotTreeMode.dominatorTree; |
M.IsolateRef get isolate => _isolate; |
@@ -138,7 +140,9 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
Future _refresh() async { |
_progress = null; |
- _progressStream = _snapshots.get(isolate); |
+ _progressStream = _snapshots.get(isolate, |
+ roots: _roots, |
+ gc: true); |
_r.dirty(); |
_progressStream.listen((e) { |
_progress = e.progress; |
@@ -233,6 +237,16 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
..children = [ |
new DivElement() |
..classes = ['memberName'] |
+ ..text = 'Roots ', |
+ new DivElement() |
+ ..classes = ['memberName'] |
+ ..children = _createRootsSelect() |
+ ], |
+ new DivElement() |
+ ..classes = ['memberItem'] |
+ ..children = [ |
+ new DivElement() |
+ ..classes = ['memberName'] |
..text = 'Analysis ', |
new DivElement() |
..classes = ['memberName'] |
@@ -396,11 +410,20 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
..classes = ['name'] |
..text = 'Loading...'; |
element.children[4] = wrapper; |
- node.object.then((object) { |
+ if (node.isStack) { |
wrapper |
..text = '' |
- ..children = [anyRef(_isolate, object, _instances, queue: _r.queue)]; |
- }); |
+ ..children = [ |
+ new AnchorElement(href: Uris.debugger(isolate)) |
+ ..text = 'stack frames' |
+ ]; |
+ } else { |
+ node.object.then((object) { |
+ wrapper |
+ ..text = '' |
+ ..children = [anyRef(_isolate, object, _instances, queue: _r.queue)]; |
+ }); |
+ } |
} |
void _updateMergedDominator( |
@@ -418,14 +441,23 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
..classes = ['name'] |
..text = 'Loading...'; |
element.children[4] = wrapper; |
- node.klass.then((klass) { |
+ if (node.isStack) { |
wrapper |
..text = '' |
..children = [ |
- new SpanElement()..text = '${node.instanceCount} instances of ', |
- anyRef(_isolate, klass, _instances, queue: _r.queue) |
+ new AnchorElement(href: Uris.debugger(isolate)) |
+ ..text = 'stack frames' |
]; |
- }); |
+ } else { |
+ node.klass.then((klass) { |
+ wrapper |
+ ..text = '' |
+ ..children = [ |
+ new SpanElement()..text = '${node.instanceCount} instances of ', |
+ anyRef(_isolate, klass, _instances, queue: _r.queue) |
+ ]; |
+ }); |
+ } |
} |
void _updateGroup(HtmlElement element, item, int depth) { |
@@ -487,6 +519,34 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
} |
} |
+ static String rootsToString(M.HeapSnapshotRoots roots) { |
+ switch (roots) { |
+ case M.HeapSnapshotRoots.user: |
+ return 'User'; |
+ case M.HeapSnapshotRoots.vm: |
+ return 'VM'; |
+ } |
+ throw new Exception('Unknown HeapSnapshotRoots'); |
+ } |
+ |
+ List<Element> _createRootsSelect() { |
+ var s; |
+ return [ |
+ s = new SelectElement() |
+ ..classes = ['roots-select'] |
+ ..value = rootsToString(_roots) |
+ ..children = M.HeapSnapshotRoots.values.map((roots) { |
+ return new OptionElement( |
+ value: rootsToString(roots), |
+ selected: _roots == roots)..text = rootsToString(roots); |
+ }).toList(growable: false) |
+ ..onChange.listen((_) { |
+ _roots = M.HeapSnapshotRoots.values[s.selectedIndex]; |
+ _refresh(); |
+ }) |
+ ]; |
+ } |
+ |
static String modeToString(HeapSnapshotTreeMode mode) { |
switch (mode) { |
case HeapSnapshotTreeMode.dominatorTree: |
@@ -496,7 +556,7 @@ class HeapSnapshotElement extends HtmlElement implements Renderable { |
case HeapSnapshotTreeMode.groupByClass: |
return 'Group by class'; |
} |
- throw new Exception('Unknown ProfileTreeMode'); |
+ throw new Exception('Unknown HeapSnapshotTreeMode'); |
} |
List<Element> _createModeSelect() { |