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.

R=vegorov@chromium.org
BUG=v8:2060
TEST=cctest/test-weakmaps/Regress2060b

Review URL: https://chromiumcodereview.appspot.com/10034018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11279 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8bdbfc02
......@@ -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();
......
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment