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 |