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 |
| 11 #include "vm/dart.h" | 11 #include "vm/dart.h" |
| 12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
| 13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 #include "vm/stack_frame.h" | 15 #include "vm/stack_frame.h" |
| 16 #include "vm/store_buffer.h" | 16 #include "vm/store_buffer.h" |
| 17 #include "vm/verifier.h" | 17 #include "vm/verifier.h" |
| 18 #include "vm/visitor.h" | 18 #include "vm/visitor.h" |
| 19 #include "vm/weak_table.h" | 19 #include "vm/weak_table.h" |
| 20 #include "vm/object_id_ring.h" | |
| 20 | 21 |
| 21 namespace dart { | 22 namespace dart { |
| 22 | 23 |
| 23 // Scavenger uses RawObject::kMarkBit to distinguish forwaded and non-forwarded | 24 // Scavenger uses RawObject::kMarkBit to distinguish forwaded and non-forwarded |
| 24 // objects. The kMarkBit does not intersect with the target address because of | 25 // objects. The kMarkBit does not intersect with the target address because of |
| 25 // object alignment. | 26 // object alignment. |
| 26 enum { | 27 enum { |
| 27 kForwardingMask = 1 << RawObject::kMarkBit, | 28 kForwardingMask = 1 << RawObject::kMarkBit, |
| 28 kNotForwarded = 0, | 29 kNotForwarded = 0, |
| 29 kForwarded = kForwardingMask, | 30 kForwarded = kForwardingMask, |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 397 } | 398 } |
| 398 delete pending; | 399 delete pending; |
| 399 pending = next; | 400 pending = next; |
| 400 } | 401 } |
| 401 heap_->RecordData(kStoreBufferEntries, entries); | 402 heap_->RecordData(kStoreBufferEntries, entries); |
| 402 // Done iterating through old objects remembered in the store buffers. | 403 // Done iterating through old objects remembered in the store buffers. |
| 403 visitor->VisitingOldObject(NULL); | 404 visitor->VisitingOldObject(NULL); |
| 404 } | 405 } |
| 405 | 406 |
| 406 | 407 |
| 408 void Scavenger::IterateObjectIdTable(Isolate* isolate, | |
| 409 ScavengerVisitor* visitor) { | |
| 410 ObjectIdRing* ring = isolate->object_id_ring(); | |
| 411 ASSERT(ring != NULL); | |
| 412 ring->VisitPointers(visitor); | |
| 413 } | |
| 414 | |
| 415 | |
| 407 void Scavenger::IterateRoots(Isolate* isolate, | 416 void Scavenger::IterateRoots(Isolate* isolate, |
| 408 ScavengerVisitor* visitor, | 417 ScavengerVisitor* visitor, |
| 409 bool visit_prologue_weak_persistent_handles) { | 418 bool visit_prologue_weak_persistent_handles) { |
| 410 int64_t start = OS::GetCurrentTimeMicros(); | 419 int64_t start = OS::GetCurrentTimeMicros(); |
| 411 isolate->VisitObjectPointers(visitor, | 420 isolate->VisitObjectPointers(visitor, |
| 412 visit_prologue_weak_persistent_handles, | 421 visit_prologue_weak_persistent_handles, |
| 413 StackFrameIterator::kDontValidateFrames); | 422 StackFrameIterator::kDontValidateFrames); |
| 414 int64_t middle = OS::GetCurrentTimeMicros(); | 423 int64_t middle = OS::GetCurrentTimeMicros(); |
| 415 IterateStoreBuffers(isolate, visitor); | 424 IterateStoreBuffers(isolate, visitor); |
| 425 IterateObjectIdTable(isolate, visitor); | |
| 416 int64_t end = OS::GetCurrentTimeMicros(); | 426 int64_t end = OS::GetCurrentTimeMicros(); |
| 417 heap_->RecordTime(kVisitIsolateRoots, middle - start); | 427 heap_->RecordTime(kVisitIsolateRoots, middle - start); |
| 418 heap_->RecordTime(kIterateStoreBuffers, end - middle); | 428 heap_->RecordTime(kIterateStoreBuffers, end - middle); |
| 419 } | 429 } |
| 420 | 430 |
| 421 | 431 |
| 422 bool Scavenger::IsUnreachable(RawObject** p) { | 432 bool Scavenger::IsUnreachable(RawObject** p) { |
| 423 RawObject* raw_obj = *p; | 433 RawObject* raw_obj = *p; |
| 424 if (!raw_obj->IsHeapObject()) { | 434 if (!raw_obj->IsHeapObject()) { |
| 425 return false; | 435 return false; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 } | 593 } |
| 584 } | 594 } |
| 585 } | 595 } |
| 586 // Remove the old table as it has been replaced with the newly allocated | 596 // Remove the old table as it has been replaced with the newly allocated |
| 587 // table above. | 597 // table above. |
| 588 delete table; | 598 delete table; |
| 589 } | 599 } |
| 590 } | 600 } |
| 591 | 601 |
| 592 | 602 |
| 603 class ObjectIdRingMovePointerVisitor : public ObjectPointerVisitor { | |
| 604 public: | |
| 605 explicit ObjectIdRingMovePointerVisitor(Isolate* isolate) : | |
| 606 ObjectPointerVisitor(isolate) {} | |
| 607 | |
| 608 void Move(RawObject** current) { | |
| 609 RawObject* raw_obj = *current; | |
| 610 ASSERT(raw_obj->IsHeapObject()); | |
| 611 if (raw_obj->IsOldObject()) { | |
| 612 // Skip old objects. | |
| 613 return; | |
| 614 } | |
| 615 uword raw_addr = RawObject::ToAddr(raw_obj); | |
| 616 uword header = *reinterpret_cast<uword*>(raw_addr); | |
| 617 if (IsForwarding(header)) { | |
| 618 // The object has survived. Update its address in the table. | |
| 619 uword new_addr = ForwardedAddr(header); | |
| 620 raw_obj = RawObject::FromAddr(new_addr); | |
| 621 *current = raw_obj; | |
| 622 } | |
| 623 } | |
| 624 | |
| 625 void VisitPointers(RawObject** first, RawObject** last) { | |
| 626 for (RawObject** current = first; current <= last; current++) { | |
| 627 Move(current); | |
| 628 } | |
| 629 } | |
| 630 }; | |
| 631 | |
| 632 | |
| 633 void Scavenger::ProcessObjectIdTable(Isolate* isolate) { | |
| 634 ObjectIdRingMovePointerVisitor visitor(isolate); | |
| 635 ObjectIdRing* ring = isolate->object_id_ring(); | |
| 636 ASSERT(ring != NULL); | |
| 637 ring->VisitPointers(&visitor); | |
| 638 } | |
| 639 | |
| 640 | |
| 593 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 641 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 594 uword cur = FirstObjectStart(); | 642 uword cur = FirstObjectStart(); |
| 595 while (cur < top_) { | 643 while (cur < top_) { |
| 596 RawObject* raw_obj = RawObject::FromAddr(cur); | 644 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 597 cur += raw_obj->VisitPointers(visitor); | 645 cur += raw_obj->VisitPointers(visitor); |
| 598 } | 646 } |
| 599 } | 647 } |
| 600 | 648 |
| 601 | 649 |
| 602 void Scavenger::VisitObjects(ObjectVisitor* visitor) const { | 650 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); | 683 Prologue(isolate, invoke_api_callbacks); |
| 636 IterateRoots(isolate, &visitor, !invoke_api_callbacks); | 684 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
| 637 int64_t start = OS::GetCurrentTimeMicros(); | 685 int64_t start = OS::GetCurrentTimeMicros(); |
| 638 ProcessToSpace(&visitor); | 686 ProcessToSpace(&visitor); |
| 639 int64_t middle = OS::GetCurrentTimeMicros(); | 687 int64_t middle = OS::GetCurrentTimeMicros(); |
| 640 IterateWeakReferences(isolate, &visitor); | 688 IterateWeakReferences(isolate, &visitor); |
| 641 ScavengerWeakVisitor weak_visitor(this); | 689 ScavengerWeakVisitor weak_visitor(this); |
| 642 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); | 690 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| 643 visitor.Finalize(); | 691 visitor.Finalize(); |
| 644 ProcessWeakTables(); | 692 ProcessWeakTables(); |
| 693 ProcessObjectIdTable(isolate); | |
|
Ivan Posva
2013/07/11 17:01:42
It is unclear to me why you need this here and all
Cutch
2013/07/11 21:31:47
You are correct.
| |
| 645 int64_t end = OS::GetCurrentTimeMicros(); | 694 int64_t end = OS::GetCurrentTimeMicros(); |
| 646 heap_->RecordTime(kProcessToSpace, middle - start); | 695 heap_->RecordTime(kProcessToSpace, middle - start); |
| 647 heap_->RecordTime(kIterateWeaks, end - middle); | 696 heap_->RecordTime(kIterateWeaks, end - middle); |
| 648 Epilogue(isolate, invoke_api_callbacks); | 697 Epilogue(isolate, invoke_api_callbacks); |
| 649 | 698 |
| 650 if (FLAG_verify_after_gc) { | 699 if (FLAG_verify_after_gc) { |
| 651 OS::PrintErr("Verifying after Scavenge..."); | 700 OS::PrintErr("Verifying after Scavenge..."); |
| 652 heap_->Verify(); | 701 heap_->Verify(); |
| 653 OS::PrintErr(" done.\n"); | 702 OS::PrintErr(" done.\n"); |
| 654 } | 703 } |
| 655 | 704 |
| 656 // Done scavenging. Reset the marker. | 705 // Done scavenging. Reset the marker. |
| 657 ASSERT(scavenging_); | 706 ASSERT(scavenging_); |
| 658 scavenging_ = false; | 707 scavenging_ = false; |
| 659 } | 708 } |
| 660 | 709 |
| 661 | 710 |
| 662 void Scavenger::WriteProtect(bool read_only) { | 711 void Scavenger::WriteProtect(bool read_only) { |
| 663 space_->Protect( | 712 space_->Protect( |
| 664 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); | 713 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); |
| 665 } | 714 } |
| 666 | 715 |
| 667 | 716 |
| 668 } // namespace dart | 717 } // namespace dart |
| OLD | NEW |