Fix map modification in transition tree traversal.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 30 Sep 2011 13:03:48 +0000 (13:03 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 30 Sep 2011 13:03:48 +0000 (13:03 +0000)
While traversing the transition tree we build a work-list using the map
field of maps. Setting those map values with a write barrier causes
black-to-gray changes on maps which are currently not recognized as
such, hence their computed size might be off.

R=vegorov@chromium.org
BUG=v8:1672
TEST=cctest/test-decls/Present

Review URL: http://codereview.chromium.org/8082023

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9498 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects-inl.h
src/objects.cc
src/objects.h

index cc70bfa..3b236d2 100644 (file)
@@ -1239,6 +1239,12 @@ void HeapObject::set_map(Map* value) {
 }
 
 
+// Unsafe accessor omitting write barrier.
+void HeapObject::set_map_unsafe(Map* value) {
+  set_map_word(MapWord::FromMap(value));
+}
+
+
 MapWord HeapObject::map_word() {
   return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
 }
index aa0b6f2..45ae49d 100644 (file)
@@ -4474,7 +4474,7 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
           // of the next map and recording the index in the transition array in
           // the map field of the array.
           Map* next = Map::cast(contents->get(i));
-          next->set_map(current);
+          next->set_map_unsafe(current);
           *map_or_index_field = Smi::FromInt(i + 2);
           current = next;
           map_done = false;
@@ -4499,7 +4499,7 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
       Object* perhaps_map = prototype_transitions->get(i);
       if (perhaps_map->IsMap()) {
         Map* next = Map::cast(perhaps_map);
-        next->set_map(current);
+        next->set_map_unsafe(current);
         *proto_map_or_index_field =
             Smi::FromInt(i + kProtoTransitionElementsPerEntry);
         current = next;
@@ -4515,7 +4515,7 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
     // the map field, which is being used to track the traversal and put the
     // correct map (the meta_map) in place while we do the callback.
     Map* prev = current->map();
-    current->set_map(meta_map);
+    current->set_map_unsafe(meta_map);
     callback(current, data);
     current = prev;
   }
index ad6deed..39c1af0 100644 (file)
@@ -1127,6 +1127,7 @@ class HeapObject: public Object {
   // information.
   inline Map* map();
   inline void set_map(Map* value);
+  inline void set_map_unsafe(Map* value);
 
   // During garbage collection, the map word of a heap object does not
   // necessarily contain a map pointer.