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

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

Issue 1278653004: Unpack the heap snapshot from a representation of var ints and addresses to a representation of fix… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | 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
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 109
110 int get clampedUint32 { 110 int get clampedUint32 {
111 if (high != 0 || mid > 0xF) { 111 if (high != 0 || mid > 0xF) {
112 return 0xFFFFFFFF; 112 return 0xFFFFFFFF;
113 } else { 113 } else {
114 // Not shift as JS shifts are signed 32-bit. 114 // Not shift as JS shifts are signed 32-bit.
115 return mid * 0x10000000 + low; 115 return mid * 0x10000000 + low;
116 } 116 }
117 } 117 }
118 118
119 int get highUint32 {
120 return high * (1 << 24) + (mid >> 4);
121 }
122
123 int get lowUint32 {
124 return (mid & 0xF) * (1 << 28) + low;
125 }
126
119 bool get isZero { 127 bool get isZero {
120 return (high == 0) && (mid == 0) && (low == 0); 128 return (high == 0) && (mid == 0) && (low == 0);
121 } 129 }
122 130
123 void readUnsigned() { 131 void readUnsigned() {
124 low = 0; 132 low = 0;
125 mid = 0; 133 mid = 0;
126 high = 0; 134 high = 0;
127 135
128 // Low 28 bits. 136 // Low 28 bits.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 ObjectVertex._(this._id, this._graph); 225 ObjectVertex._(this._id, this._graph);
218 226
219 bool get isRoot => _id == 1; 227 bool get isRoot => _id == 1;
220 228
221 bool operator ==(other) => _id == other._id && _graph == other._graph; 229 bool operator ==(other) => _id == other._id && _graph == other._graph;
222 int get hashCode => _id; 230 int get hashCode => _id;
223 231
224 int get retainedSize => _graph._retainedSizes[_id]; 232 int get retainedSize => _graph._retainedSizes[_id];
225 ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph); 233 ObjectVertex get dominator => new ObjectVertex._(_graph._doms[_id], _graph);
226 234
227 int get shallowSize { 235 int get shallowSize => _graph._shallowSizes[_id];
228 var stream = new ReadStream(_graph._chunks); 236 int get vmCid => _graph._cids[_id];
229 stream.position = _graph._positions[_id];
230 stream.skipUnsigned(); // addr
231 stream.readUnsigned(); // shallowSize
232 return stream.clampedUint32;
233 }
234
235 int get vmCid {
236 var stream = new ReadStream(_graph._chunks);
237 stream.position = _graph._positions[_id];
238 stream.skipUnsigned(); // addr
239 stream.skipUnsigned(); // shallowSize
240 stream.readUnsigned(); // cid
241 return stream.clampedUint32;
242 }
243 237
244 get successors => new _SuccessorsIterable(_graph, _id); 238 get successors => new _SuccessorsIterable(_graph, _id);
245 239
246 String get address { 240 String get address {
247 // Note that everywhere else in this file, "address" really means an address 241 // Note that everywhere else in this file, "address" really means an address
248 // scaled down by kObjectAlignment. They were scaled down so they would fit 242 // scaled down by kObjectAlignment. They were scaled down so they would fit
249 // into Smis on the client. 243 // into Smis on the client.
250 var stream = new ReadStream(_graph._chunks);
251 stream.position = _graph._positions[_id];
252 stream.readUnsigned();
253 244
254 // Complicated way to do (high:mid:low * _kObjectAlignment).toHexString() 245 var high32 = _graph._addressesHigh[_id];
246 var low32 = _graph._addressesLow[_id];
247
248 // Complicated way to do (high:low * _kObjectAlignment).toHexString()
255 // without intermediate values exceeding int32. 249 // without intermediate values exceeding int32.
256 250
257 var strAddr = ""; 251 var strAddr = "";
258 var carry = 0; 252 var carry = 0;
259 combine4(nibble) { 253 combine4(nibble) {
260 nibble = nibble * _graph._kObjectAlignment + carry; 254 nibble = nibble * _graph._kObjectAlignment + carry;
261 carry = nibble >> 4; 255 carry = nibble >> 4;
262 nibble = nibble & 0xF; 256 nibble = nibble & 0xF;
263 strAddr = nibble.toRadixString(16) + strAddr; 257 strAddr = nibble.toRadixString(16) + strAddr;
264 } 258 }
265 combine28(twentyEightBits) { 259 combine32(thirtyTwoBits) {
266 for (int shift = 0; shift < 28; shift += 4) { 260 for (int shift = 0; shift < 32; shift += 4) {
267 combine4((twentyEightBits >> shift) & 0xF); 261 combine4((thirtyTwoBits >> shift) & 0xF);
268 } 262 }
269 } 263 }
270 combine28(stream.low); 264 combine32(low32);
271 combine28(stream.mid); 265 combine32(high32);
272 combine28(stream.high);
273 return strAddr; 266 return strAddr;
274 } 267 }
275 268
276 List<ObjectVertex> dominatorTreeChildren() { 269 List<ObjectVertex> dominatorTreeChildren() {
277 var N = _graph._N; 270 var N = _graph._N;
278 var doms = _graph._doms; 271 var doms = _graph._doms;
279 272
280 var parentId = _id; 273 var parentId = _id;
281 var domChildren = []; 274 var domChildren = [];
282 275
(...skipping 11 matching lines...) Expand all
294 final ObjectGraph _graph; 287 final ObjectGraph _graph;
295 final int _id; 288 final int _id;
296 289
297 _SuccessorsIterable(this._graph, this._id); 290 _SuccessorsIterable(this._graph, this._id);
298 291
299 Iterator<ObjectVertex> get iterator => new _SuccessorsIterator(_graph, _id); 292 Iterator<ObjectVertex> get iterator => new _SuccessorsIterator(_graph, _id);
300 } 293 }
301 294
302 class _SuccessorsIterator implements Iterator<ObjectVertex> { 295 class _SuccessorsIterator implements Iterator<ObjectVertex> {
303 final ObjectGraph _graph; 296 final ObjectGraph _graph;
304 ReadStream _stream; 297 int _nextSuccIndex;
298 int _limitSuccIndex;
305 299
306 ObjectVertex current; 300 ObjectVertex current;
307 301
308 _SuccessorsIterator(this._graph, int id) { 302 _SuccessorsIterator(this._graph, int id) {
309 _stream = new ReadStream(this._graph._chunks); 303 _nextSuccIndex = _graph._firstSuccs[id];
310 _stream.position = _graph._positions[id]; 304 _limitSuccIndex = _graph._firstSuccs[id + 1];
311 _stream.skipUnsigned(); // addr
312 _stream.skipUnsigned(); // shallowSize
313 _stream.skipUnsigned(); // cid
314 } 305 }
315 306
316 bool moveNext() { 307 bool moveNext() {
317 while (true) { 308 if (_nextSuccIndex < _limitSuccIndex) {
318 _stream.readUnsigned(); 309 var succId = _graph._succs[_nextSuccIndex++];
319 if (_stream.isZero) return false; 310 current = new ObjectVertex._(succId, _graph);
320 var nextId = _graph._addrToId.get(_stream.high, _stream.mid, _stream.low);
321 if (nextId == null) continue; // Reference to VM isolate's heap.
322 current = new ObjectVertex._(nextId, _graph);
323 return true; 311 return true;
324 } 312 }
313 return false;
325 } 314 }
326 } 315 }
327 316
328 class _VerticesIterable extends IterableBase<ObjectVertex> { 317 class _VerticesIterable extends IterableBase<ObjectVertex> {
329 final ObjectGraph _graph; 318 final ObjectGraph _graph;
330 319
331 _VerticesIterable(this._graph); 320 _VerticesIterable(this._graph);
332 321
333 Iterator<ObjectVertex> get iterator => new _VerticesIterator(_graph); 322 Iterator<ObjectVertex> get iterator => new _VerticesIterator(_graph);
334 } 323 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 if (limit != null) { 361 if (limit != null) {
373 result = result.take(limit); 362 result = result.take(limit);
374 } 363 }
375 return result; 364 return result;
376 } 365 }
377 366
378 Future process(statusReporter) async { 367 Future process(statusReporter) async {
379 // We build futures here instead of marking the steps as async to avoid the 368 // We build futures here instead of marking the steps as async to avoid the
380 // heavy lifting being inside a transformed method. 369 // heavy lifting being inside a transformed method.
381 370
382 statusReporter.add("Finding node positions..."); 371 statusReporter.add("Remapping $_N objects...");
383 await new Future(() => _buildPositions()); 372 await new Future(() => _remapNodes());
373
374 statusReporter.add("Remapping $_E references...");
375 await new Future(() => _remapEdges());
376
377 _addrToId = null;
378 _chunks = null;
384 379
385 statusReporter.add("Finding post order..."); 380 statusReporter.add("Finding post order...");
386 await new Future(() => _buildPostOrder()); 381 await new Future(() => _buildPostOrder());
387 382
388 statusReporter.add("Finding predecessors..."); 383 statusReporter.add("Finding predecessors...");
389 await new Future(() => _buildPredecessors()); 384 await new Future(() => _buildPredecessors());
390 385
391 statusReporter.add("Finding dominators..."); 386 statusReporter.add("Finding dominators...");
392 await new Future(() => _buildDominators()); 387 await new Future(() => _buildDominators());
393 388
394 _firstPreds = null; 389 _firstPreds = null;
395 _preds = null; 390 _preds = null;
396 _postOrderIndices = null; 391 _postOrderIndices = null;
397 392
398 statusReporter.add("Finding retained sizes..."); 393 statusReporter.add("Finding retained sizes...");
399 await new Future(() => _calculateRetainedSizes()); 394 await new Future(() => _calculateRetainedSizes());
400 395
401 _postOrderOrdinals = null; 396 _postOrderOrdinals = null;
402 397
403 statusReporter.add("Loaded"); 398 statusReporter.add("Loaded");
404 return this; 399 return this;
405 } 400 }
406 401
407 final List<ByteData> _chunks; 402 List<ByteData> _chunks;
408 403
409 int _kObjectAlignment; 404 int _kObjectAlignment;
410 int _N; 405 int _N;
411 int _E; 406 int _E;
412 int _size; 407 int _size;
413 408
409 // Indexed by node id, with id 0 representing invalid/uninitialized.
410 // From snapshot.
411 Uint16List _cids;
412 Uint32List _shallowSizes;
413 Uint32List _firstSuccs;
414 Uint32List _succs;
415 Uint32List _addressesLow; // No Uint64List in Javascript.
416 Uint32List _addressesHigh;
417
418 // Intermediates.
414 AddressMapper _addrToId; 419 AddressMapper _addrToId;
415
416 // Indexed by node id, with id 0 representing invalid/uninitialized.
417 Uint32List _positions; // Position of the node in the snapshot.
418 Uint32List _postOrderOrdinals; // post-order index -> id 420 Uint32List _postOrderOrdinals; // post-order index -> id
419 Uint32List _postOrderIndices; // id -> post-order index 421 Uint32List _postOrderIndices; // id -> post-order index
420 Uint32List _firstPreds; // Offset into preds. 422 Uint32List _firstPreds; // Offset into preds.
421 Uint32List _preds; 423 Uint32List _preds;
424
425 // Outputs.
422 Uint32List _doms; 426 Uint32List _doms;
423 Uint32List _retainedSizes; 427 Uint32List _retainedSizes;
424 428
425 void _buildPositions() { 429 void _remapNodes() {
426 var N = _N; 430 var N = _N;
431 var E = 0;
427 var addrToId = new AddressMapper(N); 432 var addrToId = new AddressMapper(N);
428 433
429 var positions = new Uint32List(N + 1); 434 var addressesHigh = new Uint32List(N + 1);
435 var addressesLow = new Uint32List(N + 1);
436 var shallowSizes = new Uint32List(N + 1);
437 var cids = new Uint16List(N + 1);
430 438
431 var stream = new ReadStream(_chunks); 439 var stream = new ReadStream(_chunks);
432 stream.readUnsigned(); 440 stream.readUnsigned();
433 _kObjectAlignment = stream.clampedUint32; 441 _kObjectAlignment = stream.clampedUint32;
434 442
435 var id = 1; 443 var id = 1;
436 while (stream.pendingBytes > 0) { 444 while (stream.pendingBytes > 0) {
437 positions[id] = stream.position;
438 stream.readUnsigned(); // addr 445 stream.readUnsigned(); // addr
439 addrToId.put(stream.high, stream.mid, stream.low, id); 446 addrToId.put(stream.high, stream.mid, stream.low, id);
440 stream.skipUnsigned(); // shallowSize 447 addressesHigh[id] = stream.highUint32;
441 stream.skipUnsigned(); // cid 448 addressesLow[id] = stream.lowUint32;
449 stream.readUnsigned(); // shallowSize
450 shallowSizes[id] = stream.clampedUint32;
451 stream.readUnsigned(); // cid
452 cids[id] = stream.clampedUint32;
442 453
443 stream.readUnsigned(); 454 stream.readUnsigned();
444 while (!stream.isZero) { 455 while (!stream.isZero) {
456 E++;
445 stream.readUnsigned(); 457 stream.readUnsigned();
446 } 458 }
447 id++; 459 id++;
448 } 460 }
449 assert(id == (N + 1)); 461 assert(id == (N + 1));
450 462
451 var root = addrToId.get(0, 0, 0); 463 var root = addrToId.get(0, 0, 0);
452 assert(root == 1); 464 assert(root == 1);
453 465
466 _E = E;
454 _addrToId = addrToId; 467 _addrToId = addrToId;
455 _positions = positions; 468 _addressesLow = addressesLow;
469 _addressesHigh = addressesHigh;
470 _shallowSizes = shallowSizes;
471 _cids = cids;
472 }
473
474 void _remapEdges() {
475 var N = _N;
476 var E = _E;
477 var addrToId = _addrToId;
478
479 var firstSuccs = new Uint32List(N + 2);
480 var succs = new Uint32List(E);
481
482 var stream = new ReadStream(_chunks);
483 stream.skipUnsigned(); // addr alignment
484
485 var id = 1, edge = 0;
486 while (stream.pendingBytes > 0) {
487 stream.skipUnsigned(); // addr
488 stream.skipUnsigned(); // shallowSize
489 stream.skipUnsigned(); // cid
490
491 firstSuccs[id] = edge;
492
493 stream.readUnsigned();
494 while (!stream.isZero) {
495 var childId = addrToId.get(stream.high, stream.mid, stream.low);
496 if (childId != null) {
497 succs[edge] = childId;
498 edge++;
499 } else {
500 // Reference into VM isolate's heap.
501 }
502 stream.readUnsigned();
503 }
504 id++;
505 }
506 firstSuccs[id] = edge; // Extra entry for cheap boundary detection.
507
508 assert(id == N + 1);
509 assert(edge <= E); // edge is smaller because E was computed before we knew
510 // if references pointed into the VM isolate
511
512 _E = edge;
513 _firstSuccs = firstSuccs;
514 _succs = succs;
456 } 515 }
457 516
458 void _buildPostOrder() { 517 void _buildPostOrder() {
459 var N = _N; 518 var N = _N;
460 var E = 0; 519 var E = _E;
461 var addrToId = _addrToId; 520 var firstSuccs = _firstSuccs;
462 var positions = _positions; 521 var succs = _succs;
463 522
464 var postOrderOrdinals = new Uint32List(N); 523 var postOrderOrdinals = new Uint32List(N);
465 var postOrderIndices = new Uint32List(N + 1); 524 var postOrderIndices = new Uint32List(N + 1);
466 var stackNodes = new Uint32List(N); 525 var stackNodes = new Uint32List(N);
467 var stackCurrentEdgePos = new Uint32List(N); 526 var stackCurrentEdgePos = new Uint32List(N);
468 527
469 var visited = new Uint8List(N + 1); 528 var visited = new Uint8List(N + 1);
470 var postOrderIndex = 0; 529 var postOrderIndex = 0;
471 var stackTop = 0; 530 var stackTop = 0;
472 var root = 1; 531 var root = 1;
473 532
474 stackNodes[0] = root; 533 stackNodes[0] = root;
475 534 stackCurrentEdgePos[0] = firstSuccs[root];
476 var stream = new ReadStream(_chunks);
477 stream.position = positions[root];
478 stream.skipUnsigned(); // addr
479 stream.skipUnsigned(); // shallowSize
480 stream.skipUnsigned(); // cid
481 stackCurrentEdgePos[0] = stream.position;
482 visited[root] = 1; 535 visited[root] = 1;
483 536
484 while (stackTop >= 0) { 537 while (stackTop >= 0) {
485 var n = stackNodes[stackTop]; 538 var n = stackNodes[stackTop];
486 var edgePos = stackCurrentEdgePos[stackTop]; 539 var edgePos = stackCurrentEdgePos[stackTop];
487 540
488 stream.position = edgePos; 541 if (edgePos < firstSuccs[n + 1]) {
489 stream.readUnsigned(); // childAddr 542 var childId = succs[edgePos];
490 if (!stream.isZero) { 543 edgePos++;
491 stackCurrentEdgePos[stackTop] = stream.position; 544 stackCurrentEdgePos[stackTop] = edgePos;
492 var childId = addrToId.get(stream.high, stream.mid, stream.low);
493 if (childId == null) continue; // Reference to VM isolate's heap.
494 E++;
495 if (visited[childId] == 1) continue; 545 if (visited[childId] == 1) continue;
496 546
547 // Push child.
497 stackTop++; 548 stackTop++;
498 stackNodes[stackTop] = childId; 549 stackNodes[stackTop] = childId;
499 550 edgePos = firstSuccs[childId];
500 stream.position = positions[childId]; 551 stackCurrentEdgePos[stackTop] = edgePos;
501 stream.skipUnsigned(); // addr
502 stream.skipUnsigned(); // shallowSize
503 stream.skipUnsigned(); // cid
504 stackCurrentEdgePos[stackTop] = stream.position; // i.e., first edge
505 visited[childId] = 1; 552 visited[childId] = 1;
506 } else { 553 } else {
507 // Done with all children. 554 // Done with all children.
508 postOrderIndices[n] = postOrderIndex; 555 postOrderIndices[n] = postOrderIndex;
509 postOrderOrdinals[postOrderIndex++] = n; 556 postOrderOrdinals[postOrderIndex++] = n;
510 stackTop--; 557 stackTop--;
511 } 558 }
512 } 559 }
513 560
514 assert(postOrderIndex == N); 561 assert(postOrderIndex == N);
515 assert(postOrderOrdinals[N - 1] == root); 562 assert(postOrderOrdinals[N - 1] == root);
516 563
517 _postOrderOrdinals = postOrderOrdinals; 564 _postOrderOrdinals = postOrderOrdinals;
518 _postOrderIndices = postOrderIndices; 565 _postOrderIndices = postOrderIndices;
519 _E = E; 566 _E = E;
520 } 567 }
521 568
522 void _buildPredecessors() { 569 void _buildPredecessors() {
523 var N = _N; 570 var N = _N;
524 var E = _E; 571 var E = _E;
525 var addrToId = _addrToId; 572 var firstSuccs = _firstSuccs;
526 var positions = _positions; 573 var succs = _succs;
527 574
528 // This is first filled with the predecessor counts, then reused to hold the 575 // This is first filled with the predecessor counts, then reused to hold the
529 // offset to the first predecessor (see alias below). 576 // offset to the first predecessor (see alias below).
530 // + 1 because 0 is a sentinel 577 // + 1 because 0 is a sentinel
531 // + 1 so the number of predecessors can be found from the difference with 578 // + 1 so the number of predecessors can be found from the difference with
532 // the next node's offset. 579 // the next node's offset.
533 var numPreds = new Uint32List(N + 2); 580 var numPreds = new Uint32List(N + 2);
534 var preds = new Uint32List(E); 581 var preds = new Uint32List(E);
535 582
536 // Count predecessors of each node. 583 // Count predecessors of each node.
537 var stream = new ReadStream(_chunks); 584 for (var succIndex = 0; succIndex < E; succIndex++) {
538 for (var i = 1; i <= N; i++) { 585 var succId = succs[succIndex];
539 stream.position = positions[i]; 586 numPreds[succId]++;
540 stream.skipUnsigned(); // addr
541 stream.skipUnsigned(); // shallowSize
542 stream.skipUnsigned(); // cid
543 stream.readUnsigned(); // succAddr
544 while (!stream.isZero) {
545 var succId = addrToId.get(stream.high, stream.mid, stream.low);
546 if (succId != null) {
547 numPreds[succId]++;
548 } else {
549 // Reference to VM isolate's heap.
550 }
551 stream.readUnsigned(); // succAddr
552 }
553 } 587 }
554 588
555 // Assign indices into predecessors array. 589 // Assign indices into predecessors array.
556 var firstPreds = numPreds; // Alias. 590 var firstPreds = numPreds; // Alias.
557 var nextPreds = new Uint32List(N + 1); 591 var nextPreds = new Uint32List(N + 1);
558 var predIndex = 0; 592 var predIndex = 0;
559 for (var i = 1; i <= N; i++) { 593 for (var i = 1; i <= N; i++) {
560 var thisPredIndex = predIndex; 594 var thisPredIndex = predIndex;
561 predIndex += numPreds[i]; 595 predIndex += numPreds[i];
562 firstPreds[i] = thisPredIndex; 596 firstPreds[i] = thisPredIndex;
563 nextPreds[i] = thisPredIndex; 597 nextPreds[i] = thisPredIndex;
564 } 598 }
565 assert(predIndex == E); 599 assert(predIndex == E);
566 firstPreds[N + 1] = E; // Extra entry for cheap boundary detection. 600 firstPreds[N + 1] = E; // Extra entry for cheap boundary detection.
567 601
568 // Fill predecessors array. 602 // Fill predecessors array.
569 for (var i = 1; i <= N; i++) { 603 for (var i = 1; i <= N; i++) {
570 stream.position = positions[i]; 604 var startSuccIndex = firstSuccs[i];
571 stream.skipUnsigned(); // addr 605 var limitSuccIndex = firstSuccs[i + 1];
572 stream.skipUnsigned(); // shallowSize 606 for (var succIndex = startSuccIndex;
573 stream.skipUnsigned(); // cid 607 succIndex < limitSuccIndex;
574 stream.readUnsigned(); // succAddr 608 succIndex++) {
575 while (!stream.isZero) { 609 var succId = succs[succIndex];
576 var succId = addrToId.get(stream.high, stream.mid, stream.low); 610 var predIndex = nextPreds[succId]++;
577 if (succId != null) { 611 preds[predIndex] = i;
578 var predIndex = nextPreds[succId]++;
579 preds[predIndex] = i;
580 } else {
581 // Reference to VM isolate's heap.
582 }
583 stream.readUnsigned(); // succAddr
584 } 612 }
585 } 613 }
586 614
587 _firstPreds = firstPreds; 615 _firstPreds = firstPreds;
588 _preds = preds; 616 _preds = preds;
589 } 617 }
590 618
591 // "A Simple, Fast Dominance Algorithm" 619 // "A Simple, Fast Dominance Algorithm"
592 // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy 620 // Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
593 void _buildDominators() { 621 void _buildDominators() {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 695
668 domById[root] = 0; 696 domById[root] = 0;
669 697
670 _doms = domById; 698 _doms = domById;
671 } 699 }
672 700
673 void _calculateRetainedSizes() { 701 void _calculateRetainedSizes() {
674 var N = _N; 702 var N = _N;
675 703
676 var size = 0; 704 var size = 0;
677 var positions = _positions; 705 var shallowSizes = _shallowSizes;
678 var postOrderOrdinals = _postOrderOrdinals; 706 var postOrderOrdinals = _postOrderOrdinals;
679 var doms = _doms; 707 var doms = _doms;
680 var retainedSizes = new Uint32List(N + 1); 708
709 // Sum shallow sizes.
710 for (var i = 1; i < N; i++) {
711 size += shallowSizes[i];
712 }
681 713
682 // Start with retained size as shallow size. 714 // Start with retained size as shallow size.
683 var reader = new ReadStream(_chunks); 715 var retainedSizes = new Uint32List.fromList(shallowSizes);
684 for (var i = 1; i <= N; i++) {
685 reader.position = positions[i];
686 reader.skipUnsigned(); // addr
687 reader.readUnsigned(); // shallowSize
688 var shallowSize = reader.clampedUint32;
689 retainedSizes[i] = shallowSize;
690 size += shallowSize;
691 }
692 716
693 // In post order (bottom up), add retained size to dominator's retained 717 // In post order (bottom up), add retained size to dominator's retained
694 // size, skipping root. 718 // size, skipping root.
695 for (var o = 0; o < (N - 1); o++) { 719 for (var o = 0; o < (N - 1); o++) {
696 var i = postOrderOrdinals[o]; 720 var i = postOrderOrdinals[o];
697 assert(i != 1); 721 assert(i != 1);
698 retainedSizes[doms[i]] += retainedSizes[i]; 722 retainedSizes[doms[i]] += retainedSizes[i];
699 } 723 }
700 724
701 _retainedSizes = retainedSizes; 725 _retainedSizes = retainedSizes;
702 _size = size; 726 _size = size;
703 } 727 }
704 } 728 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698