Index: src/heap/concurrent-marking.cc |
diff --git a/src/heap/concurrent-marking.cc b/src/heap/concurrent-marking.cc |
index 099715759a7e91e5886af2b923e2a55b23a6eda2..32afac63f3eae03b5e351ef33d9009e79372b0fb 100644 |
--- a/src/heap/concurrent-marking.cc |
+++ b/src/heap/concurrent-marking.cc |
@@ -22,6 +22,27 @@ |
namespace v8 { |
namespace internal { |
+// Helper class for storing in-object slot addresses and values. |
+class SlotSnapshot { |
+ public: |
+ SlotSnapshot() : number_of_slots_(0) {} |
+ int number_of_slots() const { return number_of_slots_; } |
+ Object** slot(int i) const { return snapshot_[i].first; } |
+ Object* value(int i) const { return snapshot_[i].second; } |
+ void clear() { number_of_slots_ = 0; } |
+ void add(Object** slot, Object* value) { |
+ snapshot_[number_of_slots_].first = slot; |
+ snapshot_[number_of_slots_].second = value; |
+ ++number_of_slots_; |
+ } |
+ |
+ private: |
+ static const int kMaxSnapshotSize = JSObject::kMaxInstanceSize / kPointerSize; |
+ int number_of_slots_; |
+ std::pair<Object**, Object*> snapshot_[kMaxSnapshotSize]; |
+ DISALLOW_COPY_AND_ASSIGN(SlotSnapshot); |
+}; |
+ |
class ConcurrentMarkingVisitor final |
: public HeapVisitor<int, ConcurrentMarkingVisitor> { |
public: |
@@ -44,13 +65,24 @@ class ConcurrentMarkingVisitor final |
} |
} |
+ void VisitPointersInSnapshot(const SlotSnapshot& snapshot) { |
+ for (int i = 0; i < snapshot.number_of_slots(); i++) { |
+ Object* object = snapshot.value(i); |
+ if (!object->IsHeapObject()) continue; |
+ MarkObject(HeapObject::cast(object)); |
+ } |
+ } |
+ |
// =========================================================================== |
// JS object ================================================================= |
// =========================================================================== |
int VisitJSObject(Map* map, JSObject* object) override { |
- // TODO(ulan): impement snapshot iteration. |
- return BaseClass::VisitJSObject(map, object); |
+ int size = JSObject::BodyDescriptor::SizeOf(map, object); |
+ const SlotSnapshot& snapshot = MakeSlotSnapshot(map, object, size); |
+ if (!ShouldVisit(object)) return 0; |
+ VisitPointersInSnapshot(snapshot); |
+ return size; |
} |
int VisitJSObjectFast(Map* map, JSObject* object) override { |
@@ -139,11 +171,41 @@ class ConcurrentMarkingVisitor final |
} |
private: |
+ // Helper class for collecting in-object slot addresses and values. |
+ class SlotSnapshottingVisitor final : public ObjectVisitor { |
+ public: |
+ explicit SlotSnapshottingVisitor(SlotSnapshot* slot_snapshot) |
+ : slot_snapshot_(slot_snapshot) { |
+ slot_snapshot_->clear(); |
+ } |
+ |
+ void VisitPointers(HeapObject* host, Object** start, |
+ Object** end) override { |
+ for (Object** p = start; p < end; p++) { |
+ Object* object = reinterpret_cast<Object*>( |
+ base::NoBarrier_Load(reinterpret_cast<const base::AtomicWord*>(p))); |
+ slot_snapshot_->add(p, object); |
+ } |
+ } |
+ |
+ private: |
+ SlotSnapshot* slot_snapshot_; |
+ }; |
+ |
+ const SlotSnapshot& MakeSlotSnapshot(Map* map, HeapObject* object, int size) { |
+ SlotSnapshottingVisitor visitor(&slot_snapshot_); |
+ visitor.VisitPointer(object, |
+ reinterpret_cast<Object**>(object->map_slot())); |
+ JSObject::BodyDescriptor::IterateBody(object, size, &visitor); |
+ return slot_snapshot_; |
+ } |
+ |
MarkingState marking_state(HeapObject* object) const { |
return MarkingState::Internal(object); |
} |
ConcurrentMarkingDeque* deque_; |
+ SlotSnapshot slot_snapshot_; |
}; |
class ConcurrentMarking::Task : public CancelableTask { |