Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Unified Diff: src/heap/mark-compact.cc

Issue 1818013002: [heap] Optimize migration of objects (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
« no previous file with comments | « src/heap/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698