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

Side by Side Diff: runtime/bin/vmservice/observatory/lib/object_graph.dart

Issue 777693002: Compute retained size for every object, using dominator trees. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library object_graph; 5 library object_graph;
6 6
7 import 'dart:typed_data'; 7 import 'dart:typed_data';
8 8
9 import 'dominator_tree.dart';
10
9 // Port of dart::ReadStream from vm/datastream.h. 11 // Port of dart::ReadStream from vm/datastream.h.
10 class ReadStream { 12 class ReadStream {
11 int _cur = 0; 13 int _cur = 0;
12 final ByteData _data; 14 final ByteData _data;
13 15
14 ReadStream(this._data); 16 ReadStream(this._data);
15 17
16 int get pendingBytes => _data.lengthInBytes - _cur; 18 int get pendingBytes => _data.lengthInBytes - _cur;
17 19
18 int readUnsigned() { 20 int readUnsigned() {
19 int result = 0; 21 int result = 0;
20 int shift = 0; 22 int shift = 0;
21 while (_data.getUint8(_cur) <= maxUnsignedDataPerByte) { 23 while (_data.getUint8(_cur) <= maxUnsignedDataPerByte) {
22 result |= _data.getUint8(_cur) << shift; 24 result |= _data.getUint8(_cur) << shift;
23 shift += dataBitsPerByte; 25 shift += dataBitsPerByte;
24 ++_cur; 26 ++_cur;
25 } 27 }
26 result |= (_data.getUint8(_cur) & byteMask) << shift; 28 result |= (_data.getUint8(_cur) & byteMask) << shift;
27 ++_cur; 29 ++_cur;
28 return result; 30 return result;
29 } 31 }
30 32
31 static const int dataBitsPerByte = 7; 33 static const int dataBitsPerByte = 7;
32 static const int byteMask = (1 << dataBitsPerByte) - 1; 34 static const int byteMask = (1 << dataBitsPerByte) - 1;
33 static const int maxUnsignedDataPerByte = byteMask; 35 static const int maxUnsignedDataPerByte = byteMask;
34 } 36 }
35 37
36 class ObjectVertex { 38 class ObjectVertex {
37 // Never null. 39 // Never null. The isolate root has id 0.
38 final int _id; 40 final int _id;
39 // null for VM-heap objects. 41 // null for VM-heap objects.
40 int _size; 42 int _shallowSize;
41 int get size => _size; 43 int get shallowSize => _shallowSize;
44 int _retainedSize;
45 int get retainedSize => _retainedSize;
42 // null for VM-heap objects. 46 // null for VM-heap objects.
43 int _classId; 47 int _classId;
44 int get classId => _classId; 48 int get classId => _classId;
45 final List<ObjectVertex> succ = new List<ObjectVertex>(); 49 final List<ObjectVertex> succ = new List<ObjectVertex>();
46 ObjectVertex(this._id); 50 ObjectVertex(this._id) : _retainedSize = 0;
51 String toString() => '$_id,$_shallowSize,$succ';
47 } 52 }
48 53
49 // See implementation of ObjectGraph::Serialize for format. 54 // See implementation of ObjectGraph::Serialize for format.
50 class ObjectGraph { 55 class ObjectGraph {
51 final Map<int, ObjectVertex> _idToVertex = new Map<int, ObjectVertex>(); 56 final Map<int, ObjectVertex> _idToVertex = new Map<int, ObjectVertex>();
52 57
53 ObjectVertex _asVertex(int id) { 58 ObjectVertex _asVertex(int id) {
54 return _idToVertex.putIfAbsent(id, () => new ObjectVertex(id)); 59 return _idToVertex.putIfAbsent(id, () => new ObjectVertex(id));
55 } 60 }
56 61
57 void _addFrom(ReadStream stream) { 62 void _addFrom(ReadStream stream) {
58 ObjectVertex obj = _asVertex(stream.readUnsigned()); 63 ObjectVertex obj = _asVertex(stream.readUnsigned());
59 obj._size = stream.readUnsigned(); 64 obj._shallowSize = stream.readUnsigned();
60 obj._classId = stream.readUnsigned(); 65 obj._classId = stream.readUnsigned();
61 int last = stream.readUnsigned(); 66 int last = stream.readUnsigned();
62 while (last != 0) { 67 while (last != 0) {
63 obj.succ.add(_asVertex(last)); 68 obj.succ.add(_asVertex(last));
64 last = stream.readUnsigned(); 69 last = stream.readUnsigned();
65 } 70 }
66 } 71 }
67 72
68 ObjectGraph(ReadStream reader) { 73 ObjectGraph(ReadStream reader) {
69 while (reader.pendingBytes > 0) { 74 while (reader.pendingBytes > 0) {
70 _addFrom(reader); 75 _addFrom(reader);
71 } 76 }
77 _computeRetainedSizes();
72 } 78 }
73 79
74 Iterable<ObjectVertex> get vertices => _idToVertex.values; 80 Iterable<ObjectVertex> get vertices => _idToVertex.values;
81
82 ObjectVertex get root => _asVertex(0);
83
84 void _computeRetainedSizes() {
85 // The retained size for an object is the sum of the shallow sizes of
Cutch 2014/12/04 18:34:54 could you fast path by checking if _retainedSize !
koda 2014/12/04 19:27:27 This private method is currently always called exa
86 // all its descendants in the dominator tree (including itself).
87 var d = new Dominator();
88 for (ObjectVertex u in vertices) {
89 if (u.shallowSize != null) {
90 u._retainedSize = u.shallowSize;
91 d.addEdges(u, u.succ.where((ObjectVertex v) => v.shallowSize != null));
92 }
93 }
94 d.computeDominatorTree(root);
95 // Compute all retained sizes "bottom up", starting from the leaves.
96 // Keep track of number of remaining children of each vertex.
97 var degree = new Map<ObjectVertex, int>();
98 for (ObjectVertex u in vertices) {
99 var v = d.dominator(u);
100 if (v != null) {
101 degree[v] = 1 + degree.putIfAbsent(v, () => 0);
102 }
103 }
104 var leaves = new List<ObjectVertex>();
105 for (ObjectVertex u in vertices) {
106 if (!degree.containsKey(u)) {
107 leaves.add(u);
108 }
109 }
110 while (!leaves.isEmpty) {
111 var v = leaves.removeLast();
112 var u = d.dominator(v);
113 if (u == null) continue;
114 u._retainedSize += v._retainedSize;
115 if (--degree[u] == 0) {
116 leaves.add(u);
117 }
118 }
119 }
75 } 120 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698