| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index d359d3654af40969d09bd890dbb79099549621d3..d2d0ca2d2f0cf736502b5aac3474f7ae2b5a5658 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -4293,14 +4293,47 @@ void Heap::NotifyObjectLayoutChange(HeapObject* object,
|
| }
|
|
|
| #ifdef VERIFY_HEAP
|
| +// Helper class for collecting slot addresses.
|
| +class SlotCollectingVisitor final : public ObjectVisitor {
|
| + public:
|
| + void VisitPointers(HeapObject* host, Object** start, Object** end) override {
|
| + for (Object** p = start; p < end; p++) {
|
| + slots_.push_back(p);
|
| + }
|
| + }
|
| +
|
| + int number_of_slots() { return static_cast<int>(slots_.size()); }
|
| +
|
| + Object** slot(int i) { return slots_[i]; }
|
| +
|
| + private:
|
| + std::vector<Object**> slots_;
|
| +};
|
| +
|
| void Heap::VerifyObjectLayoutChange(HeapObject* object, Map* new_map) {
|
| // Check that Heap::NotifyObjectLayout was called for object transitions
|
| // that are not safe for concurrent marking.
|
| // If you see this check triggering for a freshly allocated object,
|
| // use object->set_map_after_allocation() to initialize its map.
|
| if (pending_layout_change_object_ == nullptr) {
|
| - DCHECK(!object->IsJSObject() ||
|
| - !object->map()->TransitionRequiresSynchronizationWithGC(new_map));
|
| + if (object->IsJSObject()) {
|
| + DCHECK(!object->map()->TransitionRequiresSynchronizationWithGC(new_map));
|
| + } else {
|
| + // Check that the set of slots before and after the transition match.
|
| + SlotCollectingVisitor old_visitor;
|
| + object->IterateFast(&old_visitor);
|
| + MapWord old_map_word = object->map_word();
|
| + // Temporarily set the new map to iterate new slots.
|
| + object->set_map_word(MapWord::FromMap(new_map));
|
| + SlotCollectingVisitor new_visitor;
|
| + object->IterateFast(&new_visitor);
|
| + // Restore the old map.
|
| + object->set_map_word(old_map_word);
|
| + DCHECK_EQ(new_visitor.number_of_slots(), old_visitor.number_of_slots());
|
| + for (int i = 0; i < new_visitor.number_of_slots(); i++) {
|
| + DCHECK_EQ(new_visitor.slot(i), old_visitor.slot(i));
|
| + }
|
| + }
|
| } else {
|
| DCHECK_EQ(pending_layout_change_object_, object);
|
| pending_layout_change_object_ = nullptr;
|
|
|