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

Unified Diff: runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart

Issue 2266343002: Converted Observatory heap-snapshot element (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Removed debug code Created 4 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/heap_snapshot/heap_snapshot.dart
diff --git a/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart b/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart
new file mode 100644
index 0000000000000000000000000000000000000000..71f41e4f948d29e813ee2938da7d779abdcead18
--- /dev/null
+++ b/runtime/observatory/lib/src/heap_snapshot/heap_snapshot.dart
@@ -0,0 +1,226 @@
+// 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 heap_snapshot;
+
+class HeapSnapshot implements M.HeapSnapshot {
+ ObjectGraph graph;
+ DateTime timestamp;
+ int get objects => graph.vertexCount;
+ int get references => graph.edgeCount;
+ int get size => graph.size;
+ HeapSnapshotDominatorNode dominatorTree;
+ List<MergedVertex> classReferences;
+
+ static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
+ final Completer completer = new Completer();
+ new Timer(duration, () => completer.complete() );
+ return completer.future;
+ }
+
+ Stream<List> loadProgress(S.Isolate isolate, S.RawHeapSnapshot raw) {
+ final progress = new StreamController<List>.broadcast();
+ progress.add(['', 0.0]);
+ graph = new ObjectGraph(raw.chunks, raw.count);
+ var signal = (String description, double p) {
+ progress.add([description, p]);
+ return sleep();
+ };
+ (() async {
+ timestamp = new DateTime.now();
+ final stream = graph.process();
+ stream.listen((status) {
+ status[1] /= 2.0;
+ progress.add(status);
+ });
+ await stream.last;
+ dominatorTree = new HeapSnapshotDominatorNode(isolate, graph.root);
+ classReferences = await buildMergedVertices(isolate, graph, signal);
+ progress.close();
+ }());
+ return progress.stream;
+ }
+
+ Future<List<MergedVertex>> buildMergedVertices(S.Isolate isolate,
+ ObjectGraph graph,
+ signal) async {
+ final cidToMergedVertex = {};
+
+ int count = 0;
+ final Stopwatch watch = new Stopwatch();
+ watch.start();
+ var needToUpdate = () {
+ count++;
+ if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) {
+ watch.reset();
+ return true;
+ }
+ return false;
+ };
+ final length = graph.vertices.length;
+ for (final vertex in graph.vertices) {
+ if (vertex.vmCid == 0) {
+ continue;
+ }
+ if (needToUpdate()) {
+ await signal('', count * 50.0 / length + 50);
+ }
+ final cid = vertex.vmCid;
+ MergedVertex source = cidToMergedVertex[cid];
+ if (source == null) {
+ cidToMergedVertex[cid] = source = new MergedVertex(isolate, cid);
+ }
+
+ source.instances++;
+ source.shallowSize += vertex.shallowSize ?? 0;
+
+ for (final vertex2 in vertex.successors) {
+ if (vertex2.vmCid == 0) {
+ continue;
+ }
+ final cid2 = vertex2.vmCid;
+ MergedEdge edge = source.outgoingEdges[cid2];
+ if (edge == null) {
+ MergedVertex target = cidToMergedVertex[cid2];
+ if (target == null) {
+ cidToMergedVertex[cid2] = target = new MergedVertex(isolate, cid2);
+ }
+ edge = new MergedEdge(source, target);
+ source.outgoingEdges[cid2] = edge;
+ target.incomingEdges.add(edge);
+ }
+ edge.count++;
+ // An over-estimate if there are multiple references to the same object.
+ edge.shallowSize += vertex2.shallowSize ?? 0;
+ }
+ }
+ return cidToMergedVertex.values.toList();
+ }
+
+ List<Future<S.ServiceObject>> getMostRetained(S.Isolate isolate,
+ {int classId, int limit}) {
+ var result = [];
+ for (ObjectVertex v in graph.getMostRetained(classId: classId,
+ limit: limit)) {
+ result.add(isolate.getObjectByAddress(v.address)
+ .then((S.ServiceObject obj) {
+ if (obj is S.HeapObject) {
+ obj.retainedSize = v.retainedSize;
+ } else {
+ print("${obj.runtimeType} should be a HeapObject");
+ }
+ return obj;
+ }));
+ }
+ return result;
+ }
+}
+
+class HeapSnapshotDominatorNode implements M.HeapSnapshotDominatorNode {
+ final ObjectVertex v;
+ final S.Isolate isolate;
+ S.HeapObject _preloaded;
+
+ Future<S.HeapObject> get object {
+ if (_preloaded != null) {
+ return new Future.value(_preloaded);
+ } else {
+ return isolate.getObjectByAddress(v.address).then((S.HeapObject obj) {
+ return _preloaded = obj;
+ });
+ }
+ }
+ Iterable<HeapSnapshotDominatorNode> _children;
+ Iterable<HeapSnapshotDominatorNode> get children {
+ if (_children != null) {
+ return _children;
+ } else {
+ return _children = new List.unmodifiable(
+ v.dominatorTreeChildren().map((v) {
+ return new HeapSnapshotDominatorNode(isolate, v);
+ })
+ );
+ }
+ }
+ int get retainedSize => v.retainedSize;
+ int get shallowSize => v.shallowSize;
+
+ HeapSnapshotDominatorNode(S.Isolate isolate, ObjectVertex vertex)
+ : isolate = isolate,
+ v = vertex;
+}
+
+class MergedEdge {
+ final MergedVertex sourceVertex;
+ final MergedVertex targetVertex;
+ int count = 0;
+ int shallowSize = 0;
+ int retainedSize = 0;
+
+ MergedEdge(this.sourceVertex, this.targetVertex);
+}
+
+class MergedVertex implements M.HeapSnapshotClassReferences {
+ final int cid;
+ final S.Isolate isolate;
+ S.Class get clazz => isolate.getClassByCid(cid);
+ int instances = 0;
+ int shallowSize = 0;
+ int retainedSize = 0;
+
+ List<MergedEdge> incomingEdges = new List<MergedEdge>();
+ Map<int, MergedEdge> outgoingEdges = new Map<int, MergedEdge>();
+
+ Iterable<HeapSnapshotClassInbound> _inbounds;
+ Iterable<HeapSnapshotClassInbound> get inbounds {
+ if (_inbounds != null) {
+ return _inbounds;
+ } else {
+ return _inbounds = new List.unmodifiable(
+ incomingEdges.map((edge) {
+ return new HeapSnapshotClassInbound(this, edge);
+ })
+ );
+ }
+ }
+
+ Iterable<HeapSnapshotClassOutbound> _outbounds;
+ Iterable<HeapSnapshotClassOutbound> get outbounds {
+ if (_outbounds != null) {
+ return _outbounds;
+ } else {
+ return _outbounds = new List.unmodifiable(
+ outgoingEdges.values.map((edge) {
+ return new HeapSnapshotClassInbound(this, edge);
+ })
+ );
+ }
+ }
+
+ MergedVertex(this.isolate, this.cid);
+}
+
+class HeapSnapshotClassInbound implements M.HeapSnapshotClassInbound {
+ final MergedVertex vertex;
+ final MergedEdge edge;
+ S.Class get source => edge.sourceVertex != vertex ? edge.sourceVertex.clazz
+ : edge.targetVertex.clazz;
+ int get count => edge.count;
+ int get shallowSize => edge.shallowSize;
+ int get retainedSize => edge.retainedSize;
+
+ HeapSnapshotClassInbound(this.vertex, this.edge);
+}
+
+class HeapSnapshotClassOutbound implements M.HeapSnapshotClassOutbound {
+ final MergedVertex vertex;
+ final MergedEdge edge;
+ S.Class get target => edge.sourceVertex != vertex ? edge.sourceVertex.clazz
+ : edge.targetVertex.clazz;
+ int get count => edge.count;
+ int get shallowSize => edge.shallowSize;
+ int get retainedSize => edge.retainedSize;
+
+ HeapSnapshotClassOutbound(this.vertex, this.edge);
+}
« no previous file with comments | « runtime/observatory/lib/src/elements/service_view.html ('k') | runtime/observatory/lib/src/models/objects/heap_snapshot.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698