if (lo_space()->Contains(object)) return false;
- // We cannot move the object start if the given old space page is
- // concurrently swept.
+ Page* page = Page::FromAddress(address);
+ // We can move the object start if:
+ // (1) the object is not in old pointer or old data space,
+ // (2) the page of the object was already swept,
+ // (3) the page was already concurrently swept. This case is an optimization
+ // for concurrent sweeping. The WasSwept predicate for concurrently swept
+ // pages is set after sweeping all pages.
return (!is_in_old_pointer_space && !is_in_old_data_space) ||
- Page::FromAddress(address)->parallel_sweeping() <=
- MemoryChunk::PARALLEL_SWEEPING_FINALIZE;
+ page->WasSwept() ||
+ (mark_compact_collector()->AreSweeperThreadsActivated() &&
+ page->parallel_sweeping() <=
+ MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
}
"f()()");
CHECK_EQ(42.0, result->ToNumber()->Value());
}
+
+
+TEST(ArrayShiftLazySweeping) {
+ i::FLAG_expose_gc = true;
+ i::FLAG_parallel_sweeping = false;
+ i::FLAG_concurrent_sweeping = false;
+ i::FLAG_lazy_sweeping = true;
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+
+ v8::Local<v8::Value> result = CompileRun(
+ "var array = new Array(40000);"
+ "var tmp = new Array(100000);"
+ "gc();"
+ "array.shift();"
+ "array;");
+
+ Handle<JSObject> o =
+ v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
+ CHECK(heap->InOldPointerSpace(o->elements()));
+ CHECK(heap->InOldPointerSpace(*o));
+ Page* page = Page::FromAddress(o->elements()->address());
+ CHECK(page->WasSwept() ||
+ Marking::IsBlack(Marking::MarkBitFrom(o->elements())));
+}