Don't move the object start of objects on non-swept pages.
authorhpayer@chromium.org <hpayer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 24 Apr 2014 09:04:12 +0000 (09:04 +0000)
committerhpayer@chromium.org <hpayer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 24 Apr 2014 09:04:12 +0000 (09:04 +0000)
BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/255603002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20929 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/heap.cc
test/cctest/test-heap.cc

index 7f23886..a1070fa 100644 (file)
@@ -3426,11 +3426,18 @@ bool Heap::CanMoveObjectStart(HeapObject* object) {
 
   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);
 }
 
 
index dfb4105..0b0c704 100644 (file)
@@ -4197,3 +4197,30 @@ TEST(Regress357137) {
       "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())));
+}