Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index 89ce89ef77ebf66a98189d70a1f0599ed5371301..f155ceb25cf2ece4a0e5af76f65f194bbf8f74f0 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -2916,6 +2916,14 @@ class PointersUpdatingVisitor: public ObjectVisitor { |
} |
} |
+ void VisitCodeTarget(Address target_address_pointer) { |
+ Object* target = Code::GetCodeFromTargetAddress( |
+ Memory::Address_at(target_address_pointer)); |
+ VisitPointer(&target); |
+ *reinterpret_cast<Address*>(target_address_pointer) = |
Michael Starzinger
2014/03/07 14:36:59
Instead of the reinterpret case, case we use ...
rmcilroy
2014/03/10 12:25:23
Removed VisitCodeTarget(Address) as discussed, so
|
+ Code::cast(target)->instruction_start(); |
+ } |
+ |
void VisitCodeAgeSequence(RelocInfo* rinfo) { |
ASSERT(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); |
Object* stub = rinfo->code_age_stub(); |
@@ -3156,11 +3164,15 @@ static inline void UpdateSlot(Isolate* isolate, |
SlotsBuffer::SlotType slot_type, |
Address addr) { |
switch (slot_type) { |
- case SlotsBuffer::CODE_TARGET_SLOT: { |
+ case SlotsBuffer::CODE_TARGET_RELOC_INFO_SLOT: { |
RelocInfo rinfo(addr, RelocInfo::CODE_TARGET, 0, NULL); |
rinfo.Visit(isolate, v); |
break; |
} |
+ case SlotsBuffer::CODE_TARGET_CONSTANT_POOL_SLOT: { |
+ v->VisitCodeTarget(addr); |
+ break; |
+ } |
case SlotsBuffer::CODE_ENTRY_SLOT: { |
v->VisitCodeEntry(addr); |
break; |
@@ -4324,7 +4336,7 @@ bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, |
static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
if (RelocInfo::IsCodeTarget(rmode)) { |
- return SlotsBuffer::CODE_TARGET_SLOT; |
+ return SlotsBuffer::CODE_TARGET_RELOC_INFO_SLOT; |
} else if (RelocInfo::IsEmbeddedObject(rmode)) { |
return SlotsBuffer::EMBEDDED_OBJECT_SLOT; |
} else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
@@ -4339,14 +4351,33 @@ static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { |
Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
+ RelocInfo::Mode rmode = rinfo->rmode(); |
if (target_page->IsEvacuationCandidate() && |
(rinfo->host() == NULL || |
!ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
- if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
- target_page->slots_buffer_address(), |
- SlotTypeForRMode(rinfo->rmode()), |
- rinfo->pc(), |
- SlotsBuffer::FAIL_ON_OVERFLOW)) { |
+ bool success; |
+ if (RelocInfo::IsEmbeddedObject(rmode) && rinfo->IsInConstantPool()) { |
+ // This doesn't need to be typed since it is just a normal heap pointer. |
+ Object** target_pointer = |
+ reinterpret_cast<Object**>(rinfo->constant_pool_entry_address()); |
+ success = SlotsBuffer::AddTo(&slots_buffer_allocator_, |
+ target_page->slots_buffer_address(), |
+ target_pointer, |
+ SlotsBuffer::FAIL_ON_OVERFLOW); |
+ } else if (RelocInfo::IsCodeTarget(rmode) && rinfo->IsInConstantPool()) { |
+ success = SlotsBuffer::AddTo(&slots_buffer_allocator_, |
+ target_page->slots_buffer_address(), |
+ SlotsBuffer::CODE_TARGET_CONSTANT_POOL_SLOT, |
+ rinfo->constant_pool_entry_address(), |
+ SlotsBuffer::FAIL_ON_OVERFLOW); |
+ } else { |
+ success = SlotsBuffer::AddTo(&slots_buffer_allocator_, |
+ target_page->slots_buffer_address(), |
+ SlotTypeForRMode(rmode), |
+ rinfo->pc(), |
+ SlotsBuffer::FAIL_ON_OVERFLOW); |
+ } |
+ if (!success) { |
EvictEvacuationCandidate(target_page); |
} |
} |