diff --git a/src/objects-debug.cc b/src/objects-debug.cc index 3bfb74d6a4..9006abde1b 100644 --- a/src/objects-debug.cc +++ b/src/objects-debug.cc @@ -992,6 +992,28 @@ void NormalizedMapCache::NormalizedMapCacheVerify() { } +void Map::ZapInstanceDescriptors() { + DescriptorArray* descriptors = instance_descriptors(); + if (descriptors == GetHeap()->empty_descriptor_array()) return; + FixedArray* contents = FixedArray::cast( + descriptors->get(DescriptorArray::kContentArrayIndex)); + MemsetPointer(descriptors->data_start(), + GetHeap()->the_hole_value(), + descriptors->length()); + MemsetPointer(contents->data_start(), + GetHeap()->the_hole_value(), + contents->length()); +} + + +void Map::ZapPrototypeTransitions() { + FixedArray* proto_transitions = prototype_transitions(); + MemsetPointer(proto_transitions->data_start(), + GetHeap()->the_hole_value(), + proto_transitions->length()); +} + + #endif // DEBUG } } // namespace v8::internal diff --git a/src/objects-inl.h b/src/objects-inl.h index eb1586ad0c..544443866e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -3351,6 +3351,9 @@ void Map::clear_instance_descriptors() { Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); if (!object->IsSmi()) { +#ifdef DEBUG + ZapInstanceDescriptors(); +#endif WRITE_FIELD( this, kInstanceDescriptorsOrBitField3Offset, @@ -3376,6 +3379,11 @@ void Map::set_instance_descriptors(DescriptorArray* value, } } ASSERT(!is_shared()); +#ifdef DEBUG + if (value != instance_descriptors()) { + ZapInstanceDescriptors(); + } +#endif WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); CONDITIONAL_WRITE_BARRIER( heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); @@ -3448,6 +3456,11 @@ void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) { Heap* heap = GetHeap(); ASSERT(value != heap->empty_fixed_array()); value->set(kProtoTransitionBackPointerOffset, GetBackPointer()); +#ifdef DEBUG + if (value != prototype_transitions()) { + ZapPrototypeTransitions(); + } +#endif WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value); CONDITIONAL_WRITE_BARRIER( heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode); diff --git a/src/objects.h b/src/objects.h index 22993f2568..358af4a9d4 100644 --- a/src/objects.h +++ b/src/objects.h @@ -4855,6 +4855,14 @@ class Map: public HeapObject { Handle FindTransitionedMap(MapHandleList* candidates); Map* FindTransitionedMap(MapList* candidates); + // Zaps the contents of backing data structures in debug mode. Note that the + // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects + // holding weak references when incremental marking is used, because it also + // iterates over objects that are otherwise unreachable. +#ifdef DEBUG + void ZapInstanceDescriptors(); + void ZapPrototypeTransitions(); +#endif // Dispatched behavior. #ifdef OBJECT_PRINT