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

Unified Diff: runtime/observatory/lib/src/elements/memory/profile.dart

Issue 3002843002: Introduce heap snapshot into Memory Dashboard (Closed)
Patch Set: Address CL comments Created 3 years, 4 months 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 side-by-side diff with in-line comments
Download patch
Index: runtime/observatory/lib/src/elements/memory/profile.dart
diff --git a/runtime/observatory/lib/src/elements/memory/profile.dart b/runtime/observatory/lib/src/elements/memory/profile.dart
index 2d0e0093f224b73b8b3a9000f03d00fc00ac44b2..34e52372d0fff3011f0bfef96605f06b1ab5638e 100644
--- a/runtime/observatory/lib/src/elements/memory/profile.dart
+++ b/runtime/observatory/lib/src/elements/memory/profile.dart
@@ -16,25 +16,19 @@
import 'dart:async';
import 'dart:html';
import 'package:observatory/models.dart' as M;
-import 'package:observatory/src/elements/class_ref.dart';
-import 'package:observatory/src/elements/containers/virtual_collection.dart';
import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/utils.dart';
+import 'package:observatory/src/elements/memory/allocations.dart';
+import 'package:observatory/src/elements/memory/snapshot.dart';
-enum _SortingField {
- accumulatedSize,
- accumulatedInstances,
- currentSize,
- currentInstances,
- className,
-}
-
-enum _SortingDirection { ascending, descending }
+enum _Analysis { allocations, dominatorTree }
class MemoryProfileElement extends HtmlElement implements Renderable {
static const tag = const Tag<MemoryProfileElement>('memory-profile',
- dependencies: const [ClassRefElement.tag, VirtualCollectionElement.tag]);
+ dependencies: const [
+ MemoryAllocationsElement.tag,
+ MemorySnapshotElement.tag
+ ]);
RenderingScheduler<MemoryProfileElement> _r;
@@ -42,28 +36,37 @@ class MemoryProfileElement extends HtmlElement implements Renderable {
M.IsolateRef _isolate;
M.EventRepository _events;
- M.AllocationProfileRepository _repository;
- M.AllocationProfile _profile;
+ M.AllocationProfileRepository _allocations;
M.EditorRepository _editor;
- StreamSubscription _gcSubscription;
- _SortingField _sortingField = _SortingField.accumulatedInstances;
- _SortingDirection _sortingDirection = _SortingDirection.descending;
+ M.HeapSnapshotRepository _snapshots;
+ M.ObjectRepository _objects;
+
+ _Analysis _analysis = _Analysis.allocations;
M.IsolateRef get isolate => _isolate;
- factory MemoryProfileElement(M.IsolateRef isolate, M.EditorRepository editor,
- M.EventRepository events, M.AllocationProfileRepository repository,
+ factory MemoryProfileElement(
+ M.IsolateRef isolate,
+ M.EditorRepository editor,
+ M.EventRepository events,
+ M.AllocationProfileRepository allocations,
+ M.HeapSnapshotRepository snapshots,
+ M.ObjectRepository objects,
{RenderingQueue queue}) {
assert(isolate != null);
assert(events != null);
assert(editor != null);
- assert(repository != null);
+ assert(allocations != null);
+ assert(snapshots != null);
+ assert(objects != null);
MemoryProfileElement e = document.createElement(tag.name);
e._r = new RenderingScheduler(e, queue: queue);
e._isolate = isolate;
e._editor = editor;
e._events = events;
- e._repository = repository;
+ e._allocations = allocations;
+ e._snapshots = snapshots;
+ e._objects = objects;
return e;
}
@@ -73,12 +76,6 @@ class MemoryProfileElement extends HtmlElement implements Renderable {
attached() {
super.attached();
_r.enable();
- _refresh();
- _gcSubscription = _events.onGCEvent.listen((e) {
- if (e.isolate.id == _isolate.id) {
- _refresh();
- }
- });
}
@override
@@ -86,172 +83,79 @@ class MemoryProfileElement extends HtmlElement implements Renderable {
super.detached();
_r.disable(notify: true);
children = [];
- _gcSubscription.cancel();
- }
-
- Future reload({bool gc = false, bool reset = false}) async {
- return _refresh(gc: gc, reset: reset);
}
void render() {
- if (_profile == null) {
- children = [
- new DivElement()
- ..classes = ['content-centered-big']
- ..children = [new HeadingElement.h2()..text = 'Loading...']
- ];
- } else {
- children = [
- new VirtualCollectionElement(
- _createCollectionLine, _updateCollectionLine,
- createHeader: _createCollectionHeader,
- items: _profile.members.toList()..sort(_createSorter()),
- queue: _r.queue)
- ];
- }
- }
-
- _createSorter() {
- var getter;
- switch (_sortingField) {
- case _SortingField.accumulatedSize:
- getter = _getAccumulatedSize;
- break;
- case _SortingField.accumulatedInstances:
- getter = _getAccumulatedInstances;
- break;
- case _SortingField.currentSize:
- getter = _getCurrentSize;
+ HtmlElement current;
+ var reload;
+ switch (_analysis) {
+ case _Analysis.allocations:
+ final MemoryAllocationsElement allocations =
+ new MemoryAllocationsElement(
+ _isolate, _editor, _events, _allocations);
+ current = allocations;
+ reload = ({bool gc: false}) => allocations.reload(gc: gc);
break;
- case _SortingField.currentInstances:
- getter = _getCurrentInstances;
+ case _Analysis.dominatorTree:
+ final MemorySnapshotElement snapshot =
+ new MemorySnapshotElement(_isolate, _editor, _snapshots, _objects);
+ current = snapshot;
+ reload = ({bool gc: false}) => snapshot.reload(gc: gc);
break;
- case _SortingField.className:
- getter = (M.ClassHeapStats s) => s.clazz.name;
- break;
- }
- switch (_sortingDirection) {
- case _SortingDirection.ascending:
- return (a, b) => getter(a).compareTo(getter(b));
- case _SortingDirection.descending:
- return (a, b) => getter(b).compareTo(getter(a));
}
- }
- static HtmlElement _createCollectionLine() => new DivElement()
- ..classes = ['collection-item']
- ..children = [
- new SpanElement()
- ..classes = ['bytes']
- ..text = '0B',
- new SpanElement()
- ..classes = ['instances']
- ..text = '0',
- new SpanElement()
- ..classes = ['bytes']
- ..text = '0B',
- new SpanElement()
- ..classes = ['instances']
- ..text = '0',
- new SpanElement()..classes = ['name']
- ];
+ assert(current != null);
- List<HtmlElement> _createCollectionHeader() {
- final resetAccumulators = new ButtonElement();
- return [
+ final ButtonElement bReload = new ButtonElement();
+ final ButtonElement bGC = new ButtonElement();
+ children = [
new DivElement()
- ..classes = ['collection-item']
+ ..classes = ['content-centered-big']
..children = [
- new SpanElement()
- ..classes = ['group']
+ new HeadingElement.h1()
..children = [
- new Text('Since Last '),
- resetAccumulators
- ..text = 'Reset↺'
- ..title = 'Reset'
- ..onClick.listen((_) async {
- resetAccumulators.disabled = true;
- await _refresh(reset: true);
- resetAccumulators.disabled = false;
- })
+ new Text("Isolate ${_isolate.name}"),
+ bReload
+ ..classes = ['link', 'big']
+ ..text = ' ↺ '
+ ..title = 'Refresh'
+ ..onClick.listen((e) async {
+ bReload.disabled = true;
+ bGC.disabled = true;
+ await reload();
+ bReload.disabled = false;
+ bGC.disabled = false;
+ }),
+ bGC
+ ..classes = ['link', 'big']
+ ..text = ' ♺ '
+ ..title = 'Collect Garbage'
+ ..onClick.listen((e) async {
+ bGC.disabled = true;
+ bReload.disabled = true;
+ await reload(gc: true);
+ bGC.disabled = false;
+ bReload.disabled = false;
+ }),
+ new ButtonElement()
+ ..classes = ['tab_button']
+ ..text = 'Dominator Tree'
+ ..disabled = _analysis == _Analysis.dominatorTree
+ ..onClick.listen((_) {
+ _analysis = _Analysis.dominatorTree;
+ _r.dirty();
+ }),
+ new ButtonElement()
+ ..classes = ['tab_button']
+ ..text = 'Allocations'
+ ..disabled = _analysis == _Analysis.allocations
+ ..onClick.listen((_) {
+ _analysis = _Analysis.allocations;
+ _r.dirty();
+ }),
],
- new SpanElement()
- ..classes = ['group']
- ..text = 'Current'
- ],
- new DivElement()
- ..classes = ['collection-item']
- ..children = [
- _createHeaderButton(const ['bytes'], 'Size',
- _SortingField.accumulatedSize, _SortingDirection.descending),
- _createHeaderButton(const ['instances'], 'Instances',
- _SortingField.accumulatedInstances, _SortingDirection.descending),
- _createHeaderButton(const ['bytes'], 'Size',
- _SortingField.currentSize, _SortingDirection.descending),
- _createHeaderButton(const ['instances'], 'Instances',
- _SortingField.currentInstances, _SortingDirection.descending),
- _createHeaderButton(const ['name'], 'Class', _SortingField.className,
- _SortingDirection.ascending)
],
+ current
];
}
-
- ButtonElement _createHeaderButton(List<String> classes, String text,
- _SortingField field, _SortingDirection direction) =>
- new ButtonElement()
- ..classes = classes
- ..text = _sortingField != field
- ? text
- : _sortingDirection == _SortingDirection.ascending
- ? '$text▼'
- : '$text▲'
- ..onClick.listen((_) => _setSorting(field, direction));
-
- void _setSorting(_SortingField field, _SortingDirection defaultDirection) {
- if (_sortingField == field) {
- switch (_sortingDirection) {
- case _SortingDirection.descending:
- _sortingDirection = _SortingDirection.ascending;
- break;
- case _SortingDirection.ascending:
- _sortingDirection = _SortingDirection.descending;
- break;
- }
- } else {
- _sortingDirection = defaultDirection;
- _sortingField = field;
- }
- _r.dirty();
- }
-
- void _updateCollectionLine(Element e, M.ClassHeapStats item, index) {
- e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
- e.children[1].text = '${_getAccumulatedInstances(item)}';
- e.children[2].text = Utils.formatSize(_getCurrentSize(item));
- e.children[3].text = '${_getCurrentInstances(item)}';
- e.children[4] = new ClassRefElement(_isolate, item.clazz, queue: _r.queue)
- ..classes = ['name'];
- Element.clickEvent.forTarget(e.children[4], useCapture: true).listen((e) {
- if (_editor.canOpenClass) {
- e.preventDefault();
- _editor.openClass(isolate, item.clazz);
- }
- });
- }
-
- Future _refresh({bool gc: false, bool reset: false}) async {
- _profile = null;
- _r.dirty();
- _profile = await _repository.get(_isolate, gc: gc, reset: reset);
- _r.dirty();
- }
-
- static int _getAccumulatedSize(M.ClassHeapStats s) =>
- s.newSpace.accumulated.bytes + s.oldSpace.accumulated.bytes;
- static int _getAccumulatedInstances(M.ClassHeapStats s) =>
- s.newSpace.accumulated.instances + s.oldSpace.accumulated.instances;
- static int _getCurrentSize(M.ClassHeapStats s) =>
- s.newSpace.current.bytes + s.oldSpace.current.bytes;
- static int _getCurrentInstances(M.ClassHeapStats s) =>
- s.newSpace.current.instances + s.oldSpace.current.instances;
}
« no previous file with comments | « runtime/observatory/lib/src/elements/memory/dashboard.dart ('k') | runtime/observatory/lib/src/elements/memory/snapshot.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698