Pass correct anchor_slot for EMBEDDED_OBJECT pointers from code objects.
authorvegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 28 Sep 2011 17:45:58 +0000 (17:45 +0000)
committervegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 28 Sep 2011 17:45:58 +0000 (17:45 +0000)
Correctly initialize newly created large-object pages when incremental marking with compaction is in progress.

R=erik.corry@gmail.com
BUG=v8:1737

Review URL: http://codereview.chromium.org/8070002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/assembler-arm-inl.h
src/ia32/assembler-ia32-inl.h
src/incremental-marking.cc
src/incremental-marking.h
src/mark-compact.cc
src/mips/assembler-mips-inl.h
src/objects.h
src/x64/assembler-x64-inl.h

index 5cb41cab4ec99c9c2445b6a6daa16d2d7d600b0f..54c291d412e2130f42b17a1676d234cf577d3f45 100644 (file)
@@ -215,7 +215,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
 void RelocInfo::Visit(ObjectVisitor* visitor) {
   RelocInfo::Mode mode = rmode();
   if (mode == RelocInfo::EMBEDDED_OBJECT) {
-    visitor->VisitPointer(target_object_address());
+    visitor->VisitEmbeddedPointer(host(), target_object_address());
   } 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::VisitPointer(heap, target_object_address());
+    StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
   } else if (RelocInfo::IsCodeTarget(mode)) {
     StaticVisitor::VisitCodeTarget(heap, this);
   } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
