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

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