| 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 |