Reviewers: Vyacheslav Egorov,

Description:
Fix WeakMap processing for evacuation candidates (2).

This fixes processing of WeakMaps so that keys on evacuation candidates
which are also reachable by other strong paths are correctly recorded in
the slots buffer.

Also backing stores that reside in the large-object-space now use the
correct anchor slot.

[email protected]
BUG=v8:2060
TEST=cctest/test-weakmaps/Regress2060b


Please review this at https://chromiumcodereview.appspot.com/10034018/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/mark-compact.cc
  M test/cctest/test-weakmaps.cc


Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index fb5a7e7caef741e1c2fd1bd51c4a95662ba32417..346b9a1c0d8986bb701255f0babbbaa93466bb82 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2592,12 +2592,17 @@ void MarkCompactCollector::ProcessWeakMaps() {
     ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
     JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
     ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
+    Object** anchor = reinterpret_cast<Object**>(table->address());
     for (int i = 0; i < table->Capacity(); i++) {
if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
-        int idx = ObjectHashTable::EntryToValueIndex(i);
-        Object** slot =
- HeapObject::RawField(table, FixedArray::OffsetOfElementAt(idx));
-        StaticMarkingVisitor::VisitPointer(heap(), slot);
+        Object** key_slot =
+            HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
+                ObjectHashTable::EntryToIndex(i)));
+        RecordSlot(anchor, key_slot, *key_slot);
+        Object** value_slot =
+            HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
+                ObjectHashTable::EntryToValueIndex(i)));
+ StaticMarkingVisitor::MarkObjectByPointer(this, anchor, value_slot);
       }
     }
     weak_map_obj = weak_map->next();
Index: test/cctest/test-weakmaps.cc
diff --git a/test/cctest/test-weakmaps.cc b/test/cctest/test-weakmaps.cc
index d12b9c7628aba2ed01ca541964116bcb64da5c8e..9f5ef9543dc3214b4f66c9a5eb0d62807e5ecec7 100644
--- a/test/cctest/test-weakmaps.cc
+++ b/test/cctest/test-weakmaps.cc
@@ -158,7 +158,7 @@ TEST(Shrinking) {

// Test that weak map values on an evacuation candidate which are not reachable
 // by other paths are correctly recorded in the slots buffer.
-TEST(Regress2060) {
+TEST(Regress2060a) {
   FLAG_always_compact = true;
   LocalContext context;
   v8::HandleScope scope;
@@ -186,3 +186,38 @@ TEST(Regress2060) {
   CHECK(FLAG_always_compact);
   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 }
+
+
+// Test that weak map keys on an evacuation candidate which are reachable by
+// other strong paths are correctly recorded in the slots buffer.
+TEST(Regress2060b) {
+  FLAG_always_compact = true;
+  FLAG_verify_heap = true;
+  LocalContext context;
+  v8::HandleScope scope;
+  Handle<JSFunction> function =
+ FACTORY->NewFunction(FACTORY->function_symbol(), FACTORY->null_value());
+
+  // Start second old-space page so that keys land on evacuation candidate.
+  Page* first_page = HEAP->old_pointer_space()->anchor()->next_page();
+  FACTORY->NewFixedArray(900 * KB / kPointerSize, TENURED);
+
+  // Fill up weak map with keys on an evacuation candidate.
+  Handle<JSObject> keys[32];
+  for (int i = 0; i < 32; i++) {
+    keys[i] = FACTORY->NewJSObject(function, TENURED);
+    CHECK(!HEAP->InNewSpace(keys[i]->address()));
+    CHECK(!first_page->Contains(keys[i]->address()));
+  }
+  Handle<JSWeakMap> weakmap = AllocateJSWeakMap();
+  for (int i = 0; i < 32; i++) {
+    PutIntoWeakMap(weakmap, keys[i], Handle<Smi>(Smi::FromInt(i)));
+  }
+
+ // Force compacting garbage collection. The subsequent collections are used
+  // to verify that key references were actually updated.
+  CHECK(FLAG_always_compact);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+}


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to