Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include "vm/scavenger.h" | 5 #include "vm/scavenger.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 } | 397 } |
| 398 delete pending; | 398 delete pending; |
| 399 pending = next; | 399 pending = next; |
| 400 } | 400 } |
| 401 heap_->RecordData(kStoreBufferEntries, entries); | 401 heap_->RecordData(kStoreBufferEntries, entries); |
| 402 // Done iterating through old objects remembered in the store buffers. | 402 // Done iterating through old objects remembered in the store buffers. |
| 403 visitor->VisitingOldObject(NULL); | 403 visitor->VisitingOldObject(NULL); |
| 404 } | 404 } |
| 405 | 405 |
| 406 | 406 |
| 407 void Scavenger::IterateObjectIdTable(Isolate* isolate, | |
| 408 ScavengerVisitor* visitor) { | |
| 409 RawObject** table = heap_->get_object_id_ring_table(); | |
| 410 const intptr_t table_size = heap_->get_object_id_ring_table_size(); | |
| 411 if ((table == NULL) || (table_size <= 0)) { | |
| 412 return; | |
| 413 } | |
| 414 visitor->VisitPointers(&table[0], &table[table_size]); | |
| 415 } | |
| 416 | |
| 417 | |
| 407 void Scavenger::IterateRoots(Isolate* isolate, | 418 void Scavenger::IterateRoots(Isolate* isolate, |
| 408 ScavengerVisitor* visitor, | 419 ScavengerVisitor* visitor, |
| 409 bool visit_prologue_weak_persistent_handles) { | 420 bool visit_prologue_weak_persistent_handles) { |
| 410 int64_t start = OS::GetCurrentTimeMicros(); | 421 int64_t start = OS::GetCurrentTimeMicros(); |
| 411 isolate->VisitObjectPointers(visitor, | 422 isolate->VisitObjectPointers(visitor, |
| 412 visit_prologue_weak_persistent_handles, | 423 visit_prologue_weak_persistent_handles, |
| 413 StackFrameIterator::kDontValidateFrames); | 424 StackFrameIterator::kDontValidateFrames); |
| 414 int64_t middle = OS::GetCurrentTimeMicros(); | 425 int64_t middle = OS::GetCurrentTimeMicros(); |
| 415 IterateStoreBuffers(isolate, visitor); | 426 IterateStoreBuffers(isolate, visitor); |
| 427 IterateObjectIdTable(isolate, visitor); | |
| 416 int64_t end = OS::GetCurrentTimeMicros(); | 428 int64_t end = OS::GetCurrentTimeMicros(); |
| 417 heap_->RecordTime(kVisitIsolateRoots, middle - start); | 429 heap_->RecordTime(kVisitIsolateRoots, middle - start); |
| 418 heap_->RecordTime(kIterateStoreBuffers, end - middle); | 430 heap_->RecordTime(kIterateStoreBuffers, end - middle); |
| 419 } | 431 } |
| 420 | 432 |
| 421 | 433 |
| 422 bool Scavenger::IsUnreachable(RawObject** p) { | 434 bool Scavenger::IsUnreachable(RawObject** p) { |
| 423 RawObject* raw_obj = *p; | 435 RawObject* raw_obj = *p; |
| 424 if (!raw_obj->IsHeapObject()) { | 436 if (!raw_obj->IsHeapObject()) { |
| 425 return false; | 437 return false; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 } | 595 } |
| 584 } | 596 } |
| 585 } | 597 } |
| 586 // Remove the old table as it has been replaced with the newly allocated | 598 // Remove the old table as it has been replaced with the newly allocated |
| 587 // table above. | 599 // table above. |
| 588 delete table; | 600 delete table; |
| 589 } | 601 } |
| 590 } | 602 } |
| 591 | 603 |
| 592 | 604 |
| 605 void Scavenger::ProcessObjectIdTable() { | |
| 606 RawObject** table = heap_->get_object_id_ring_table(); | |
|
Ivan Posva
2013/07/10 01:10:13
It would be better if we used a pointer visitor he
Cutch
2013/07/10 17:23:10
All accesses to the ring table via the scavenger a
| |
| 607 const intptr_t table_size = heap_->get_object_id_ring_table_size(); | |
| 608 if ((table == NULL) || (table_size <= 0)) { | |
| 609 return; | |
| 610 } | |
| 611 for (intptr_t i = 0; i < table_size; i++) { | |
| 612 RawObject* raw_obj = table[i]; | |
| 613 ASSERT(raw_obj->IsHeapObject()); | |
| 614 if (raw_obj->IsOldObject()) { | |
| 615 // SKip old objects. | |
| 616 continue; | |
| 617 } | |
| 618 uword raw_addr = RawObject::ToAddr(raw_obj); | |
| 619 uword header = *reinterpret_cast<uword*>(raw_addr); | |
| 620 if (IsForwarding(header)) { | |
| 621 // The object has survived. Update its address in the table. | |
| 622 uword new_addr = ForwardedAddr(header); | |
| 623 raw_obj = RawObject::FromAddr(new_addr); | |
| 624 table[i] = raw_obj; | |
| 625 } | |
| 626 } | |
| 627 } | |
| 628 | |
| 629 | |
| 593 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 630 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 594 uword cur = FirstObjectStart(); | 631 uword cur = FirstObjectStart(); |
| 595 while (cur < top_) { | 632 while (cur < top_) { |
| 596 RawObject* raw_obj = RawObject::FromAddr(cur); | 633 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 597 cur += raw_obj->VisitPointers(visitor); | 634 cur += raw_obj->VisitPointers(visitor); |
| 598 } | 635 } |
| 599 } | 636 } |
| 600 | 637 |
| 601 | 638 |
| 602 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { | 639 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 Prologue(isolate, invoke_api_callbacks); | 672 Prologue(isolate, invoke_api_callbacks); |
| 636 IterateRoots(isolate, &visitor, !invoke_api_callbacks); | 673 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
| 637 int64_t start = OS::GetCurrentTimeMicros(); | 674 int64_t start = OS::GetCurrentTimeMicros(); |
| 638 ProcessToSpace(&visitor); | 675 ProcessToSpace(&visitor); |
| 639 int64_t middle = OS::GetCurrentTimeMicros(); | 676 int64_t middle = OS::GetCurrentTimeMicros(); |
| 640 IterateWeakReferences(isolate, &visitor); | 677 IterateWeakReferences(isolate, &visitor); |
| 641 ScavengerWeakVisitor weak_visitor(this); | 678 ScavengerWeakVisitor weak_visitor(this); |
| 642 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); | 679 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| 643 visitor.Finalize(); | 680 visitor.Finalize(); |
| 644 ProcessWeakTables(); | 681 ProcessWeakTables(); |
| 682 ProcessObjectIdTable(); | |
| 645 int64_t end = OS::GetCurrentTimeMicros(); | 683 int64_t end = OS::GetCurrentTimeMicros(); |
| 646 heap_->RecordTime(kProcessToSpace, middle - start); | 684 heap_->RecordTime(kProcessToSpace, middle - start); |
| 647 heap_->RecordTime(kIterateWeaks, end - middle); | 685 heap_->RecordTime(kIterateWeaks, end - middle); |
| 648 Epilogue(isolate, invoke_api_callbacks); | 686 Epilogue(isolate, invoke_api_callbacks); |
| 649 | 687 |
| 650 if (FLAG_verify_after_gc) { | 688 if (FLAG_verify_after_gc) { |
| 651 OS::PrintErr("Verifying after Scavenge..."); | 689 OS::PrintErr("Verifying after Scavenge..."); |
| 652 heap_->Verify(); | 690 heap_->Verify(); |
| 653 OS::PrintErr(" done.\n"); | 691 OS::PrintErr(" done.\n"); |
| 654 } | 692 } |
| 655 | 693 |
| 656 // Done scavenging. Reset the marker. | 694 // Done scavenging. Reset the marker. |
| 657 ASSERT(scavenging_); | 695 ASSERT(scavenging_); |
| 658 scavenging_ = false; | 696 scavenging_ = false; |
| 659 } | 697 } |
| 660 | 698 |
| 661 | 699 |
| 662 void Scavenger::WriteProtect(bool read_only) { | 700 void Scavenger::WriteProtect(bool read_only) { |
| 663 space_->Protect( | 701 space_->Protect( |
| 664 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 702 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
| 665 } | 703 } |
| 666 | 704 |
| 667 | 705 |
| 668 } // namespace dart | 706 } // namespace dart |
| OLD | NEW |