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
parent d32c330e
......@@ -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<typename StaticVisitor>
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) {
......
......@@ -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;
......
......@@ -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<typename StaticVisitor>
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);
......
......@@ -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<Object**>(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);
}
}
......
......@@ -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<Object**>(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<Address>(target));
void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) {
Page* target_page = Page::FromAddress(reinterpret_cast<Address>(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<Address>(target));
Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target));
if (target_page->IsEvacuationCandidate() &&
!ShouldSkipEvacuationSlotRecording(reinterpret_cast<Object**>(slot))) {
if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
......
......@@ -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));
......
......@@ -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());
}
......
......@@ -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
......
......@@ -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<typename StaticVisitor>
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment