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 54c291d412e2130f42b17a1676d234cf577d3f45..93cecf52b68cd5c249975797800bf4ab45acd442 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 01c3a70c6542889975f5b4e15db8943106314696..e5661c9f12644e56a64a0c2d3cc178736bb401ce 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 ed277e5da2dea96cdff18f3917a5a02e03c3b77d..446aa3e2de7b684747155f01dea41e6ec6882132 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 60a21eed6a984efe65db86c08f890060a3e25119..88ebd783ea8369a0839e9c1e39207596aafa8972 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 6250e5439f17e52f129457dcd13b65ef45ece1a2..9fa79ca74629a406ea6a27181bfa296c23f47cee 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 86850369a906029c2075c000df787009f72013ae..d54d8224956e6dcd6c83b376cd2d5550420f4cc6 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 c2ff64eb920fb079a7a448a7340fc86ccf399eb9..561273230389c5909163fd1fd253f887b7e66490 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 2b53ff19369ff526768d4308fdfad82855d5d1ca..b95fa574a05c9af262f5fbd64a206a7c203d682b 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 fabaf259b31209e3887343a3be8a0bdfca3a220c..10f0b886da57d37638400c3fc3df9d402dc6df07 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);