Reviewers: ulan,
Description:
Add zapping of Map contents in debug mode.
This zaps the contents of stale descriptor arrays and prototype
transition arrays before overwriting references to them. It should help
to discover accidental sharing early and is needed for the heap verifier
when map collection with incremental marking lands.
[email protected]
BUG=v8:1465
Please review this at https://chromiumcodereview.appspot.com/10383186/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/objects-debug.cc
M src/objects-inl.h
M src/objects.h
Index: src/objects-debug.cc
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index
3bfb74d6a494e8a1a60d9cba10fe461a5c95e22d..9006abde1b88114f9ab57f8554993d5b042f2bf4
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
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
eb1586ad0c2802b63cff7a299f3ae87c0297268d..544443866efc52a82fdb20f9b84db8540c1334fb
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);
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
22993f25689011328c0fb2ced90bad4ba57d1689..808cf4dd07c34c5cbfc88d5a8aafeff8fa850ec9
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4855,6 +4855,13 @@ class Map: public HeapObject {
Handle<Map> 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.
+#ifdef DEBUG
+ void ZapInstanceDescriptors();
+ void ZapPrototypeTransitions();
+#endif
// Dispatched behavior.
#ifdef OBJECT_PRINT
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev