| 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 {
|
|
|