Revision: 11385
Author: [email protected]
Date: Thu Apr 19 03:32:38 2012
Log: Fix issues when stressing compaction with WeakMaps.
1) While marking the backing hash table of a WeakMap we also need to
record the slot because it might be on an evacuation candidate.
2) With incremental marking one backing hash table might be marked more
than once because the WeakMap might have gone through a white to gray
transition.
3) The corner case when the allocation of the backing hash table itself
causes a GC, leads to a WeakMap with an undefined table field, so we
still need to handle this case correctly.
[email protected]
TEST=mjsunit/harmony/proxies-example-membrane --stress-compaction
Review URL: https://chromiumcodereview.appspot.com/9985010
http://code.google.com/p/v8/source/detail?r=11385
Modified:
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/test/cctest/test-weakmaps.cc
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Tue Apr 17 03:37:41 2012
+++ /branches/bleeding_edge/src/mark-compact.cc Thu Apr 19 03:32:38 2012
@@ -1152,9 +1152,10 @@
JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(object);
// Enqueue weak map in linked list of encountered weak maps.
- ASSERT(weak_map->next() == Smi::FromInt(0));
- weak_map->set_next(collector->encountered_weak_maps());
- collector->set_encountered_weak_maps(weak_map);
+ if (weak_map->next() == Smi::FromInt(0)) {
+ weak_map->set_next(collector->encountered_weak_maps());
+ collector->set_encountered_weak_maps(weak_map);
+ }
// Skip visiting the backing hash table containing the mappings.
int object_size = JSWeakMap::BodyDescriptor::SizeOf(map, object);
@@ -1170,9 +1171,15 @@
object_size);
// Mark the backing hash table without pushing it on the marking stack.
- ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
- ASSERT(!MarkCompactCollector::IsMarked(table));
- collector->SetMark(table, Marking::MarkBitFrom(table));
+ Object* table_object = weak_map->table();
+ if (!table_object->IsHashTable()) return;
+ ObjectHashTable* table = ObjectHashTable::cast(table_object);
+ Object** table_slot =
+ HeapObject::RawField(weak_map, JSWeakMap::kTableOffset);
+ MarkBit table_mark = Marking::MarkBitFrom(table);
+ collector->RecordSlot(table_slot, table_slot, table);
+ if (!table_mark.Get()) collector->SetMark(table, table_mark);
+ // Recording the map slot can be skipped, because maps are not
compacted.
collector->MarkObject(table->map(),
Marking::MarkBitFrom(table->map()));
ASSERT(MarkCompactCollector::IsMarked(table->map()));
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-weakmaps.cc Wed Apr 11
08:47:46 2012
+++ /branches/bleeding_edge/test/cctest/test-weakmaps.cc Thu Apr 19
03:32:38 2012
@@ -65,6 +65,7 @@
TEST(Weakness) {
+ FLAG_incremental_marking = false;
LocalContext context;
v8::HandleScope scope;
Handle<JSWeakMap> weakmap = AllocateJSWeakMap();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev