Refactor how embedded pointers are visited.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Oct 2011 15:43:41 +0000 (15:43 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Oct 2011 15:43:41 +0000 (15:43 +0000)
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
src/assembler.h
src/ia32/assembler-ia32-inl.h
src/incremental-marking.cc
src/mark-compact.cc
src/mark-compact.h
src/objects.cc
src/objects.h
src/x64/assembler-x64-inl.h

index 54c291d..93cecf5 100644 (file)
@@ -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) {
index 01c3a70..e5661c9 100644 (file)
@@ -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;
index ed277e5..446aa3e 100644 (file)
@@ -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);
index 60a21ee..88ebd78 100644 (file)
@@ -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);
     }
   }
 
index 6250e54..9fa79ca 100644 (file)
@@ -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_,
index 8685036..d54d822 100644 (file)
@@ -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));
index c2ff64e..5612732 100644 (file)
@@ -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());
 }
index 2b53ff1..b95fa57 100644 (file)
@@ -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
index fabaf25..10f0b88 100644 (file)
@@ -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);