Revision: 11279
Author: [email protected]
Date: Wed Apr 11 08:32:31 2012
Log: 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
Review URL: https://chromiumcodereview.appspot.com/10034018
http://code.google.com/p/v8/source/detail?r=11279
Modified:
/branches/bleeding_edge/src/mark-compact.cc
/branches/bleeding_edge/test/cctest/test-weakmaps.cc
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Wed Apr 11 02:14:29 2012
+++ /branches/bleeding_edge/src/mark-compact.cc Wed Apr 11 08:32:31 2012
@@ -2592,12 +2592,17 @@
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();
=======================================
--- /branches/bleeding_edge/test/cctest/test-weakmaps.cc Wed Apr 11
02:14:29 2012
+++ /branches/bleeding_edge/test/cctest/test-weakmaps.cc Wed Apr 11
08:32:31 2012
@@ -158,7 +158,7 @@
// 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 @@
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