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

Unified Diff: runtime/observatory/lib/src/service/object.dart

Issue 1124153006: Heap snapshot visualizations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: sync Created 5 years, 7 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/service/object.dart
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 4c8d17370246e097735fb9351a896dd29e9649fc..46e84a7e518cf2d630aa7f5df19ed6815b5e029c 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -827,10 +827,9 @@ class HeapSnapshot {
final DateTime timeStamp;
final Isolate isolate;
- HeapSnapshot(this.isolate, ByteData data) :
- graph = new ObjectGraph(new ReadStream(data)),
- timeStamp = new DateTime.now() {
- }
+ HeapSnapshot(this.isolate, chunks, nodeCount) :
+ graph = new ObjectGraph(chunks, nodeCount),
+ timeStamp = new DateTime.now();
List<Future<ServiceObject>> getMostRetained({int classId, int limit}) {
var result = [];
@@ -843,8 +842,6 @@ class HeapSnapshot {
}
return result;
}
-
-
}
/// State for a running isolate.
@@ -905,6 +902,20 @@ class Isolate extends ServiceObjectOwner with Coverage {
.then(_buildClassHierarchy);
}
+ Future<List<Class>> getClassRefs() async {
+ ServiceMap classList = await invokeRpc('getClassList', {});
+ assert(classList.type == 'ClassList');
+ var classRefs = [];
+ for (var cls in classList['classes']) {
+ // Skip over non-class classes.
+ if (cls is Class) {
+ _classesByCid[cls.vmCid] = cls;
+ classRefs.add(cls);
+ }
+ }
+ return classRefs;
+ }
+
/// Given the class list, loads each class.
Future<List<Class>> _loadClasses(ServiceMap classList) {
assert(classList.type == 'ClassList');
@@ -912,6 +923,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
for (var cls in classList['classes']) {
// Skip over non-class classes.
if (cls is Class) {
+ _classesByCid[cls.vmCid] = cls;
futureClasses.add(cls.load());
}
}
@@ -934,6 +946,8 @@ class Isolate extends ServiceObjectOwner with Coverage {
return new Future.value(objectClass);
}
+ Class getClassByCid(int cid) => _classesByCid[cid];
+
ServiceObject getFromMap(ObservableMap map) {
if (map == null) {
return null;
@@ -986,6 +1000,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
@observable Class objectClass;
@observable final rootClasses = new ObservableList<Class>();
+ Map<int, Class> _classesByCid = new Map<int, Class>();
@observable Library rootLibrary;
@observable ObservableList<Library> libraries =
@@ -1006,21 +1021,51 @@ class Isolate extends ServiceObjectOwner with Coverage {
@observable DartError error;
@observable HeapSnapshot latestSnapshot;
- Completer<HeapSnapshot> _snapshotFetch;
+ StreamController _snapshotFetch;
+
+ List<ByteData> _chunksInProgress;
void _loadHeapSnapshot(ServiceEvent event) {
- latestSnapshot = new HeapSnapshot(this, event.data);
+ if (_snapshotFetch == null || _snapshotFetch.isClosed) {
+ // No outstanding snapshot request. Presumably another client asked for a
+ // snapshot.
+ Logger.root.info("Dropping unsolicited heap snapshot chunk");
+ return;
+ }
+
+ // Occasionally these actually arrive out of order.
+ var chunkIndex = event.chunkIndex;
+ var chunkCount = event.chunkCount;
+ if (_chunksInProgress == null) {
+ _chunksInProgress = new List(chunkCount);
+ }
+ _chunksInProgress[chunkIndex] = event.data;
+ _snapshotFetch.add("Receiving snapshot chunk ${chunkIndex + 1}"
+ " of $chunkCount...");
+
+ for (var i = 0; i < chunkCount; i++) {
+ if (_chunksInProgress[i] == null) return;
+ }
+
+ var loadedChunks = _chunksInProgress;
+ _chunksInProgress = null;
+
+ latestSnapshot = new HeapSnapshot(this, loadedChunks, event.nodeCount);
if (_snapshotFetch != null) {
- _snapshotFetch.complete(latestSnapshot);
+ latestSnapshot.graph.process(_snapshotFetch).then((graph) {
+ _snapshotFetch.add(latestSnapshot);
+ _snapshotFetch.close();
+ });
}
}
- Future<HeapSnapshot> fetchHeapSnapshot() {
- if (_snapshotFetch == null || _snapshotFetch.isCompleted) {
- _snapshotFetch = new Completer<HeapSnapshot>();
+ Stream fetchHeapSnapshot() {
+ if (_snapshotFetch == null || _snapshotFetch.isClosed) {
+ _snapshotFetch = new StreamController();
+ isolate.vm.streamListen('_Graph');
isolate.invokeRpcNoUpgrade('requestHeapSnapshot', {});
}
- return _snapshotFetch.future;
+ return _snapshotFetch.stream;
}
void updateHeapsFromMap(ObservableMap map) {
@@ -1458,6 +1503,7 @@ class ServiceEvent extends ServiceObject {
@observable ByteData data;
@observable int count;
@observable String reason;
+ int chunkIndex, chunkCount, nodeCount;
@observable bool get isPauseEvent {
return (eventType == kPauseStart ||
@@ -1490,6 +1536,15 @@ class ServiceEvent extends ServiceObject {
if (map['_data'] != null) {
data = map['_data'];
}
+ if (map['chunkIndex'] != null) {
+ chunkIndex = map['chunkIndex'];
+ }
+ if (map['chunkCount'] != null) {
+ chunkCount = map['chunkCount'];
+ }
+ if (map['nodeCount'] != null) {
+ nodeCount = map['nodeCount'];
+ }
if (map['count'] != null) {
count = map['count'];
}
« no previous file with comments | « runtime/observatory/lib/src/elements/service_view.html ('k') | runtime/observatory/observatory_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698