OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p)); | 1643 LiveObjectIterator<kGreyObjects> it(p, MarkingState::Internal(p)); |
1644 HeapObject* object = NULL; | 1644 HeapObject* object = NULL; |
1645 while ((object = it.Next()) != NULL) { | 1645 while ((object = it.Next()) != NULL) { |
1646 DCHECK(ObjectMarking::IsGrey(object, MarkingState::Internal(object))); | 1646 DCHECK(ObjectMarking::IsGrey(object, MarkingState::Internal(object))); |
1647 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object)); | 1647 ObjectMarking::GreyToBlack(object, MarkingState::Internal(object)); |
1648 PushBlack(object); | 1648 PushBlack(object); |
1649 if (marking_deque()->IsFull()) return; | 1649 if (marking_deque()->IsFull()) return; |
1650 } | 1650 } |
1651 } | 1651 } |
1652 | 1652 |
1653 class RecordMigratedSlotVisitor final : public ObjectVisitor { | 1653 class RecordMigratedSlotVisitor : public ObjectVisitor { |
1654 public: | 1654 public: |
1655 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector) | 1655 explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector) |
1656 : collector_(collector) {} | 1656 : collector_(collector) {} |
1657 | 1657 |
1658 inline void VisitPointer(HeapObject* host, Object** p) final { | 1658 inline void VisitPointer(HeapObject* host, Object** p) final { |
1659 RecordMigratedSlot(*p, reinterpret_cast<Address>(p)); | 1659 RecordMigratedSlot(host, *p, reinterpret_cast<Address>(p)); |
1660 } | 1660 } |
1661 | 1661 |
1662 inline void VisitPointers(HeapObject* host, Object** start, | 1662 inline void VisitPointers(HeapObject* host, Object** start, |
1663 Object** end) final { | 1663 Object** end) final { |
1664 while (start < end) { | 1664 while (start < end) { |
1665 RecordMigratedSlot(*start, reinterpret_cast<Address>(start)); | 1665 RecordMigratedSlot(host, *start, reinterpret_cast<Address>(start)); |
1666 ++start; | 1666 ++start; |
1667 } | 1667 } |
1668 } | 1668 } |
1669 | 1669 |
1670 inline void VisitCodeEntry(JSFunction* host, Address code_entry_slot) final { | 1670 inline void VisitCodeEntry(JSFunction* host, |
| 1671 Address code_entry_slot) override { |
1671 Address code_entry = Memory::Address_at(code_entry_slot); | 1672 Address code_entry = Memory::Address_at(code_entry_slot); |
1672 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { | 1673 if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
1673 RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot), | 1674 RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot), |
1674 nullptr, CODE_ENTRY_SLOT, | 1675 nullptr, CODE_ENTRY_SLOT, |
1675 code_entry_slot); | 1676 code_entry_slot); |
1676 } | 1677 } |
1677 } | 1678 } |
1678 | 1679 |
1679 inline void VisitCodeTarget(Code* host, RelocInfo* rinfo) final { | 1680 inline void VisitCodeTarget(Code* host, RelocInfo* rinfo) override { |
1680 DCHECK_EQ(host, rinfo->host()); | 1681 DCHECK_EQ(host, rinfo->host()); |
1681 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); | 1682 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); |
1682 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 1683 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
1683 // The target is always in old space, we don't have to record the slot in | 1684 // The target is always in old space, we don't have to record the slot in |
1684 // the old-to-new remembered set. | 1685 // the old-to-new remembered set. |
1685 DCHECK(!collector_->heap()->InNewSpace(target)); | 1686 DCHECK(!collector_->heap()->InNewSpace(target)); |
1686 collector_->RecordRelocSlot(host, rinfo, target); | 1687 collector_->RecordRelocSlot(host, rinfo, target); |
1687 } | 1688 } |
1688 | 1689 |
1689 inline void VisitDebugTarget(Code* host, RelocInfo* rinfo) final { | 1690 inline void VisitDebugTarget(Code* host, RelocInfo* rinfo) override { |
1690 DCHECK_EQ(host, rinfo->host()); | 1691 DCHECK_EQ(host, rinfo->host()); |
1691 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 1692 DCHECK(RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
1692 rinfo->IsPatchedDebugBreakSlotSequence()); | 1693 rinfo->IsPatchedDebugBreakSlotSequence()); |
1693 Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); | 1694 Code* target = Code::GetCodeFromTargetAddress(rinfo->debug_call_address()); |
1694 // The target is always in old space, we don't have to record the slot in | 1695 // The target is always in old space, we don't have to record the slot in |
1695 // the old-to-new remembered set. | 1696 // the old-to-new remembered set. |
1696 DCHECK(!collector_->heap()->InNewSpace(target)); | 1697 DCHECK(!collector_->heap()->InNewSpace(target)); |
1697 collector_->RecordRelocSlot(host, rinfo, target); | 1698 collector_->RecordRelocSlot(host, rinfo, target); |
1698 } | 1699 } |
1699 | 1700 |
1700 inline void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) final { | 1701 inline void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) override { |
1701 DCHECK_EQ(host, rinfo->host()); | 1702 DCHECK_EQ(host, rinfo->host()); |
1702 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 1703 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
1703 HeapObject* object = HeapObject::cast(rinfo->target_object()); | 1704 HeapObject* object = HeapObject::cast(rinfo->target_object()); |
1704 collector_->heap()->RecordWriteIntoCode(host, rinfo, object); | 1705 collector_->heap()->RecordWriteIntoCode(host, rinfo, object); |
1705 collector_->RecordRelocSlot(host, rinfo, object); | 1706 collector_->RecordRelocSlot(host, rinfo, object); |
1706 } | 1707 } |
1707 | 1708 |
1708 inline void VisitCellPointer(Code* host, RelocInfo* rinfo) final { | 1709 inline void VisitCellPointer(Code* host, RelocInfo* rinfo) override { |
1709 DCHECK_EQ(host, rinfo->host()); | 1710 DCHECK_EQ(host, rinfo->host()); |
1710 DCHECK(rinfo->rmode() == RelocInfo::CELL); | 1711 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
1711 Cell* cell = rinfo->target_cell(); | 1712 Cell* cell = rinfo->target_cell(); |
1712 // The cell is always in old space, we don't have to record the slot in | 1713 // The cell is always in old space, we don't have to record the slot in |
1713 // the old-to-new remembered set. | 1714 // the old-to-new remembered set. |
1714 DCHECK(!collector_->heap()->InNewSpace(cell)); | 1715 DCHECK(!collector_->heap()->InNewSpace(cell)); |
1715 collector_->RecordRelocSlot(host, rinfo, cell); | 1716 collector_->RecordRelocSlot(host, rinfo, cell); |
1716 } | 1717 } |
1717 | 1718 |
1718 // Entries that will never move. | 1719 // Entries that will never move. |
1719 inline void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) final { | 1720 inline void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) override { |
1720 DCHECK_EQ(host, rinfo->host()); | 1721 DCHECK_EQ(host, rinfo->host()); |
1721 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); | 1722 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); |
1722 Code* stub = rinfo->code_age_stub(); | 1723 Code* stub = rinfo->code_age_stub(); |
1723 USE(stub); | 1724 USE(stub); |
1724 DCHECK(!Page::FromAddress(stub->address())->IsEvacuationCandidate()); | 1725 DCHECK(!Page::FromAddress(stub->address())->IsEvacuationCandidate()); |
1725 } | 1726 } |
1726 | 1727 |
1727 // Entries that are skipped for recording. | 1728 // Entries that are skipped for recording. |
1728 inline void VisitExternalReference(Code* host, RelocInfo* rinfo) final {} | 1729 inline void VisitExternalReference(Code* host, RelocInfo* rinfo) final {} |
1729 inline void VisitExternalReference(Foreign* host, Address* p) final {} | 1730 inline void VisitExternalReference(Foreign* host, Address* p) final {} |
1730 inline void VisitRuntimeEntry(Code* host, RelocInfo* rinfo) final {} | 1731 inline void VisitRuntimeEntry(Code* host, RelocInfo* rinfo) final {} |
1731 inline void VisitInternalReference(Code* host, RelocInfo* rinfo) final {} | 1732 inline void VisitInternalReference(Code* host, RelocInfo* rinfo) final {} |
1732 | 1733 |
1733 private: | 1734 protected: |
1734 inline void RecordMigratedSlot(Object* value, Address slot) { | 1735 inline virtual void RecordMigratedSlot(HeapObject* host, Object* value, |
| 1736 Address slot) { |
1735 if (value->IsHeapObject()) { | 1737 if (value->IsHeapObject()) { |
1736 Page* p = Page::FromAddress(reinterpret_cast<Address>(value)); | 1738 Page* p = Page::FromAddress(reinterpret_cast<Address>(value)); |
1737 if (p->InNewSpace()) { | 1739 if (p->InNewSpace()) { |
1738 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); | 1740 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); |
1739 } else if (p->IsEvacuationCandidate()) { | 1741 } else if (p->IsEvacuationCandidate()) { |
1740 RememberedSet<OLD_TO_OLD>::Insert(Page::FromAddress(slot), slot); | 1742 RememberedSet<OLD_TO_OLD>::Insert(Page::FromAddress(slot), slot); |
1741 } | 1743 } |
1742 } | 1744 } |
1743 } | 1745 } |
1744 | 1746 |
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4204 // The target is always in old space, we don't have to record the slot in | 4206 // The target is always in old space, we don't have to record the slot in |
4205 // the old-to-new remembered set. | 4207 // the old-to-new remembered set. |
4206 DCHECK(!heap()->InNewSpace(target)); | 4208 DCHECK(!heap()->InNewSpace(target)); |
4207 RecordRelocSlot(host, &rinfo, target); | 4209 RecordRelocSlot(host, &rinfo, target); |
4208 } | 4210 } |
4209 } | 4211 } |
4210 } | 4212 } |
4211 | 4213 |
4212 } // namespace internal | 4214 } // namespace internal |
4213 } // namespace v8 | 4215 } // namespace v8 |
OLD | NEW |