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