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

Reply via email to