index abb437f3b1505f9b97d47c8f4ed9e2d0206500c8..ed277e5da2dea96cdff18f3917a5a02e03c3b77d 100644 (file)
@@ -214,7 +214,7 @@ bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
 void RelocInfo::Visit(ObjectVisitor* visitor) {
   RelocInfo::Mode mode = rmode();
   if (mode == RelocInfo::EMBEDDED_OBJECT) {
-    visitor->VisitPointer(target_object_address());
+    visitor->VisitEmbeddedPointer(host(), target_object_address());
     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::VisitPointer(heap, target_object_address());
+    StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
     CPU::FlushICache(pc_, sizeof(Address));
   } else if (RelocInfo::IsCodeTarget(mode)) {
     StaticVisitor::VisitCodeTarget(heap, this);
index d9725244a804aa3c1f6881ed5e2e1b39199a6f66..95642e90f19d11b3212bc37013ec46433da9701c 100644 (file)
@@ -115,6 +115,17 @@ 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 VisitCodeTarget(RelocInfo* rinfo) {
     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
     Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
@@ -218,10 +229,18 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
 
 
 void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
-                                              bool is_marking) {
+                                              bool is_marking,
+                                              bool is_compacting) {
   if (is_marking) {
     chunk->SetFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
     chunk->SetFlag(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING);
+
+    // It's difficult to filter out slots recorded for large objects.
+    if (chunk->owner()->identity() == LO_SPACE &&
+        chunk->size() > static_cast<size_t>(Page::kPageSize) &&
+        is_compacting) {
+      chunk->SetFlag(MemoryChunk::RESCAN_ON_EVACUATION);
+    }
   } else if (chunk->owner()->identity() == CELL_SPACE ||
              chunk->scan_on_scavenge()) {
     chunk->ClearFlag(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING);
@@ -250,7 +269,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrierForSpace(
   PageIterator it(space);
   while (it.has_next()) {
     Page* p = it.next();
-    SetOldSpacePageFlags(p, false);
+    SetOldSpacePageFlags(p, false, false);
   }
 }
 
@@ -275,7 +294,7 @@ void IncrementalMarking::DeactivateIncrementalWriteBarrier() {
 
   LargePage* lop = heap_->lo_space()->first_page();
   while (lop->is_valid()) {
-    SetOldSpacePageFlags(lop, false);
+    SetOldSpacePageFlags(lop, false, false);
     lop = lop->next_page();
   }
 }
@@ -285,7 +304,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier(PagedSpace* space) {
   PageIterator it(space);
   while (it.has_next()) {
     Page* p = it.next();
-    SetOldSpacePageFlags(p, true);
+    SetOldSpacePageFlags(p, true, is_compacting_);
   }
 }
 
@@ -309,7 +328,7 @@ void IncrementalMarking::ActivateIncrementalWriteBarrier() {
 
   LargePage* lop = heap_->lo_space()->first_page();
   while (lop->is_valid()) {
-    SetOldSpacePageFlags(lop, true);
+    SetOldSpacePageFlags(lop, true, is_compacting_);
     lop = lop->next_page();
   }
 }
@@ -453,19 +472,6 @@ void IncrementalMarking::StartMarking() {
     MarkObjectGreyDoNotEnqueue(heap_->polymorphic_code_cache());
   }
 
-  if (is_compacting_) {
-    // It's difficult to filter out slots recorded for large objects.
-    LargeObjectIterator it(heap_->lo_space());
-    for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
-      if (obj->IsFixedArray() || obj->IsCode()) {
-        Page* p = Page::FromAddress(obj->address());
-        if (p->size() > static_cast<size_t>(Page::kPageSize)) {
-          p->SetFlag(Page::RESCAN_ON_EVACUATION);
-        }
-      }
-    }
-  }
-
   // Mark strong roots grey.
   IncrementalMarkingRootMarkingVisitor visitor(heap_, this);
   heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
index cd1a41142107b22e36012739ab6651f53b594f00..30dbbc1605c7c5415767101469cc1f55c2d504ef 100644 (file)
@@ -172,7 +172,7 @@ class IncrementalMarking {
   }
 
   inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
-    SetOldSpacePageFlags(chunk, IsMarking());
+    SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
   }
 
   inline void SetNewSpacePageFlags(NewSpacePage* chunk) {
@@ -208,7 +208,7 @@ class IncrementalMarking {
 
   void StartMarking();
 
-  static void ActivateIncrementalWriteBarrier(PagedSpace* space);
+  void ActivateIncrementalWriteBarrier(PagedSpace* space);
   static void ActivateIncrementalWriteBarrier(NewSpace* space);
   void ActivateIncrementalWriteBarrier();
 
@@ -216,7 +216,10 @@ class IncrementalMarking {
   static void DeactivateIncrementalWriteBarrierForSpace(NewSpace* space);
   void DeactivateIncrementalWriteBarrier();
 
-  static void SetOldSpacePageFlags(MemoryChunk* chunk, bool is_marking);
+  static void SetOldSpacePageFlags(MemoryChunk* chunk,
+                                   bool is_marking,
+                                   bool is_compacting);
+
   static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking);
 
   void EnsureMarkingDequeIsCommitted();
index 4b0f7e232c5fd91a0f439cfff9fd63661ceafa11..4fc9fdba5e974a8c43fa9c4f1872cbc93f01ca1d 100644 (file)
@@ -841,6 +841,12 @@ 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 VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
@@ -2441,6 +2447,10 @@ class PointersUpdatingVisitor: public ObjectVisitor {
     for (Object** p = start; p < end; p++) UpdatePointer(p);
   }
 
+  void VisitEmbeddedPointer(Code* host, Object** p) {
+    UpdatePointer(p);
+  }
+
   void VisitCodeTarget(RelocInfo* rinfo) {
     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
     Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
index c4c4fd25906fd2a6b6578ed19c60606ce3e60399..0cbe533398588e952899ec42cdef0cc9c3b51c36 100644 (file)
@@ -244,7 +244,7 @@ void RelocInfo::Visit(ObjectVisitor* visitor) {
   if (mode == RelocInfo::EMBEDDED_OBJECT) {
     Object** p = target_object_address();
     Object* orig = *p;
-    visitor->VisitPointer(p);
+    visitor->VisitEmbeddedPointer(host(), p);
     if (*p != orig) {
       set_target_object(*p);
     }
@@ -273,7 +273,7 @@ template<typename StaticVisitor>
 void RelocInfo::Visit(Heap* heap) {
   RelocInfo::Mode mode = rmode();
   if (mode == RelocInfo::EMBEDDED_OBJECT) {
-    StaticVisitor::VisitPointer(heap, target_object_address());
+    StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
   } else if (RelocInfo::IsCodeTarget(mode)) {
     StaticVisitor::VisitCodeTarget(heap, this);
   } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
index 2bf99f313975da3bbf36ed8c8518721fae414c44..ef9fad59509cce0d2c271aef69399c8eea108d4f 100644 (file)
@@ -7502,6 +7502,13 @@ class ObjectVisitor BASE_EMBEDDED {
   // Handy shorthand for visiting a single pointer.
   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);
+  }
+
   // 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
   // may be modified on return.
index 254795a9413ca25c5f642b02a82e492b8f125c25..fabaf259b31209e3887343a3be8a0bdfca3a220c 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->VisitPointer(target_object_address());
+    visitor->VisitEmbeddedPointer(host(), target_object_address());
     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::VisitPointer(heap, target_object_address());
+    StaticVisitor::VisitEmbeddedPointer(heap, host(), target_object_address());
     CPU::FlushICache(pc_, sizeof(Address));
   } else if (RelocInfo::IsCodeTarget(mode)) {
     StaticVisitor::VisitCodeTarget(heap, this);