Fix map modification in transition tree traversal.

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
parent f274c94e
......@@ -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)));
}
......
......@@ -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;
}
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment