Index: src/heap/mark-compact.cc |
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc |
index abd8487b86fe97905380781798231ac13d04eeb0..2a77888fa784b510f230743fd9e461d6ea29f66d 100644 |
--- a/src/heap/mark-compact.cc |
+++ b/src/heap/mark-compact.cc |
@@ -1508,6 +1508,39 @@ void MarkCompactCollector::DiscoverGreyObjectsOnPage(MemoryChunk* p) { |
} |
} |
+class RecordMigratedSlotVisitor final : public ObjectVisitor { |
+ public: |
+ inline void VisitPointer(Object** p) final { |
+ RecordMigratedSlot(*p, reinterpret_cast<Address>(p)); |
+ } |
+ |
+ inline void VisitPointers(Object** start, Object** end) final { |
+ while (start < end) { |
+ RecordMigratedSlot(*start, reinterpret_cast<Address>(start)); |
+ ++start; |
+ } |
+ } |
+ |
+ inline void VisitCodeEntry(Address code_entry_slot) final { |
+ Address code_entry = Memory::Address_at(code_entry_slot); |
+ if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
+ RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot), |
+ CODE_ENTRY_SLOT, code_entry_slot); |
+ } |
+ } |
+ |
+ private: |
+ inline void RecordMigratedSlot(Object* value, Address slot) { |
+ if (value->IsHeapObject()) { |
+ Page* p = Page::FromAddress(reinterpret_cast<Address>(value)); |
+ if (p->InNewSpace()) { |
+ RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); |
+ } else if (p->IsEvacuationCandidate()) { |
+ RememberedSet<OLD_TO_OLD>::Insert(Page::FromAddress(slot), slot); |
+ } |
+ } |
+ } |
+}; |
class MarkCompactCollector::HeapObjectVisitor { |
public: |
@@ -1515,32 +1548,62 @@ class MarkCompactCollector::HeapObjectVisitor { |
virtual bool Visit(HeapObject* object) = 0; |
}; |
- |
class MarkCompactCollector::EvacuateVisitorBase |
: public MarkCompactCollector::HeapObjectVisitor { |
public: |
EvacuateVisitorBase(Heap* heap, CompactionSpaceCollection* compaction_spaces) |
: heap_(heap), compaction_spaces_(compaction_spaces) {} |
- bool TryEvacuateObject(PagedSpace* target_space, HeapObject* object, |
- HeapObject** target_object) { |
+ inline bool TryEvacuateObject(PagedSpace* target_space, HeapObject* object, |
+ HeapObject** target_object) { |
int size = object->Size(); |
AllocationAlignment alignment = object->RequiredAlignment(); |
AllocationResult allocation = target_space->AllocateRaw(size, alignment); |
if (allocation.To(target_object)) { |
- heap_->mark_compact_collector()->MigrateObject( |
- *target_object, object, size, target_space->identity()); |
+ MigrateObject(*target_object, object, size, target_space->identity()); |
return true; |
} |
return false; |
} |
+ inline void MigrateObject(HeapObject* dst, HeapObject* src, int size, |
+ AllocationSpace dest) { |
+ Address dst_addr = dst->address(); |
+ Address src_addr = src->address(); |
+ DCHECK(heap_->AllowedToBeMigrated(src, dest)); |
+ DCHECK(dest != LO_SPACE); |
+ if (dest == OLD_SPACE) { |
+ DCHECK_OBJECT_SIZE(size); |
+ DCHECK(IsAligned(size, kPointerSize)); |
+ heap_->MoveBlock(dst_addr, src_addr, size); |
+ if (FLAG_ignition && dst->IsBytecodeArray()) { |
+ PROFILE(heap_->isolate(), |
+ CodeMoveEvent(AbstractCode::cast(src), dst_addr)); |
+ } |
+ RecordMigratedSlotVisitor visitor; |
+ dst->IterateBodyFast(dst->map()->instance_type(), size, &visitor); |
+ } else if (dest == CODE_SPACE) { |
+ DCHECK_CODEOBJECT_SIZE(size, heap_->code_space()); |
+ PROFILE(heap_->isolate(), |
+ CodeMoveEvent(AbstractCode::cast(src), dst_addr)); |
+ heap_->MoveBlock(dst_addr, src_addr, size); |
+ RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(dst_addr), |
+ RELOCATED_CODE_OBJECT, dst_addr); |
+ Code::cast(dst)->Relocate(dst_addr - src_addr); |
+ } else { |
+ DCHECK_OBJECT_SIZE(size); |
+ DCHECK(dest == NEW_SPACE); |
+ heap_->MoveBlock(dst_addr, src_addr, size); |
+ } |
+ heap_->OnMoveEvent(dst, src, size); |
+ Memory::Address_at(src_addr) = dst_addr; |
+ } |
+ |
protected: |
Heap* heap_; |
CompactionSpaceCollection* compaction_spaces_; |
}; |
- |
class MarkCompactCollector::EvacuateNewSpaceVisitor final |
: public MarkCompactCollector::EvacuateVisitorBase { |
public: |
@@ -1575,8 +1638,7 @@ class MarkCompactCollector::EvacuateNewSpaceVisitor final |
} |
HeapObject* target = nullptr; |
AllocationSpace space = AllocateTargetObject(object, &target); |
- heap_->mark_compact_collector()->MigrateObject(HeapObject::cast(target), |
- object, size, space); |
+ MigrateObject(HeapObject::cast(target), object, size, space); |
if (V8_UNLIKELY(target->IsJSArrayBuffer())) { |
heap_->array_buffer_tracker()->MarkLive(JSArrayBuffer::cast(target)); |
} |
@@ -2556,95 +2618,6 @@ void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, |
} |
} |
- |
-class RecordMigratedSlotVisitor final : public ObjectVisitor { |
- public: |
- explicit RecordMigratedSlotVisitor(MarkCompactCollector* collector) |
- : collector_(collector) {} |
- |
- V8_INLINE void VisitPointer(Object** p) override { |
- RecordMigratedSlot(*p, reinterpret_cast<Address>(p)); |
- } |
- |
- V8_INLINE void VisitPointers(Object** start, Object** end) override { |
- while (start < end) { |
- RecordMigratedSlot(*start, reinterpret_cast<Address>(start)); |
- ++start; |
- } |
- } |
- |
- V8_INLINE void VisitCodeEntry(Address code_entry_slot) override { |
- if (collector_->compacting_) { |
- Address code_entry = Memory::Address_at(code_entry_slot); |
- if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) { |
- RememberedSet<OLD_TO_OLD>::InsertTyped( |
- Page::FromAddress(code_entry_slot), CODE_ENTRY_SLOT, |
- code_entry_slot); |
- } |
- } |
- } |
- |
- private: |
- inline void RecordMigratedSlot(Object* value, Address slot) { |
- if (collector_->heap()->InNewSpace(value)) { |
- RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); |
- } else if (value->IsHeapObject() && |
- Page::FromAddress(reinterpret_cast<Address>(value)) |
- ->IsEvacuationCandidate()) { |
- RememberedSet<OLD_TO_OLD>::Insert(Page::FromAddress(slot), slot); |
- } |
- } |
- |
- MarkCompactCollector* collector_; |
-}; |
- |
- |
-// We scavenge new space simultaneously with sweeping. This is done in two |
-// passes. |
-// |
-// The first pass migrates all alive objects from one semispace to another or |
-// promotes them to old space. Forwarding address is written directly into |
-// first word of object without any encoding. If object is dead we write |
-// NULL as a forwarding address. |
-// |
-// The second pass updates pointers to new space in all spaces. It is possible |
-// to encounter pointers to dead new space objects during traversal of pointers |
-// to new space. We should clear them to avoid encountering them during next |
-// pointer iteration. This is an issue if the store buffer overflows and we |
-// have to scan the entire old space, including dead objects, looking for |
-// pointers to new space. |
-void MarkCompactCollector::MigrateObject(HeapObject* dst, HeapObject* src, |
- int size, AllocationSpace dest) { |
- Address dst_addr = dst->address(); |
- Address src_addr = src->address(); |
- DCHECK(heap()->AllowedToBeMigrated(src, dest)); |
- DCHECK(dest != LO_SPACE); |
- if (dest == OLD_SPACE) { |
- DCHECK_OBJECT_SIZE(size); |
- DCHECK(IsAligned(size, kPointerSize)); |
- |
- heap()->MoveBlock(dst->address(), src->address(), size); |
- if (FLAG_ignition && dst->IsBytecodeArray()) { |
- PROFILE(isolate(), CodeMoveEvent(AbstractCode::cast(src), dst_addr)); |
- } |
- RecordMigratedSlotVisitor visitor(this); |
- dst->IterateBody(&visitor); |
- } else if (dest == CODE_SPACE) { |
- DCHECK_CODEOBJECT_SIZE(size, heap()->code_space()); |
- PROFILE(isolate(), CodeMoveEvent(AbstractCode::cast(src), dst_addr)); |
- heap()->MoveBlock(dst_addr, src_addr, size); |
- RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(dst_addr), |
- RELOCATED_CODE_OBJECT, dst_addr); |
- Code::cast(dst)->Relocate(dst_addr - src_addr); |
- } else { |
- DCHECK_OBJECT_SIZE(size); |
- DCHECK(dest == NEW_SPACE); |
- heap()->MoveBlock(dst_addr, src_addr, size); |
- } |
- heap()->OnMoveEvent(dst, src, size); |
- Memory::Address_at(src_addr) = dst_addr; |
-} |
- |
static inline void UpdateTypedSlot(Isolate* isolate, ObjectVisitor* v, |
SlotType slot_type, Address addr) { |
switch (slot_type) { |