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

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

Issue 1219103002: Deal with Javascript integer limitations in heap snapshot processing to handle 64-bit target VMs. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 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 unified diff | Download patch
« no previous file with comments | « no previous file | runtime/observatory/lib/src/elements/heap_snapshot.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:typed_data'; 9 import 'dart:typed_data';
10 10
11 import 'package:logging/logging.dart'; 11 import 'package:logging/logging.dart';
12 12
13 // Map<[uint32, uint32, uint32], uint32>
14 class AddressMapper {
15 final Uint32List _table;
16
17 // * 4 ~/3 for 75% load factor
18 // * 4 for four-tuple entries
19 AddressMapper(int N) : _table = new Uint32List((N * 4 ~/ 3) * 4);
20
21 // Jenkin's smi hash.
22 static int combine(int hash, int value) {
23 hash = 0x1fffffff & (hash + value);
24 hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
25 return hash ^ (hash >> 6);
26 }
27
28 static int finish(int hash) {
29 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
30 hash = hash ^ (hash >> 11);
31 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
32 }
33
34 static int hash3(a, b, c) => finish(combine(combine(combine(0, a), b), c));
35
36 int scanFor(int high, int mid, int low) {
37 var hash = hash3(high, mid, low);
38 var start = (hash % _table.length) & ~3;
39 var index = start;
40 do {
41 if (_table[index + 3] == 0) return index;
42 if (_table[index] == high &&
43 _table[index + 1] == mid &&
44 _table[index + 2] == low) return index;
45 index = (index + 4) % _table.length;
46 } while (index != start);
47
48 throw new Exception("Interal error: table full");
49 }
50
51 int get(int high, int mid, int low) {
52 int index = scanFor(high, mid, low);
53 if (_table[index + 3] == 0) return null;
54 return _table[index + 3];
55 }
56
57 int put(int high, int mid, int low, int id) {
58 if (id == 0) throw new Exception("Invalid error: invalid key");
59
60 int index = scanFor(high, mid, low);
61 if ((_table[index + 3] != 0)) {
62 throw new Exception("Internal error: attempt to overwrite key");
63 }
64 _table[index] = high;
65 _table[index + 1] = mid;
66 _table[index + 2] = low;
67 _table[index + 3] = id;
68 }
69 }
70
71
13 // Port of dart::ReadStream from vm/datastream.h. 72 // Port of dart::ReadStream from vm/datastream.h.
14 class _ReadStream { 73 class _ReadStream {
15 int position = 0; 74 int position = 0;
16 int _size = 0; 75 int _size = 0;
17 final List<ByteData> _chunks; 76 final List<ByteData> _chunks;
18 77
19 _ReadStream(this._chunks) { 78 _ReadStream(this._chunks) {
20 int n = _chunks.length; 79 int n = _chunks.length;
21 for (var i = 0; i < n; i++) { 80 for (var i = 0; i < n; i++) {
22 var chunk = _chunks[i]; 81 var chunk = _chunks[i];
23 if (i + 1 != n) { 82 if (i + 1 != n) {
24 assert(chunk.lengthInBytes == (1 << 20)); 83 assert(chunk.lengthInBytes == (1 << 20));
25 } 84 }
26 _size += chunk.lengthInBytes; 85 _size += chunk.lengthInBytes;
27 } 86 }
28 } 87 }
29 88
30 int get pendingBytes => _size - position; 89 int get pendingBytes => _size - position;
31 90
32 int getUint8(i) { 91 int getUint8(i) {
33 return _chunks[i >> 20].getUint8(i & 0xFFFFF); 92 return _chunks[i >> 20].getUint8(i & 0xFFFFF);
34 } 93 }
35 94
36 int readUnsigned() { 95 int low = 0;
37 int result = 0; 96 int mid = 0;
38 int shift = 0; 97 int high = 0;
39 while (getUint8(position) <= maxUnsignedDataPerByte) { 98
40 result |= getUint8(position) << shift; 99 int get smallValue {
41 shift += dataBitsPerByte; 100 assert(high == 0);
42 position++; 101 assert(mid == 0);
102 return (high << 56) | (mid << 28) | low;
sra1 2015/07/01 17:09:33 why do this when they are zero? You can get corre
rmacnak 2015/07/07 23:19:05 The intent was to still allow large values on Dart
103 }
104
105 bool get isZero {
106 return (high == 0) && (mid == 0) && (low == 0);
107 }
108
109 void readUnsigned() {
110 low = 0;
111 mid = 0;
112 high = 0;
113
114 // Low 28 bits.
115 var digit = getUint8(position++);
116 if (digit > maxUnsignedDataPerByte) {
117 low |= (digit & byteMask << 0);
118 return;
43 } 119 }
44 result |= (getUint8(position) & byteMask) << shift; 120 low |= (digit << 0);
45 position++; 121
46 return result; 122 digit = getUint8(position++);
123 if (digit > maxUnsignedDataPerByte) {
124 low |= ((digit & byteMask) << 7);
125 return;
126 }
127 low |= (digit << 7);
128
129 digit = getUint8(position++);
130 if (digit > maxUnsignedDataPerByte) {
131 low |= ((digit & byteMask) << 14);
132 return;
133 }
134 low |= (digit << 14);
135
136 digit = getUint8(position++);
137 if (digit > maxUnsignedDataPerByte) {
138 low |= ((digit & byteMask) << 21);
139 return;
140 }
141 low |= (digit << 21);
142
143 // Mid 28 bits.
144 digit = getUint8(position++);
145 if (digit > maxUnsignedDataPerByte) {
146 mid |= (digit & byteMask << 0);
147 return;
148 }
149 mid |= (digit << 0);
150
151 digit = getUint8(position++);
152 if (digit > maxUnsignedDataPerByte) {
153 mid |= ((digit & byteMask) << 7);
154 return;
155 }
156 mid |= (digit << 7);
157
158 digit = getUint8(position++);
159 if (digit > maxUnsignedDataPerByte) {
160 mid |= ((digit & byteMask) << 14);
161 return;
162 }
163 mid |= (digit << 14);
164
165 digit = getUint8(position++);
166 if (digit > maxUnsignedDataPerByte) {
167 mid |= ((digit & byteMask) << 21);
168 return;
169 }
170 mid |= (digit << 21);
171
172 // High 28 bits.
173 digit = getUint8(position++);
174 if (digit > maxUnsignedDataPerByte) {
175 high |= (digit & byteMask << 0);
176 return;
177 }
178 high |= (digit << 0);
179
180 digit = getUint8(position++);
181 if (digit > maxUnsignedDataPerByte) {
182 high |= ((digit & byteMask) << 7);
183 return;
184 }
185 high |= (digit << 7);
186 throw new Exception("Format error: snapshot field exceeds 64 bits");
187 }
188
189 void skipUnsigned() {
190 while (getUint8(position++) <= maxUnsignedDataPerByte);
47 } 191 }
48 192
49 static const int dataBitsPerByte = 7; 193 static const int dataBitsPerByte = 7;
50 static const int byteMask = (1 << dataBitsPerByte) - 1; 194 static const int byteMask = (1 << dataBitsPerByte) - 1;
51 static const int maxUnsignedDataPerByte = byteMask; 195 static const int maxUnsignedDataPerByte = byteMask;
52 } 196 }
53 197
54 class ObjectVertex { 198 class ObjectVertex {
55 // 0 represents invalid/uninitialized, 1 is the root. 199 // 0 represents invalid/uninitialized, 1 is the root.
56 final int _id; 200 final int _id;
57 final ObjectGraph _graph; 201 final ObjectGraph _graph;
58 202
59 ObjectVertex._(this._id, this._graph); 203 ObjectVertex._(this._id, this._graph);
60 204
61 bool get isRoot => _id == 1; 205 bool get isRoot => _id == 1;
62 206
63 bool operator ==(other) => _id == other._id && _graph == other._graph; 207 bool operator ==(other) => _id == other._id && _graph == other._graph;
64 int get hashCode => _id; 208 int get hashCode => _id;
65 209
66 int get retainedSize => _graph._retainedSizes[_id]; 210 int get retainedSize => _graph._retainedSizes[_id];
67 ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph); 211 ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph);
68 212
69 int get shallowSize { 213 int get shallowSize {
70 var stream = new _ReadStream(_graph._chunks); 214 var stream = new _ReadStream(_graph._chunks);
71 stream.position = _graph._positions[_id]; 215 stream.position = _graph._positions[_id];
72 stream.readUnsigned(); // addr 216 stream.skipUnsigned(); // addr
73 return stream.readUnsigned(); // shallowSize 217 stream.readUnsigned(); // shallowSize
218 return stream.smallValue;
74 } 219 }
75 220
76 int get vmCid { 221 int get vmCid {
77 var stream = new _ReadStream(_graph._chunks); 222 var stream = new _ReadStream(_graph._chunks);
78 stream.position = _graph._positions[_id]; 223 stream.position = _graph._positions[_id];
79 stream.readUnsigned(); // addr 224 stream.skipUnsigned(); // addr
80 stream.readUnsigned(); // shallowSize 225 stream.skipUnsigned(); // shallowSize
81 return stream.readUnsigned(); // cid 226 stream.readUnsigned(); // cid
227 return stream.smallValue;
82 } 228 }
83 229
84 get successors => new _SuccessorsIterable(_graph, _id); 230 get successors => new _SuccessorsIterable(_graph, _id);
85 231
86 int get address { 232 String get address {
87 // Note that everywhere else in this file, "address" really means an address 233 // Note that everywhere else in this file, "address" really means an address
88 // scaled down by kObjectAlignment. They were scaled down so they would fit 234 // scaled down by kObjectAlignment. They were scaled down so they would fit
89 // into Smis on the client. 235 // into Smis on the client.
90 var stream = new _ReadStream(_graph._chunks); 236 var stream = new _ReadStream(_graph._chunks);
91 stream.position = _graph._positions[_id]; 237 stream.position = _graph._positions[_id];
92 var scaledAddr = stream.readUnsigned(); 238 stream.readUnsigned();
93 return scaledAddr * _graph._kObjectAlignment; 239
240 // Complicated way to do (high:mid:low * _kObjectAlignment).toHexString()
241 // without intermediate values exceeding int32.
242
243 var strAddr = "";
244 var carry = 0;
245 combine4(nibble) {
246 nibble = nibble * _graph._kObjectAlignment + carry;
247 carry = nibble >> 4;
248 nibble = nibble & 0xF;
249 strAddr = nibble.toRadixString(16) + strAddr;
250 }
251 combine28(twentyEightBits) {
252 for (int shift = 0; shift < 28; shift += 4) {
253 combine4((twentyEightBits >> shift) & 0xF);
254 }
255 }
256 combine28(stream.low);
257 combine28(stream.mid);
258 combine28(stream.high);
sra1 2015/07/01 17:09:33 A trick which probably runs faster in dart2js is
rmacnak 2015/07/07 23:19:05 The hot path is the use of readUnsigned parsing th
259 return strAddr;
94 } 260 }
95 261
96 List<ObjectVertex> dominatorTreeChildren() { 262 List<ObjectVertex> dominatorTreeChildren() {
97 var N = _graph._N; 263 var N = _graph._N;
98 var doms = _graph._doms; 264 var doms = _graph._doms;
99 265
100 var parentId = _id; 266 var parentId = _id;
101 var domChildren = []; 267 var domChildren = [];
102 268
103 for (var childId = 1; childId <= N; childId++) { 269 for (var childId = 1; childId <= N; childId++) {
(...skipping 17 matching lines...) Expand all
121 287
122 class _SuccessorsIterator implements Iterator<ObjectVertex> { 288 class _SuccessorsIterator implements Iterator<ObjectVertex> {
123 final ObjectGraph _graph; 289 final ObjectGraph _graph;
124 _ReadStream _stream; 290 _ReadStream _stream;
125 291
126 ObjectVertex current; 292 ObjectVertex current;
127 293
128 _SuccessorsIterator(this._graph, int id) { 294 _SuccessorsIterator(this._graph, int id) {
129 _stream = new _ReadStream(this._graph._chunks); 295 _stream = new _ReadStream(this._graph._chunks);
130 _stream.position = _graph._positions[id]; 296 _stream.position = _graph._positions[id];
131 _stream.readUnsigned(); // addr 297 _stream.skipUnsigned(); // addr
132 _stream.readUnsigned(); // shallowSize 298 _stream.skipUnsigned(); // shallowSize
133 var cid = _stream.readUnsigned(); 299 _stream.skipUnsigned(); // cid
134 assert((cid & ~0xFFFF) == 0); // Sanity check: cid's are 16 bit.
135 } 300 }
136 301
137 bool moveNext() { 302 bool moveNext() {
138 while (true) { 303 while (true) {
139 var nextAddr = _stream.readUnsigned(); 304 _stream.readUnsigned();
140 if (nextAddr == 0) return false; 305 if (_stream.isZero) return false;
141 var nextId = _graph._addrToId[nextAddr]; 306 var nextId = _graph._addrToId.get(_stream.high, _stream.mid, _stream.low);
142 if (nextId == null) continue; // Reference to VM isolate's heap. 307 if (nextId == null) continue; // Reference to VM isolate's heap.
143 current = new ObjectVertex._(nextId, _graph); 308 current = new ObjectVertex._(nextId, _graph);
144 return true; 309 return true;
145 } 310 }
146 } 311 }
147 } 312 }
148 313
149 class _VerticesIterable extends IterableBase<ObjectVertex> { 314 class _VerticesIterable extends IterableBase<ObjectVertex> {
150 final ObjectGraph _graph; 315 final ObjectGraph _graph;
151 316
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 return this; 390 return this;
226 } 391 }
227 392
228 final List<ByteData> _chunks; 393 final List<ByteData> _chunks;
229 394
230 int _kObjectAlignment; 395 int _kObjectAlignment;
231 int _N; 396 int _N;
232 int _E; 397 int _E;
233 int _size; 398 int _size;
234 399
235 Map<int, int> _addrToId = new Map<int, int>(); 400 AddressMapper _addrToId;
236 401
237 // Indexed by node id, with id 0 representing invalid/uninitialized. 402 // Indexed by node id, with id 0 representing invalid/uninitialized.
238 Uint32List _positions; // Position of the node in the snapshot. 403 Uint32List _positions; // Position of the node in the snapshot.
239 Uint32List _postOrderOrdinals; // post-order index -> id 404 Uint32List _postOrderOrdinals; // post-order index -> id
240 Uint32List _postOrderIndices; // id -> post-order index 405 Uint32List _postOrderIndices; // id -> post-order index
241 Uint32List _firstPreds; // Offset into preds. 406 Uint32List _firstPreds; // Offset into preds.
242 Uint32List _preds; 407 Uint32List _preds;
243 Uint32List _doms; 408 Uint32List _doms;
244 Uint32List _retainedSizes; 409 Uint32List _retainedSizes;
245 410
246 void _buildPositions() { 411 void _buildPositions() {
247 var N = _N; 412 var N = _N;
248 var addrToId = _addrToId; 413 var addrToId = new AddressMapper(N);
249 414
250 var positions = new Uint32List(N + 1); 415 var positions = new Uint32List(N + 1);
251 416
252 var stream = new _ReadStream(_chunks); 417 var stream = new _ReadStream(_chunks);
253 _kObjectAlignment = stream.readUnsigned(); 418 stream.readUnsigned();
419 _kObjectAlignment = stream.smallValue;
254 420
255 var id = 1; 421 var id = 1;
256 while (stream.pendingBytes > 0) { 422 while (stream.pendingBytes > 0) {
257 positions[id] = stream.position; 423 positions[id] = stream.position;
258 var addr = stream.readUnsigned(); 424 stream.readUnsigned(); // addr
259 stream.readUnsigned(); // shallowSize 425 addrToId.put(stream.high, stream.mid, stream.low, id);
260 stream.readUnsigned(); // cid 426 stream.skipUnsigned(); // shallowSize
261 addrToId[addr] = id; 427 stream.skipUnsigned(); // cid
262 428
263 var succAddr = stream.readUnsigned(); 429 stream.readUnsigned();
264 while (succAddr != 0) { 430 while (!stream.isZero) {
265 succAddr = stream.readUnsigned(); 431 stream.readUnsigned();
266 } 432 }
267 id++; 433 id++;
268 } 434 }
269 assert(id == (N + 1)); 435 assert(id == (N + 1));
270 436
271 var root = addrToId[0]; 437 var root = addrToId.get(0, 0, 0);
272 assert(root == 1); 438 assert(root == 1);
273 439
440 _addrToId = addrToId;
274 _positions = positions; 441 _positions = positions;
275 } 442 }
276 443
277 void _buildPostOrder() { 444 void _buildPostOrder() {
278 var N = _N; 445 var N = _N;
279 var E = 0; 446 var E = 0;
280 var addrToId = _addrToId; 447 var addrToId = _addrToId;
281 var positions = _positions; 448 var positions = _positions;
282 449
283 var postOrderOrdinals = new Uint32List(N); 450 var postOrderOrdinals = new Uint32List(N);
284 var postOrderIndices = new Uint32List(N + 1); 451 var postOrderIndices = new Uint32List(N + 1);
285 var stackNodes = new Uint32List(N); 452 var stackNodes = new Uint32List(N);
286 var stackCurrentEdgePos = new Uint32List(N); 453 var stackCurrentEdgePos = new Uint32List(N);
287 454
288 var visited = new Uint8List(N + 1); 455 var visited = new Uint8List(N + 1);
289 var postOrderIndex = 0; 456 var postOrderIndex = 0;
290 var stackTop = 0; 457 var stackTop = 0;
291 var root = 1; 458 var root = 1;
292 459
293 stackNodes[0] = root; 460 stackNodes[0] = root;
294 461
295 var stream = new _ReadStream(_chunks); 462 var stream = new _ReadStream(_chunks);
296 stream.position = positions[root]; 463 stream.position = positions[root];
297 stream.readUnsigned(); // addr 464 stream.skipUnsigned(); // addr
298 stream.readUnsigned(); // shallowSize 465 stream.skipUnsigned(); // shallowSize
299 stream.readUnsigned(); // cid 466 stream.skipUnsigned(); // cid
300 stackCurrentEdgePos[0] = stream.position; 467 stackCurrentEdgePos[0] = stream.position;
301 visited[root] = 1; 468 visited[root] = 1;
302 469
303 while (stackTop >= 0) { 470 while (stackTop >= 0) {
304 var n = stackNodes[stackTop]; 471 var n = stackNodes[stackTop];
305 var edgePos = stackCurrentEdgePos[stackTop]; 472 var edgePos = stackCurrentEdgePos[stackTop];
306 473
307 stream.position = edgePos; 474 stream.position = edgePos;
308 var childAddr = stream.readUnsigned(); 475 stream.readUnsigned(); // childAddr
309 if (childAddr != 0) { 476 if (!stream.isZero) {
310 stackCurrentEdgePos[stackTop] = stream.position; 477 stackCurrentEdgePos[stackTop] = stream.position;
311 var childId = addrToId[childAddr]; 478 var childId = addrToId.get(stream.high, stream.mid, stream.low);
312 if (childId == null) continue; // Reference to VM isolate's heap. 479 if (childId == null) continue; // Reference to VM isolate's heap.
313 E++; 480 E++;
314 if (visited[childId] == 1) continue; 481 if (visited[childId] == 1) continue;
315 482
316 stackTop++; 483 stackTop++;
317 stackNodes[stackTop] = childId; 484 stackNodes[stackTop] = childId;
318 485
319 stream.position = positions[childId]; 486 stream.position = positions[childId];
320 stream.readUnsigned(); // addr 487 stream.skipUnsigned(); // addr
321 stream.readUnsigned(); // shallowSize 488 stream.skipUnsigned(); // shallowSize
322 stream.readUnsigned(); // cid 489 stream.skipUnsigned(); // cid
323 stackCurrentEdgePos[stackTop] = stream.position; // i.e., first edge 490 stackCurrentEdgePos[stackTop] = stream.position; // i.e., first edge
324 visited[childId] = 1; 491 visited[childId] = 1;
325 } else { 492 } else {
326 // Done with all children. 493 // Done with all children.
327 postOrderIndices[n] = postOrderIndex; 494 postOrderIndices[n] = postOrderIndex;
328 postOrderOrdinals[postOrderIndex++] = n; 495 postOrderOrdinals[postOrderIndex++] = n;
329 stackTop--; 496 stackTop--;
330 } 497 }
331 } 498 }
332 499
(...skipping 16 matching lines...) Expand all
349 // + 1 because 0 is a sentinel 516 // + 1 because 0 is a sentinel
350 // + 1 so the number of predecessors can be found from the difference with 517 // + 1 so the number of predecessors can be found from the difference with
351 // the next node's offset. 518 // the next node's offset.
352 var numPreds = new Uint32List(N + 2); 519 var numPreds = new Uint32List(N + 2);
353 var preds = new Uint32List(E); 520 var preds = new Uint32List(E);
354 521
355 // Count predecessors of each node. 522 // Count predecessors of each node.
356 var stream = new _ReadStream(_chunks); 523 var stream = new _ReadStream(_chunks);
357 for (var i = 1; i <= N; i++) { 524 for (var i = 1; i <= N; i++) {
358 stream.position = positions[i]; 525 stream.position = positions[i];
359 stream.readUnsigned(); // addr 526 stream.skipUnsigned(); // addr
360 stream.readUnsigned(); // shallowSize 527 stream.skipUnsigned(); // shallowSize
361 stream.readUnsigned(); // cid 528 stream.skipUnsigned(); // cid
362 var succAddr = stream.readUnsigned(); 529 stream.readUnsigned(); // succAddr
363 while (succAddr != 0) { 530 while (!stream.isZero) {
364 var succId = addrToId[succAddr]; 531 var succId = addrToId.get(stream.high, stream.mid, stream.low);
365 if (succId != null) { 532 if (succId != null) {
366 numPreds[succId]++; 533 numPreds[succId]++;
367 } else { 534 } else {
368 // Reference to VM isolate's heap. 535 // Reference to VM isolate's heap.
369 } 536 }
370 succAddr = stream.readUnsigned(); 537 stream.readUnsigned(); // succAddr
371 } 538 }
372 } 539 }
373 540
374 // Assign indices into predecessors array. 541 // Assign indices into predecessors array.
375 var firstPreds = numPreds; // Alias. 542 var firstPreds = numPreds; // Alias.
376 var nextPreds = new Uint32List(N + 1); 543 var nextPreds = new Uint32List(N + 1);
377 var predIndex = 0; 544 var predIndex = 0;
378 for (var i = 1; i <= N; i++) { 545 for (var i = 1; i <= N; i++) {
379 var thisPredIndex = predIndex; 546 var thisPredIndex = predIndex;
380 predIndex += numPreds[i]; 547 predIndex += numPreds[i];
381 firstPreds[i] = thisPredIndex; 548 firstPreds[i] = thisPredIndex;
382 nextPreds[i] = thisPredIndex; 549 nextPreds[i] = thisPredIndex;
383 } 550 }
384 assert(predIndex == E); 551 assert(predIndex == E);
385 firstPreds[N + 1] = E; // Extra entry for cheap boundary detection. 552 firstPreds[N + 1] = E; // Extra entry for cheap boundary detection.
386 553
387 // Fill predecessors array. 554 // Fill predecessors array.
388 for (var i = 1; i <= N; i++) { 555 for (var i = 1; i <= N; i++) {
389 stream.position = positions[i]; 556 stream.position = positions[i];
390 stream.readUnsigned(); // addr 557 stream.skipUnsigned(); // addr
391 stream.readUnsigned(); // shallowSize 558 stream.skipUnsigned(); // shallowSize
392 stream.readUnsigned(); // cid 559 stream.skipUnsigned(); // cid
393 var succAddr = stream.readUnsigned(); 560 stream.readUnsigned(); // succAddr
394 while (succAddr != 0) { 561 while (!stream.isZero) {
395 var succId = addrToId[succAddr]; 562 var succId = addrToId.get(stream.high, stream.mid, stream.low);
396 if (succId != null) { 563 if (succId != null) {
397 var predIndex = nextPreds[succId]++; 564 var predIndex = nextPreds[succId]++;
398 preds[predIndex] = i; 565 preds[predIndex] = i;
399 } else { 566 } else {
400 // Reference to VM isolate's heap. 567 // Reference to VM isolate's heap.
401 } 568 }
402 succAddr = stream.readUnsigned(); 569 stream.readUnsigned(); // succAddr
403 } 570 }
404 } 571 }
405 572
406 _firstPreds = firstPreds; 573 _firstPreds = firstPreds;
407 _preds = preds; 574 _preds = preds;
408 } 575 }
409 576
410 // "A Simple, Fast Dominance Algorithm" 577 // "A Simple, Fast Dominance Algorithm"
411 // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy 578 // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
412 void _buildDominators() { 579 void _buildDominators() {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 var size = 0; 658 var size = 0;
492 var positions = _positions; 659 var positions = _positions;
493 var postOrderOrdinals = _postOrderOrdinals; 660 var postOrderOrdinals = _postOrderOrdinals;
494 var doms = _doms; 661 var doms = _doms;
495 var retainedSizes = new Uint32List(N + 1); 662 var retainedSizes = new Uint32List(N + 1);
496 663
497 // Start with retained size as shallow size. 664 // Start with retained size as shallow size.
498 var reader = new _ReadStream(_chunks); 665 var reader = new _ReadStream(_chunks);
499 for (var i = 1; i <= N; i++) { 666 for (var i = 1; i <= N; i++) {
500 reader.position = positions[i]; 667 reader.position = positions[i];
501 reader.readUnsigned(); // addr 668 reader.skipUnsigned(); // addr
502 var shallowSize = reader.readUnsigned(); 669 reader.readUnsigned(); // shallowSize
670 var shallowSize = reader.smallValue;
503 retainedSizes[i] = shallowSize; 671 retainedSizes[i] = shallowSize;
504 size += shallowSize; 672 size += shallowSize;
505 } 673 }
506 674
507 // In post order (bottom up), add retained size to dominator's retained 675 // In post order (bottom up), add retained size to dominator's retained
508 // size, skipping root. 676 // size, skipping root.
509 for (var o = 0; o < (N - 1); o++) { 677 for (var o = 0; o < (N - 1); o++) {
510 var i = postOrderOrdinals[o]; 678 var i = postOrderOrdinals[o];
511 assert(i != 1); 679 assert(i != 1);
512 retainedSizes[doms[i]] += retainedSizes[i]; 680 retainedSizes[doms[i]] += retainedSizes[i];
513 } 681 }
514 682
515 _retainedSizes = retainedSizes; 683 _retainedSizes = retainedSizes;
516 _size = size; 684 _size = size;
517 } 685 }
518 } 686 }
OLDNEW
« no previous file with comments | « no previous file | runtime/observatory/lib/src/elements/heap_snapshot.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698