From 1da890af547a8d9217a8286b42abfc6e2ea23b34 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 12 Oct 2011 15:43:41 +0000 Subject: [PATCH] Refactor how embedded pointers are visited. This refactoring (almost) gets rid of the requirement to get the target object address for an object pointer embedded in code objects. This is not possible on MIPS as pointers are encoded using two instructions. All usages of RelocInfo::target_object_address() are (almost) obsoleted by this change. The serializer still uses it, so MIPS will not yet work with snapshots turned on. R=danno@chromium.org,vegorov@chromium.org Review URL: http://codereview.chromium.org/8245007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9597 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/assembler-arm-inl.h | 4 ++-- src/assembler.h | 3 +++ src/ia32/assembler-ia32-inl.h | 4 ++-- src/incremental-marking.cc | 14 ++++++-------- src/mark-compact.cc | 34 +++++++++++++++++++++++----------- src/mark-compact.h | 3 ++- src/objects.cc | 6 ++++++ src/objects.h | 6 +----- src/x64/assembler-x64-inl.h | 4 ++-- 9 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h index 54c291d..93cecf5 100644 --- a/src/arm/assembler-arm-inl.h +++ b/src/arm/assembler-arm-inl.h @@ -215,7 +215,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitEmbeddedPointer(host(), target_object_address()); + visitor->VisitEmbeddedPointer(this); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { @@ -241,7 +241,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, this); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { diff --git a/src/assembler.h b/src/assembler.h index 01c3a70..e5661c9 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -230,6 +230,9 @@ class RelocInfo BASE_EMBEDDED { static inline bool IsCodeTarget(Mode mode) { return mode <= LAST_CODE_ENUM; } + static inline bool IsEmbeddedObject(Mode mode) { + return mode == EMBEDDED_OBJECT; + } // Is the relocation mode affected by GC? static inline bool IsGCRelocMode(Mode mode) { return mode <= LAST_GCED_ENUM; diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h index ed277e5..446aa3e 100644 --- a/src/ia32/assembler-ia32-inl.h +++ b/src/ia32/assembler-ia32-inl.h @@ -214,7 +214,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitEmbeddedPointer(host(), target_object_address()); + visitor->VisitEmbeddedPointer(this); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); @@ -242,7 +242,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, this); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc index 60a21ee..88ebd78 100644 --- a/src/incremental-marking.cc +++ b/src/incremental-marking.cc @@ -117,14 +117,12 @@ class IncrementalMarkingMarkingVisitor : public ObjectVisitor { incremental_marking_(incremental_marking) { } - void VisitEmbeddedPointer(Code* host, Object** p) { - Object* obj = *p; - if (obj->NonFailureIsHeapObject()) { - heap_->mark_compact_collector()->RecordSlot( - reinterpret_cast(host), - p, - obj); - MarkObject(obj); + void VisitEmbeddedPointer(RelocInfo* rinfo) { + ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); + Object* target = rinfo->target_object(); + if (target->NonFailureIsHeapObject()) { + heap_->mark_compact_collector()->RecordRelocSlot(rinfo, target); + MarkObject(target); } } diff --git a/src/mark-compact.cc b/src/mark-compact.cc index 6250e54..9fa79ca 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -847,10 +847,14 @@ class StaticMarkingVisitor : public StaticVisitorBase { heap->mark_compact_collector()->MarkObject(cell, mark); } - static inline void VisitEmbeddedPointer(Heap* heap, Code* host, Object** p) { - MarkObjectByPointer(heap->mark_compact_collector(), - reinterpret_cast(host), - p); + static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) { + ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); + // TODO(mstarzinger): We do not short-circuit cons strings here, verify + // that there can be no such embedded pointers and add assertion here. + HeapObject* object = HeapObject::cast(rinfo->target_object()); + heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); + MarkBit mark = Marking::MarkBitFrom(object); + heap->mark_compact_collector()->MarkObject(object, mark); } static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { @@ -2458,8 +2462,11 @@ class PointersUpdatingVisitor: public ObjectVisitor { for (Object** p = start; p < end; p++) UpdatePointer(p); } - void VisitEmbeddedPointer(Code* host, Object** p) { - UpdatePointer(p); + void VisitEmbeddedPointer(RelocInfo* rinfo) { + ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); + Object* target = rinfo->target_object(); + VisitPointer(&target); + rinfo->set_target_object(target); } void VisitCodeTarget(RelocInfo* rinfo) { @@ -2773,6 +2780,11 @@ static inline void UpdateSlot(ObjectVisitor* v, if (rinfo.IsPatchedReturnSequence()) rinfo.Visit(v); break; } + case SlotsBuffer::EMBEDDED_OBJECT_SLOT: { + RelocInfo rinfo(addr, RelocInfo::EMBEDDED_OBJECT, 0, NULL); + rinfo.Visit(v); + break; + } default: UNREACHABLE(); break; @@ -3706,6 +3718,8 @@ bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { if (RelocInfo::IsCodeTarget(rmode)) { return SlotsBuffer::CODE_TARGET_SLOT; + } else if (RelocInfo::IsEmbeddedObject(rmode)) { + return SlotsBuffer::EMBEDDED_OBJECT_SLOT; } else if (RelocInfo::IsDebugBreakSlot(rmode)) { return SlotsBuffer::DEBUG_TARGET_SLOT; } else if (RelocInfo::IsJSReturn(rmode)) { @@ -3716,9 +3730,8 @@ static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { } -void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { - Page* target_page = Page::FromAddress( - reinterpret_cast
(target)); +void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { + Page* target_page = Page::FromAddress(reinterpret_cast
(target)); if (target_page->IsEvacuationCandidate() && (rinfo->host() == NULL || !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { @@ -3734,8 +3747,7 @@ void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { - Page* target_page = Page::FromAddress( - reinterpret_cast
(target)); + Page* target_page = Page::FromAddress(reinterpret_cast
(target)); if (target_page->IsEvacuationCandidate() && !ShouldSkipEvacuationSlotRecording(reinterpret_cast(slot))) { if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, diff --git a/src/mark-compact.h b/src/mark-compact.h index 8685036..d54d822 100644 --- a/src/mark-compact.h +++ b/src/mark-compact.h @@ -315,6 +315,7 @@ class SlotsBuffer { } enum SlotType { + EMBEDDED_OBJECT_SLOT, RELOCATED_CODE_OBJECT, CODE_TARGET_SLOT, CODE_ENTRY_SLOT, @@ -538,7 +539,7 @@ class MarkCompactCollector { } } - void RecordRelocSlot(RelocInfo* rinfo, Code* target); + void RecordRelocSlot(RelocInfo* rinfo, Object* target); void RecordCodeEntrySlot(Address slot, Code* target); INLINE(void RecordSlot(Object** anchor_slot, Object** slot, Object* object)); diff --git a/src/objects.cc b/src/objects.cc index c2ff64e..5612732 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -7371,6 +7371,12 @@ void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { } +void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { + ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); + VisitPointer(rinfo->target_object_address()); +} + + void Code::InvalidateRelocation() { set_relocation_info(GetHeap()->empty_byte_array()); } diff --git a/src/objects.h b/src/objects.h index 2b53ff1..b95fa57 100644 --- a/src/objects.h +++ b/src/objects.h @@ -7534,11 +7534,7 @@ class ObjectVisitor BASE_EMBEDDED { virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } // Visit pointer embedded into a code object. - virtual void VisitEmbeddedPointer(Code* host, Object** p) { - // Default implementation for the convenience of users that do - // not care about the host object. - VisitPointer(p); - } + virtual void VisitEmbeddedPointer(RelocInfo* rinfo); // Visits a contiguous arrays of external references (references to the C++ // heap) in the half-open range [start, end). Any or all of the values diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h index fabaf25..10f0b88 100644 --- a/src/x64/assembler-x64-inl.h +++ b/src/x64/assembler-x64-inl.h @@ -388,7 +388,7 @@ Object** RelocInfo::call_object_address() { void RelocInfo::Visit(ObjectVisitor* visitor) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - visitor->VisitEmbeddedPointer(host(), target_object_address()); + visitor->VisitEmbeddedPointer(this); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { visitor->VisitCodeTarget(this); @@ -416,7 +416,7 @@ template void RelocInfo::Visit(Heap* heap) { RelocInfo::Mode mode = rmode(); if (mode == RelocInfo::EMBEDDED_OBJECT) { - StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address()); + StaticVisitor::VisitEmbeddedPointer(heap, this); CPU::FlushICache(pc_, sizeof(Address)); } else if (RelocInfo::IsCodeTarget(mode)) { StaticVisitor::VisitCodeTarget(heap, this); -- 2.7.4