Index: runtime/observatory/lib/src/repositories/heap_snapshot.dart |
diff --git a/runtime/observatory/lib/src/repositories/heap_snapshot.dart b/runtime/observatory/lib/src/repositories/heap_snapshot.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..04891975ce198709e850d05edc895a62586756b6 |
--- /dev/null |
+++ b/runtime/observatory/lib/src/repositories/heap_snapshot.dart |
@@ -0,0 +1,112 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file |
+ |
+part of repositories; |
+ |
+class HeapSnapshotLoadingProgressEvent |
+ implements M.HeapSnapshotLoadingProgressEvent { |
+ final HeapSnapshotLoadingProgress progress; |
+ HeapSnapshotLoadingProgressEvent(this.progress); |
+} |
+ |
+class HeapSnapshotLoadingProgress extends M.HeapSnapshotLoadingProgress { |
+ StreamController<HeapSnapshotLoadingProgressEvent> _onProgress = |
+ new StreamController<HeapSnapshotLoadingProgressEvent>.broadcast(); |
+ Stream<HeapSnapshotLoadingProgressEvent> get onProgress => |
+ _onProgress.stream; |
+ |
+ final S.Isolate isolate; |
+ final bool gc; |
+ |
+ M.HeapSnapshotLoadingStatus _status = M.HeapSnapshotLoadingStatus.fetching; |
+ String _stepDescription = ''; |
+ double _progress = 0.0; |
+ final Stopwatch _fetchingTime = new Stopwatch(); |
+ final Stopwatch _loadingTime = new Stopwatch(); |
+ HeapSnapshot _snapshot; |
+ |
+ M.HeapSnapshotLoadingStatus get status => _status; |
+ String get stepDescription => _stepDescription; |
+ double get progress => _progress; |
+ Duration get fetchingTime => _fetchingTime.elapsed; |
+ Duration get loadingTime => _loadingTime.elapsed; |
+ HeapSnapshot get snapshot => _snapshot; |
+ |
+ HeapSnapshotLoadingProgress(this.isolate, this.gc) { |
+ _run(); |
+ } |
+ |
+ Future _run() async { |
+ _fetchingTime.start(); |
+ try { |
+ _status = M.HeapSnapshotLoadingStatus.fetching; |
+ _triggerOnProgress(); |
+ |
+ await isolate.getClassRefs(); |
+ |
+ final stream = isolate.fetchHeapSnapshot(gc); |
+ |
+ stream.listen((status) { |
+ if (status is List) { |
+ _progress = status[0] * 100.0 / status[1]; |
+ _stepDescription = 'Receiving snapshot chunk ${status[0] + 1}' |
+ ' of ${status[1]}...'; |
+ _triggerOnProgress(); |
+ } |
+ }); |
+ |
+ final response = await stream.last; |
+ |
+ _fetchingTime.stop(); |
+ _loadingTime.start(); |
+ _status = M.HeapSnapshotLoadingStatus.loading; |
+ _stepDescription = ''; |
+ _triggerOnProgress(); |
+ |
+ HeapSnapshot snapshot = new HeapSnapshot(); |
+ |
+ Stream<List> progress = snapshot.loadProgress(isolate, response); |
+ progress.listen((value) { |
+ _stepDescription = value[0]; |
+ _progress = value[1]; |
+ _triggerOnProgress(); |
+ }); |
+ |
+ await progress.drain(); |
+ |
+ _snapshot = snapshot; |
+ |
+ _loadingTime.stop(); |
+ _status = M.HeapSnapshotLoadingStatus.loaded; |
+ _triggerOnProgress(); |
+ } finally { |
+ _onProgress.close(); |
+ } |
+ } |
+ |
+ void _triggerOnProgress() { |
+ _onProgress.add(new HeapSnapshotLoadingProgressEvent(this)); |
+ } |
+ |
+ void reuse() { |
+ _onProgress = |
+ new StreamController<HeapSnapshotLoadingProgressEvent>.broadcast(); |
+ (() async { |
+ _triggerOnProgress(); |
+ _onProgress.close(); |
+ }()); |
+ } |
+} |
+ |
+class HeapSnapshotRepository |
+ implements M.HeapSnapshotRepository { |
+ |
+ Stream<HeapSnapshotLoadingProgressEvent> get(M.IsolateRef i, |
+ {bool gc: false}) { |
+ S.Isolate isolate = i as S.Isolate; |
+ assert(isolate != null); |
+ assert(gc != null); |
+ return new HeapSnapshotLoadingProgress(isolate, gc).onProgress; |
+ } |
+} |