Reviewers: Michael Starzinger,

Description:
Don' left-trim arrays when concurrent sweeping is active.

BUG=

Please review this at https://codereview.chromium.org/207613004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+39, -4 lines):
  M src/builtins.cc
  M src/mark-compact.h
  M src/mark-compact.cc
  M src/spaces.h


Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index b48de7f2cd52378eb5e706e1951fba1031192c4f..79b3f3bf38bfc813a42f992fc72c8b348887a7b1 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -610,7 +610,7 @@ BUILTIN(ArrayShift) {
     first = heap->undefined_value();
   }

-  if (!heap->lo_space()->Contains(elms_obj)) {
+  if (!heap->mark_compact_collector()->CanMoveObjectStart(elms_obj)) {
     array->set_elements(LeftTrimFixedArray(heap, elms_obj, 1));
   } else {
     // Shift the elements.
@@ -950,8 +950,23 @@ BUILTIN(ArraySplice) {
         heap->MoveElements(elms, delta, 0, actual_start);
       }

-      elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);
-
+      if (heap->mark_compact_collector()->CanMoveObjectStart(elms_obj)) {
+        // On the fast path we move the start of the object in memory.
+        elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);
+      } else {
+ // This is the slow path. We are going to move the elemetns to the left
+        // by copying them. For trimmed values we store the hole.
+        if (elms_obj->IsFixedDoubleArray()) {
+          FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
+          MoveDoubleElements(elms, 0, elms, delta, len - delta);
+          FillWithHoles(elms, len - delta, len);
+        } else {
+          FixedArray* elms = FixedArray::cast(elms_obj);
+          DisallowHeapAllocation no_gc;
+          heap->MoveElements(elms, 0, delta, len - delta);
+          FillWithHoles(heap, elms, len - delta, len);
+        }
+      }
       elms_changed = true;
     } else {
       if (elms_obj->IsFixedDoubleArray()) {
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index b26ca6a016af2588fa700f74966064c82c6ee859..2338095d8d059f1bfb03343d1ec17d7401bf75f1 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -664,6 +664,21 @@ bool MarkCompactCollector::IsConcurrentSweepingInProgress() {
 }


+bool MarkCompactCollector::CanMoveObjectStart(HeapObject* object) {
+  Address address = object->address();
+  bool is_in_old_pointer_space = heap_->InOldPointerSpace(address);
+  bool is_in_old_data_space = heap_->InOldDataSpace(address);
+
+  if (heap_->lo_space()->Contains(object)) return false;
+
+  // We cannot move the object start if the given old space page is
+  // concurrently swept.
+  return (!is_in_old_pointer_space && !is_in_old_data_space) ||
+      Page::FromAddress(address)->parallel_sweeping() <=
+          MemoryChunk::PARALLEL_SWEEPING_FINALIZE;
+  }
+
+
 void Marking::TransferMark(Address old_start, Address new_start) {
   // This is only used when resizing an object.
   ASSERT(MemoryChunk::FromAddress(old_start) ==
@@ -4086,6 +4101,7 @@ void MarkCompactCollector::SweepInParallel(PagedSpace* space) {
     if (p->TryParallelSweeping()) {
       SweepConservatively<SWEEP_IN_PARALLEL>(space, &private_free_list, p);
       free_list->Concatenate(&private_free_list);
+      p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
     }
   }
 }
@@ -4284,10 +4300,11 @@ void MarkCompactCollector::ParallelSweepSpaceComplete(PagedSpace* space) {
   PageIterator it(space);
   while (it.has_next()) {
     Page* p = it.next();
- if (p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_IN_PROGRESS) { + if (p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_FINALIZE) {
       p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_DONE);
       p->MarkSweptConservatively();
     }
+    ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
   }
 }

Index: src/mark-compact.h
diff --git a/src/mark-compact.h b/src/mark-compact.h
index 0ebe8a0f747846193bfd0002cccd8bec247df4a0..165eab88dcb99c1c1c35dcd3f8702be7e3e3a627 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -738,6 +738,8 @@ class MarkCompactCollector {
     return sequential_sweeping_;
   }

+  bool CanMoveObjectStart(HeapObject* object);
+
// Mark the global table which maps weak objects to dependent code without
   // marking its contents.
   void MarkWeakObjectToCodeTable();
Index: src/spaces.h
diff --git a/src/spaces.h b/src/spaces.h
index 770b88a9fba85e8ae8c37bee3880a63cf56a6f84..71a7a2b934862edcba7c7c9e0b06b36b8dc312d1 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -475,6 +475,7 @@ class MemoryChunk {
   // sweeping must not be performed on that page.
   enum ParallelSweepingState {
     PARALLEL_SWEEPING_DONE,
+    PARALLEL_SWEEPING_FINALIZE,
     PARALLEL_SWEEPING_IN_PROGRESS,
     PARALLEL_SWEEPING_PENDING
   };


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to