Refactor incremental marking to use static visitor.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 25 Jul 2012 15:23:07 +0000 (15:23 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 25 Jul 2012 15:23:07 +0000 (15:23 +0000)
This is a refactoring only change that switches incremental marking to
use a static object visitor. It also shares the common code between the
non-incremental and the incremental marker. Sharing that would require
semantical changes will be done later.

R=verwaest@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10816007

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

src/heap.h
src/incremental-marking.cc
src/incremental-marking.h
src/mark-compact.cc
src/mark-compact.h
src/objects-visiting-inl.h
src/objects-visiting.h
src/objects.cc
src/objects.h

index b7caee7..85a64ec 100644 (file)
@@ -2108,7 +2108,7 @@ class Heap {
   friend class Page;
   friend class Isolate;
   friend class MarkCompactCollector;
-  friend class StaticMarkingVisitor;
+  friend class MarkCompactMarkingVisitor;
   friend class MapCompact;
 
   DISALLOW_COPY_AND_ASSIGN(Heap);
index 93fa544..ebbee25 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "code-stubs.h"
 #include "compilation-cache.h"
+#include "objects-visiting.h"
+#include "objects-visiting-inl.h"
 #include "v8conversions.h"
 
 namespace v8 {
@@ -160,93 +162,109 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(HeapObject* obj,
 }
 
 
-class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
+class IncrementalMarkingMarkingVisitor
+    : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> {
  public:
-  IncrementalMarkingMarkingVisitor(Heap* heap,
-                                   IncrementalMarking* incremental_marking)
-      : heap_(heap),
-        incremental_marking_(incremental_marking) {
+  static void Initialize() {
+    StaticMarkingVisitor<IncrementalMarkingMarkingVisitor>::Initialize();
+
+    table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);
+
+    table_.Register(kVisitJSFunction, &VisitJSFunction);
+
+    table_.Register(kVisitJSRegExp, &VisitJSRegExp);
   }
 
-  void VisitEmbeddedPointer(RelocInfo* rinfo) {
+  static inline void VisitEmbeddedPointer(Heap* heap, 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);
+      heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+      MarkObject(heap, target);
     }
   }
 
-  void VisitCodeTarget(RelocInfo* rinfo) {
+  static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
     Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
     if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
-        && (target->ic_age() != heap_->global_ic_age())) {
+        && (target->ic_age() != heap->global_ic_age())) {
       IC::Clear(rinfo->pc());
       target = Code::GetCodeFromTargetAddress(rinfo->target_address());
     }
-    heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
-    MarkObject(target);
+    heap->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
+    MarkObject(heap, target);
   }
 
-  void VisitDebugTarget(RelocInfo* rinfo) {
-    ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
-            rinfo->IsPatchedReturnSequence()) ||
-           (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
-            rinfo->IsPatchedDebugBreakSlotSequence()));
-    Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
-    heap_->mark_compact_collector()->RecordRelocSlot(rinfo, Code::cast(target));
-    MarkObject(target);
+  static void VisitCode(Map* map, HeapObject* object) {
+    Heap* heap = map->GetHeap();
+    Code* code = reinterpret_cast<Code*>(object);
+    code->CodeIterateBody<IncrementalMarkingMarkingVisitor>(heap);
   }
 
-  void VisitCodeEntry(Address entry_address) {
-    Object* target = Code::GetObjectFromEntryAddress(entry_address);
-    heap_->mark_compact_collector()->
-        RecordCodeEntrySlot(entry_address, Code::cast(target));
-    MarkObject(target);
+  static void VisitJSWeakMap(Map* map, HeapObject* object) {
+    Heap* heap = map->GetHeap();
+    VisitPointers(heap,
+                  HeapObject::RawField(object, JSWeakMap::kPropertiesOffset),
+                  HeapObject::RawField(object, JSWeakMap::kSize));
   }
 
-  void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {
-    if (shared->ic_age() != heap_->global_ic_age()) {
-      shared->ResetForNewContext(heap_->global_ic_age());
+  static void VisitSharedFunctionInfo(Map* map, HeapObject* object) {
+    Heap* heap = map->GetHeap();
+    SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
+    if (shared->ic_age() != heap->global_ic_age()) {
+      shared->ResetForNewContext(heap->global_ic_age());
     }
-  }
-
-  void VisitPointer(Object** p) {
+    FixedBodyVisitor<IncrementalMarkingMarkingVisitor,
+                     SharedFunctionInfo::BodyDescriptor,
+                     void>::Visit(map, object);
+  }
+
+  static inline void VisitJSFunction(Map* map, HeapObject* object) {
+    Heap* heap = map->GetHeap();
+    // Iterate over all fields in the body but take care in dealing with
+    // the code entry and skip weak fields.
+    VisitPointers(heap,
+                  HeapObject::RawField(object, JSFunction::kPropertiesOffset),
+                  HeapObject::RawField(object, JSFunction::kCodeEntryOffset));
+    VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset);
+    VisitPointers(heap,
+                  HeapObject::RawField(object,
+                      JSFunction::kCodeEntryOffset + kPointerSize),
+                  HeapObject::RawField(object,
+                      JSFunction::kNonWeakFieldsEndOffset));
+  }
+
+  INLINE(static void VisitPointer(Heap* heap, Object** p)) {
     Object* obj = *p;
     if (obj->NonFailureIsHeapObject()) {
-      heap_->mark_compact_collector()->RecordSlot(p, p, obj);
-      MarkObject(obj);
+      heap->mark_compact_collector()->RecordSlot(p, p, obj);
+      MarkObject(heap, obj);
     }
   }
 
-  void VisitPointers(Object** start, Object** end) {
+  INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
     for (Object** p = start; p < end; p++) {
       Object* obj = *p;
       if (obj->NonFailureIsHeapObject()) {
-        heap_->mark_compact_collector()->RecordSlot(start, p, obj);
-        MarkObject(obj);
+        heap->mark_compact_collector()->RecordSlot(start, p, obj);
+        MarkObject(heap, obj);
       }
     }
   }
 
- private:
-  // Mark object pointed to by p.
-  INLINE(void MarkObject(Object* obj)) {
+  INLINE(static void MarkObject(Heap* heap, Object* obj)) {
     HeapObject* heap_object = HeapObject::cast(obj);
     MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
     if (mark_bit.data_only()) {
-      if (incremental_marking_->MarkBlackOrKeepGrey(mark_bit)) {
+      if (heap->incremental_marking()->MarkBlackOrKeepGrey(mark_bit)) {
         MemoryChunk::IncrementLiveBytesFromGC(heap_object->address(),
                                               heap_object->Size());
       }
     } else if (Marking::IsWhite(mark_bit)) {
-      incremental_marking_->WhiteToGreyAndPush(heap_object, mark_bit);
+      heap->incremental_marking()->WhiteToGreyAndPush(heap_object, mark_bit);
     }
   }
-
-  Heap* heap_;
-  IncrementalMarking* incremental_marking_;
 };
 
 
@@ -290,6 +308,11 @@ class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
 };
 
 
+void IncrementalMarking::Initialize() {
+  IncrementalMarkingMarkingVisitor::Initialize();
+}
+
+
 void IncrementalMarking::SetOldSpacePageFlags(MemoryChunk* chunk,
                                               bool is_marking,
                                               bool is_compacting) {
@@ -623,24 +646,6 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
 }
 
 
-void IncrementalMarking::VisitGlobalContext(Context* ctx, ObjectVisitor* v) {
-  v->VisitPointers(
-      HeapObject::RawField(
-          ctx, Context::MarkCompactBodyDescriptor::kStartOffset),
-      HeapObject::RawField(
-          ctx, Context::MarkCompactBodyDescriptor::kEndOffset));
-
-  MarkCompactCollector* collector = heap_->mark_compact_collector();
-  for (int idx = Context::FIRST_WEAK_SLOT;
-       idx < Context::GLOBAL_CONTEXT_SLOTS;
-       ++idx) {
-    Object** slot =
-        HeapObject::RawField(ctx, FixedArray::OffsetOfElementAt(idx));
-    collector->RecordSlot(slot, slot, *slot);
-  }
-}
-
-
 void IncrementalMarking::Hurry() {
   if (state() == MARKING) {
     double start = 0.0;
@@ -652,7 +657,6 @@ void IncrementalMarking::Hurry() {
     // was stopped.
     Map* filler_map = heap_->one_pointer_filler_map();
     Map* global_context_map = heap_->global_context_map();
-    IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
     while (!marking_deque_.IsEmpty()) {
       HeapObject* obj = marking_deque_.Pop();
 
@@ -663,7 +667,7 @@ void IncrementalMarking::Hurry() {
         continue;
       } else if (map == global_context_map) {
         // Global contexts have weak fields.
-        VisitGlobalContext(Context::cast(obj), &marking_visitor);
+        IncrementalMarkingMarkingVisitor::VisitGlobalContext(map, obj);
       } else if (map->instance_type() == MAP_TYPE) {
         Map* map = Map::cast(obj);
         heap_->ClearCacheOnMap(map);
@@ -676,12 +680,17 @@ void IncrementalMarking::Hurry() {
             map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
           marker_.MarkMapContents(map);
         } else {
-          marking_visitor.VisitPointers(
+          IncrementalMarkingMarkingVisitor::VisitPointers(
+              heap_,
               HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
               HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
         }
       } else {
-        obj->Iterate(&marking_visitor);
+        MarkBit map_mark_bit = Marking::MarkBitFrom(map);
+        if (Marking::IsWhite(map_mark_bit)) {
+          WhiteToGreyAndPush(map, map_mark_bit);
+        }
+        IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
       }
 
       MarkBit mark_bit = Marking::MarkBitFrom(obj);
@@ -815,7 +824,6 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
   } else if (state_ == MARKING) {
     Map* filler_map = heap_->one_pointer_filler_map();
     Map* global_context_map = heap_->global_context_map();
-    IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
     while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
       HeapObject* obj = marking_deque_.Pop();
 
@@ -840,7 +848,7 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
         // when we finish marking.
         MarkObjectGreyDoNotEnqueue(ctx->normalized_map_cache());
 
-        VisitGlobalContext(ctx, &marking_visitor);
+        IncrementalMarkingMarkingVisitor::VisitGlobalContext(map, ctx);
       } else if (map->instance_type() == MAP_TYPE) {
         Map* map = Map::cast(obj);
         heap_->ClearCacheOnMap(map);
@@ -853,25 +861,13 @@ void IncrementalMarking::Step(intptr_t allocated_bytes,
             map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
           marker_.MarkMapContents(map);
         } else {
-          marking_visitor.VisitPointers(
+          IncrementalMarkingMarkingVisitor::VisitPointers(
+              heap_,
               HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
               HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
         }
-      } else if (map->instance_type() == JS_FUNCTION_TYPE) {
-        marking_visitor.VisitPointers(
-            HeapObject::RawField(obj, JSFunction::kPropertiesOffset),
-            HeapObject::RawField(obj, JSFunction::kCodeEntryOffset));
-
-        marking_visitor.VisitCodeEntry(
-            obj->address() + JSFunction::kCodeEntryOffset);
-
-        marking_visitor.VisitPointers(
-            HeapObject::RawField(obj,
-                                 JSFunction::kCodeEntryOffset + kPointerSize),
-            HeapObject::RawField(obj,
-                                 JSFunction::kNonWeakFieldsEndOffset));
       } else {
-        obj->IterateBody(map->instance_type(), size, &marking_visitor);
+        IncrementalMarkingMarkingVisitor::IterateBody(map, obj);
       }
 
       MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
index a9c2321..4cb356d 100644 (file)
@@ -53,6 +53,8 @@ class IncrementalMarking {
 
   explicit IncrementalMarking(Heap* heap);
 
+  static void Initialize();
+
   void TearDown();
 
   State state() {
@@ -259,8 +261,6 @@ class IncrementalMarking {
 
   void EnsureMarkingDequeIsCommitted();
 
-  void VisitGlobalContext(Context* ctx, ObjectVisitor* v);
-
   Heap* heap_;
 
   State state_;
index a62196e..6c16f61 100644 (file)
@@ -938,12 +938,9 @@ static inline HeapObject* ShortCircuitConsString(Object** p) {
 }
 
 
-class StaticMarkingVisitor : public StaticVisitorBase {
+class MarkCompactMarkingVisitor
+    : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
  public:
-  static inline void IterateBody(Map* map, HeapObject* obj) {
-    table_.GetVisitor(map)(map, obj);
-  }
-
   static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id,
                                    Map* map, HeapObject* obj);
 
@@ -952,7 +949,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
       FixedArraySubInstanceType fast_type,
       FixedArraySubInstanceType dictionary_type);
 
-  template<StaticMarkingVisitor::VisitorId id>
+  template<MarkCompactMarkingVisitor::VisitorId id>
   class ObjectStatsTracker {
    public:
     static inline void Visit(Map* map, HeapObject* obj);
@@ -977,12 +974,9 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     }
   }
 
-  static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) {
-    ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
-    JSGlobalPropertyCell* cell =
-        JSGlobalPropertyCell::cast(rinfo->target_cell());
-    MarkBit mark = Marking::MarkBitFrom(cell);
-    heap->mark_compact_collector()->MarkObject(cell, mark);
+  INLINE(static void MarkObject(Heap* heap, HeapObject* object)) {
+    MarkBit mark = Marking::MarkBitFrom(object);
+    heap->mark_compact_collector()->MarkObject(object, mark);
   }
 
   static inline void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo) {
@@ -991,8 +985,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     // 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);
+    MarkObject(heap, object);
   }
 
   static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) {
@@ -1005,20 +998,8 @@ class StaticMarkingVisitor : public StaticVisitorBase {
       IC::Clear(rinfo->pc());
       target = Code::GetCodeFromTargetAddress(rinfo->target_address());
     }
-    MarkBit code_mark = Marking::MarkBitFrom(target);
-    heap->mark_compact_collector()->MarkObject(target, code_mark);
-    heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
-  }
-
-  static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) {
-    ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
-            rinfo->IsPatchedReturnSequence()) ||
-           (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
-            rinfo->IsPatchedDebugBreakSlotSequence()));
-    Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
-    MarkBit code_mark = Marking::MarkBitFrom(target);
-    heap->mark_compact_collector()->MarkObject(target, code_mark);
     heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+    MarkObject(heap, target);
   }
 
   // Mark object pointed to by p.
@@ -1073,28 +1054,14 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     return true;
   }
 
-  static inline void VisitExternalReference(Address* p) { }
-  static inline void VisitExternalReference(RelocInfo* rinfo) { }
-  static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
-
- private:
-  class DataObjectVisitor {
-   public:
-    template<int size>
-    static void VisitSpecialized(Map* map, HeapObject* object) {
-    }
-
-    static void Visit(Map* map, HeapObject* object) {
+  static void VisitCode(Map* map, HeapObject* object) {
+    Heap* heap = map->GetHeap();
+    Code* code = reinterpret_cast<Code*>(object);
+    if (FLAG_cleanup_code_caches_at_gc) {
+      code->ClearTypeFeedbackCells(heap);
     }
-  };
-
-  typedef FlexibleBodyVisitor<StaticMarkingVisitor,
-                              JSObject::BodyDescriptor,
-                              void> JSObjectVisitor;
-
-  typedef FlexibleBodyVisitor<StaticMarkingVisitor,
-                              StructBodyDescriptor,
-                              void> StructObjectVisitor;
+    code->CodeIterateBody<MarkCompactMarkingVisitor>(heap);
+  }
 
   static void VisitJSWeakMap(Map* map, HeapObject* object) {
     MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
@@ -1108,12 +1075,12 @@ class StaticMarkingVisitor : public StaticVisitorBase {
 
     // Skip visiting the backing hash table containing the mappings.
     int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
-    BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
+    BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
         map->GetHeap(),
         object,
         JSWeakMap::BodyDescriptor::kStartOffset,
         JSWeakMap::kTableOffset);
-    BodyVisitorBase<StaticMarkingVisitor>::IteratePointers(
+    BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
         map->GetHeap(),
         object,
         JSWeakMap::kTableOffset + kPointerSize,
@@ -1133,14 +1100,9 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     ASSERT(MarkCompactCollector::IsMarked(table->map()));
   }
 
-  static void VisitCode(Map* map, HeapObject* object) {
-    Heap* heap = map->GetHeap();
-    Code* code = reinterpret_cast<Code*>(object);
-    if (FLAG_cleanup_code_caches_at_gc) {
-      code->ClearTypeFeedbackCells(heap);
-    }
-    code->CodeIterateBody<StaticMarkingVisitor>(heap);
-  }
+ private:
+  template<int id>
+  static inline void TrackObjectStatsAndVisit(Map* map, HeapObject* obj);
 
   // Code flushing support.
 
@@ -1255,7 +1217,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
   static void VisitSharedFunctionInfoGeneric(Map* map, HeapObject* object) {
     SharedFunctionInfo::cast(object)->BeforeVisitingPointers();
 
-    FixedBodyVisitor<StaticMarkingVisitor,
+    FixedBodyVisitor<MarkCompactMarkingVisitor,
                      SharedFunctionInfo::BodyDescriptor,
                      void>::Visit(map, object);
   }
@@ -1323,7 +1285,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     Heap* heap = map->GetHeap();
     MarkCompactCollector* collector = heap->mark_compact_collector();
     if (!collector->is_code_flushing_enabled()) {
-      VisitJSRegExpFields(map, object);
+      VisitJSRegExp(map, object);
       return;
     }
     JSRegExp* re = reinterpret_cast<JSRegExp*>(object);
@@ -1331,7 +1293,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
     UpdateRegExpCodeAgeAndFlush(heap, re, true);
     UpdateRegExpCodeAgeAndFlush(heap, re, false);
     // Visit the fields of the RegExp, including the updated FixedArray.
-    VisitJSRegExpFields(map, object);
+    VisitJSRegExp(map, object);
   }
 
 
@@ -1370,29 +1332,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
   }
 
 
-  static void VisitCodeEntry(Heap* heap, Address entry_address) {
-    Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
-    MarkBit mark = Marking::MarkBitFrom(code);
-    heap->mark_compact_collector()->MarkObject(code, mark);
-    heap->mark_compact_collector()->
-        RecordCodeEntrySlot(entry_address, code);
-  }
-
-  static void VisitGlobalContext(Map* map, HeapObject* object) {
-    FixedBodyVisitor<StaticMarkingVisitor,
-                     Context::MarkCompactBodyDescriptor,
-                     void>::Visit(map, object);
-
-    MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
-    for (int idx = Context::FIRST_WEAK_SLOT;
-         idx < Context::GLOBAL_CONTEXT_SLOTS;
-         ++idx) {
-      Object** slot =
-          HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
-      collector->RecordSlot(slot, slot, *slot);
-    }
-  }
-
   static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
     Heap* heap = map->GetHeap();
     MarkCompactCollector* collector = heap->mark_compact_collector();
@@ -1474,15 +1413,6 @@ class StaticMarkingVisitor : public StaticVisitorBase {
                              JSFunction::kNonWeakFieldsEndOffset));
   }
 
-  static inline void VisitJSRegExpFields(Map* map,
-                                         HeapObject* object) {
-    int last_property_offset =
-        JSRegExp::kSize + kPointerSize * map->inobject_properties();
-    VisitPointers(map->GetHeap(),
-                  SLOT_ADDR(object, JSRegExp::kPropertiesOffset),
-                  SLOT_ADDR(object, last_property_offset));
-  }
-
 
   static void VisitSharedFunctionInfoFields(Heap* heap,
                                             HeapObject* object,
@@ -1500,14 +1430,11 @@ class StaticMarkingVisitor : public StaticVisitorBase {
 
   #undef SLOT_ADDR
 
-  typedef void (*Callback)(Map* map, HeapObject* object);
-
-  static VisitorDispatchTable<Callback> table_;
   static VisitorDispatchTable<Callback> non_count_table_;
 };
 
 
-void StaticMarkingVisitor::ObjectStatsCountFixedArray(
+void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray(
     FixedArrayBase* fixed_array,
     FixedArraySubInstanceType fast_type,
     FixedArraySubInstanceType dictionary_type) {
@@ -1528,8 +1455,8 @@ void StaticMarkingVisitor::ObjectStatsCountFixedArray(
 }
 
 
-void StaticMarkingVisitor::ObjectStatsVisitBase(
-    StaticVisitorBase::VisitorId id, Map* map, HeapObject* obj) {
+void MarkCompactMarkingVisitor::ObjectStatsVisitBase(
+    MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) {
   Heap* heap = map->GetHeap();
   int object_size = obj->Size();
   heap->RecordObjectStats(map->instance_type(), -1, object_size);
@@ -1546,16 +1473,16 @@ void StaticMarkingVisitor::ObjectStatsVisitBase(
 }
 
 
-template<StaticMarkingVisitor::VisitorId id>
-void StaticMarkingVisitor::ObjectStatsTracker<id>::Visit(
+template<MarkCompactMarkingVisitor::VisitorId id>
+void MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(
     Map* map, HeapObject* obj) {
   ObjectStatsVisitBase(id, map, obj);
 }
 
 
 template<>
-class StaticMarkingVisitor::ObjectStatsTracker<
-  StaticMarkingVisitor::kVisitMap> {
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+    MarkCompactMarkingVisitor::kVisitMap> {
  public:
   static inline void Visit(Map* map, HeapObject* obj) {
     Heap* heap = map->GetHeap();
@@ -1586,8 +1513,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
 
 
 template<>
-class StaticMarkingVisitor::ObjectStatsTracker<
-  StaticMarkingVisitor::kVisitCode> {
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+    MarkCompactMarkingVisitor::kVisitCode> {
  public:
   static inline void Visit(Map* map, HeapObject* obj) {
     Heap* heap = map->GetHeap();
@@ -1600,8 +1527,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
 
 
 template<>
-class StaticMarkingVisitor::ObjectStatsTracker<
-  StaticMarkingVisitor::kVisitSharedFunctionInfo> {
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+    MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> {
  public:
   static inline void Visit(Map* map, HeapObject* obj) {
     Heap* heap = map->GetHeap();
@@ -1618,8 +1545,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
 
 
 template<>
-class StaticMarkingVisitor::ObjectStatsTracker<
-  StaticMarkingVisitor::kVisitFixedArray> {
+class MarkCompactMarkingVisitor::ObjectStatsTracker<
+    MarkCompactMarkingVisitor::kVisitFixedArray> {
  public:
   static inline void Visit(Map* map, HeapObject* obj) {
     Heap* heap = map->GetHeap();
@@ -1635,48 +1562,8 @@ class StaticMarkingVisitor::ObjectStatsTracker<
 };
 
 
-void StaticMarkingVisitor::Initialize() {
-  table_.Register(kVisitShortcutCandidate,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  ConsString::BodyDescriptor,
-                  void>::Visit);
-
-  table_.Register(kVisitConsString,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  ConsString::BodyDescriptor,
-                  void>::Visit);
-
-  table_.Register(kVisitSlicedString,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  SlicedString::BodyDescriptor,
-                  void>::Visit);
-
-  table_.Register(kVisitFixedArray,
-                  &FlexibleBodyVisitor<StaticMarkingVisitor,
-                  FixedArray::BodyDescriptor,
-                  void>::Visit);
-
-  table_.Register(kVisitGlobalContext, &VisitGlobalContext);
-
-  table_.Register(kVisitFixedDoubleArray, DataObjectVisitor::Visit);
-
-  table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
-  table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
-  table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
-  table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
-
-  table_.Register(kVisitJSWeakMap, &VisitJSWeakMap);
-
-  table_.Register(kVisitOddball,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  Oddball::BodyDescriptor,
-                  void>::Visit);
-  table_.Register(kVisitMap,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  Map::BodyDescriptor,
-                  void>::Visit);
-
-  table_.Register(kVisitCode, &VisitCode);
+void MarkCompactMarkingVisitor::Initialize() {
+  StaticMarkingVisitor<MarkCompactMarkingVisitor>::Initialize();
 
   table_.Register(kVisitSharedFunctionInfo,
                   &VisitSharedFunctionInfoAndFlushCode);
@@ -1687,23 +1574,6 @@ void StaticMarkingVisitor::Initialize() {
   table_.Register(kVisitJSRegExp,
                   &VisitRegExpAndFlushCode);
 
-  table_.Register(kVisitPropertyCell,
-                  &FixedBodyVisitor<StaticMarkingVisitor,
-                  JSGlobalPropertyCell::BodyDescriptor,
-                  void>::Visit);
-
-  table_.RegisterSpecializations<DataObjectVisitor,
-      kVisitDataObject,
-      kVisitDataObjectGeneric>();
-
-  table_.RegisterSpecializations<JSObjectVisitor,
-      kVisitJSObject,
-      kVisitJSObjectGeneric>();
-
-  table_.RegisterSpecializations<StructObjectVisitor,
-      kVisitStruct,
-      kVisitStructGeneric>();
-
   if (FLAG_track_gc_object_stats) {
     // Copy the visitor table to make call-through possible.
     non_count_table_.CopyFrom(&table_);
@@ -1715,10 +1585,8 @@ void StaticMarkingVisitor::Initialize() {
 }
 
 
-VisitorDispatchTable<StaticMarkingVisitor::Callback>
-  StaticMarkingVisitor::table_;
-VisitorDispatchTable<StaticMarkingVisitor::Callback>
-  StaticMarkingVisitor::non_count_table_;
+VisitorDispatchTable<MarkCompactMarkingVisitor::Callback>
+    MarkCompactMarkingVisitor::non_count_table_;
 
 
 class MarkingVisitor : public ObjectVisitor {
@@ -1726,11 +1594,11 @@ class MarkingVisitor : public ObjectVisitor {
   explicit MarkingVisitor(Heap* heap) : heap_(heap) { }
 
   void VisitPointer(Object** p) {
-    StaticMarkingVisitor::VisitPointer(heap_, p);
+    MarkCompactMarkingVisitor::VisitPointer(heap_, p);
   }
 
   void VisitPointers(Object** start, Object** end) {
-    StaticMarkingVisitor::VisitPointers(heap_, start, end);
+    MarkCompactMarkingVisitor::VisitPointers(heap_, start, end);
   }
 
  private:
@@ -1889,7 +1757,7 @@ class RootMarkingVisitor : public ObjectVisitor {
     // Mark the map pointer and body, and push them on the marking stack.
     MarkBit map_mark = Marking::MarkBitFrom(map);
     collector_->MarkObject(map, map_mark);
-    StaticMarkingVisitor::IterateBody(map, object);
+    MarkCompactMarkingVisitor::IterateBody(map, object);
 
     // Mark all the objects reachable from the map and body.  May leave
     // overflowed objects in the heap.
@@ -2342,7 +2210,7 @@ void MarkCompactCollector::EmptyMarkingDeque() {
       MarkBit map_mark = Marking::MarkBitFrom(map);
       MarkObject(map, map_mark);
 
-      StaticMarkingVisitor::IterateBody(map, object);
+      MarkCompactMarkingVisitor::IterateBody(map, object);
     }
 
     // Process encountered weak maps, mark objects only reachable by those
@@ -2481,7 +2349,7 @@ void MarkCompactCollector::MarkLiveObjects() {
         ASSERT(cell->IsJSGlobalPropertyCell());
         if (IsMarked(cell)) {
           int offset = JSGlobalPropertyCell::kValueOffset;
-          StaticMarkingVisitor::VisitPointer(
+          MarkCompactMarkingVisitor::VisitPointer(
               heap(),
               reinterpret_cast<Object**>(cell->address() + offset));
         }
@@ -2740,7 +2608,8 @@ void MarkCompactCollector::ProcessWeakMaps() {
         Object** value_slot =
             HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
                 ObjectHashTable::EntryToValueIndex(i)));
-        StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot);
+        MarkCompactMarkingVisitor::MarkObjectByPointer(
+            this, anchor, value_slot);
       }
     }
     weak_map_obj = weak_map->next();
@@ -4141,7 +4010,8 @@ void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj,
 
 
 void MarkCompactCollector::Initialize() {
-  StaticMarkingVisitor::Initialize();
+  MarkCompactMarkingVisitor::Initialize();
+  IncrementalMarking::Initialize();
 }
 
 
index ed3def5..b94355b 100644 (file)
@@ -636,7 +636,7 @@ class MarkCompactCollector {
 
   friend class RootMarkingVisitor;
   friend class MarkingVisitor;
-  friend class StaticMarkingVisitor;
+  friend class MarkCompactMarkingVisitor;
   friend class CodeMarkingVisitor;
   friend class SharedFunctionInfoMarkingVisitor;
   friend class Marker<IncrementalMarking>;
index 8ba92f7..30a7ad4 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -93,6 +93,139 @@ void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
 }
 
 
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::Initialize() {
+  table_.Register(kVisitShortcutCandidate,
+                  &FixedBodyVisitor<StaticVisitor,
+                  ConsString::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitConsString,
+                  &FixedBodyVisitor<StaticVisitor,
+                  ConsString::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitSlicedString,
+                  &FixedBodyVisitor<StaticVisitor,
+                  SlicedString::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitFixedArray,
+                  &FlexibleBodyVisitor<StaticVisitor,
+                  FixedArray::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
+
+  table_.Register(kVisitGlobalContext, &VisitGlobalContext);
+
+  table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
+
+  table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
+
+  table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
+
+  table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
+
+  table_.Register(kVisitJSWeakMap, &StaticVisitor::VisitJSWeakMap);
+
+  table_.Register(kVisitOddball,
+                  &FixedBodyVisitor<StaticVisitor,
+                  Oddball::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitMap,
+                  &FixedBodyVisitor<StaticVisitor,
+                  Map::BodyDescriptor,
+                  void>::Visit);
+
+  table_.Register(kVisitCode, &StaticVisitor::VisitCode);
+
+  // Registration for kVisitSharedFunctionInfo is done by StaticVisitor.
+
+  // Registration for kVisitJSFunction is done by StaticVisitor.
+
+  // Registration for kVisitJSRegExp is done by StaticVisitor.
+
+  table_.Register(kVisitPropertyCell,
+                  &FixedBodyVisitor<StaticVisitor,
+                  JSGlobalPropertyCell::BodyDescriptor,
+                  void>::Visit);
+
+  table_.template RegisterSpecializations<DataObjectVisitor,
+                                          kVisitDataObject,
+                                          kVisitDataObjectGeneric>();
+
+  table_.template RegisterSpecializations<JSObjectVisitor,
+                                          kVisitJSObject,
+                                          kVisitJSObjectGeneric>();
+
+  table_.template RegisterSpecializations<StructObjectVisitor,
+                                          kVisitStruct,
+                                          kVisitStructGeneric>();
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
+    Heap* heap, Address entry_address) {
+  Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
+  heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code);
+  StaticVisitor::MarkObject(heap, code);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitGlobalPropertyCell(
+    Heap* heap, RelocInfo* rinfo) {
+  ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
+  JSGlobalPropertyCell* cell = rinfo->target_cell();
+  StaticVisitor::MarkObject(heap, cell);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(
+    Heap* heap, RelocInfo* rinfo) {
+  ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
+          rinfo->IsPatchedReturnSequence()) ||
+         (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
+          rinfo->IsPatchedDebugBreakSlotSequence()));
+  Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
+  heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
+  StaticVisitor::MarkObject(heap, target);
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitGlobalContext(
+    Map* map, HeapObject* object) {
+  FixedBodyVisitor<StaticVisitor,
+                   Context::MarkCompactBodyDescriptor,
+                   void>::Visit(map, object);
+
+  MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
+  for (int idx = Context::FIRST_WEAK_SLOT;
+       idx < Context::GLOBAL_CONTEXT_SLOTS;
+       ++idx) {
+    Object** slot =
+        HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
+    collector->RecordSlot(slot, slot, *slot);
+  }
+}
+
+
+template<typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
+    Map* map, HeapObject* object) {
+  int last_property_offset =
+      JSRegExp::kSize + kPointerSize * map->inobject_properties();
+  StaticVisitor::VisitPointers(map->GetHeap(),
+      HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
+      HeapObject::RawField(object, last_property_offset));
+}
+
+
 void Code::CodeIterateBody(ObjectVisitor* v) {
   int mode_mask = RelocInfo::kCodeTargetMask |
                   RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
index a84c512..7415101 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -360,7 +360,71 @@ class StaticNewSpaceVisitor : public StaticVisitorBase {
 
 template<typename StaticVisitor>
 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
-  StaticNewSpaceVisitor<StaticVisitor>::table_;
+    StaticNewSpaceVisitor<StaticVisitor>::table_;
+
+
+// Base class for visitors used to transitively mark the entire heap.
+// IterateBody returns nothing.
+// Certain types of objects might not be handled by this base class and
+// no visitor function is registered by the generic initialization. A
+// specialized visitor function needs to be provided by the inheriting
+// class itself for those cases.
+//
+// This class is intended to be used in the following way:
+//
+//   class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> {
+//     ...
+//   }
+//
+// This is an example of Curiously recurring template pattern.
+template<typename StaticVisitor>
+class StaticMarkingVisitor : public StaticVisitorBase {
+ public:
+  static void Initialize();
+
+  static inline void IterateBody(Map* map, HeapObject* obj) {
+    table_.GetVisitor(map)(map, obj);
+  }
+
+  static inline void VisitCodeEntry(Heap* heap, Address entry_address);
+  static inline void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo);
+  static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo);
+  static inline void VisitExternalReference(RelocInfo* rinfo) { }
+  static inline void VisitRuntimeEntry(RelocInfo* rinfo) { }
+
+  // TODO(mstarzinger): This should be made protected once refactoring is done.
+  static inline void VisitGlobalContext(Map* map, HeapObject* object);
+
+ protected:
+  static inline void VisitJSRegExp(Map* map, HeapObject* object);
+
+  class DataObjectVisitor {
+   public:
+    template<int size>
+    static inline void VisitSpecialized(Map* map, HeapObject* object) {
+    }
+
+    static inline void Visit(Map* map, HeapObject* object) {
+    }
+  };
+
+  typedef FlexibleBodyVisitor<StaticVisitor,
+                              JSObject::BodyDescriptor,
+                              void> JSObjectVisitor;
+
+  typedef FlexibleBodyVisitor<StaticVisitor,
+                              StructBodyDescriptor,
+                              void> StructObjectVisitor;
+
+  typedef void (*Callback)(Map* map, HeapObject* object);
+
+  static VisitorDispatchTable<Callback> table_;
+};
+
+
+template<typename StaticVisitor>
+VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
+    StaticMarkingVisitor<StaticVisitor>::table_;
 
 
 } }  // namespace v8::internal
index 67ff486..4905c04 100644 (file)
@@ -1398,8 +1398,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
     case EXTERNAL_DOUBLE_ARRAY_TYPE:
       break;
     case SHARED_FUNCTION_INFO_TYPE: {
-      SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(this);
-      shared->SharedFunctionInfoIterateBody(v);
+      SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
       break;
     }
 
@@ -7996,12 +7995,6 @@ int SharedFunctionInfo::SearchOptimizedCodeMap(Context* global_context) {
 }
 
 
-void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
-  v->VisitSharedFunctionInfo(this);
-  SharedFunctionInfo::BodyDescriptor::IterateBody(this, v);
-}
-
-
 #define DECLARE_TAG(ignore1, name, ignore2) name,
 const char* const VisitorSynchronization::kTags[
     VisitorSynchronization::kNumberOfSyncTags] = {
index 3694955..fa33b81 100644 (file)
@@ -5724,8 +5724,6 @@ class SharedFunctionInfo: public HeapObject {
   static bool CompileLazy(Handle<SharedFunctionInfo> shared,
                           ClearExceptionFlag flag);
 
-  void SharedFunctionInfoIterateBody(ObjectVisitor* v);
-
   // Casting.
   static inline SharedFunctionInfo* cast(Object* obj);
 
@@ -8853,8 +8851,6 @@ class ObjectVisitor BASE_EMBEDDED {
   // Visit pointer embedded into a code object.
   virtual void VisitEmbeddedPointer(RelocInfo* rinfo);
 
-  virtual void VisitSharedFunctionInfo(SharedFunctionInfo* shared) {}
-
   // 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.