Use CopyElements for SetFastDoubleElementsCapacityAndLength
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 Mar 2012 13:59:59 +0000 (13:59 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 Mar 2012 13:59:59 +0000 (13:59 +0000)
Review URL: https://chromiumcodereview.appspot.com/9663002

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

src/builtins.cc
src/elements.cc
src/elements.h
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime.cc

index 1557f8ef69c6fc4f68db4a2668b6d7015049802c..bd32fe280e3a7651e96b374cc90f1f1605e4bc7d 100644 (file)
@@ -508,8 +508,7 @@ BUILTIN(ArrayPush) {
     }
     FixedArray* new_elms = FixedArray::cast(obj);
 
-    AssertNoAllocation no_gc;
-    CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, 0,
+    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
                                new_elms, FAST_ELEMENTS, 0, len);
     FillWithHoles(heap, new_elms, new_length, capacity);
 
@@ -645,8 +644,7 @@ BUILTIN(ArrayUnshift) {
       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
     }
     FixedArray* new_elms = FixedArray::cast(obj);
-    AssertNoAllocation no_gc;
-    CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, 0,
+    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
                                new_elms, FAST_ELEMENTS, to_add, len);
     FillWithHoles(heap, new_elms, new_length, capacity);
     elms = new_elms;
@@ -757,8 +755,7 @@ BUILTIN(ArraySlice) {
   JSArray* result_array;
   if (!maybe_array->To(&result_array)) return maybe_array;
 
-  AssertNoAllocation no_gc;
-  CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, k,
+  CopyObjectToObjectElements(elms, FAST_ELEMENTS, k,
                              FixedArray::cast(result_array->elements()),
                              FAST_ELEMENTS, 0, result_len);
 
@@ -831,9 +828,8 @@ BUILTIN(ArraySplice) {
   if (!maybe_array->To(&result_array)) return maybe_array;
 
   {
-    AssertNoAllocation no_gc;
     // Fill newly created array.
-    CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, actual_start,
+    CopyObjectToObjectElements(elms, FAST_ELEMENTS, actual_start,
                                FixedArray::cast(result_array->elements()),
                                FAST_ELEMENTS, 0, actual_delete_count);
   }
@@ -883,12 +879,11 @@ BUILTIN(ArraySplice) {
       FixedArray* new_elms = FixedArray::cast(obj);
 
       {
-        AssertNoAllocation no_gc;
         // Copy the part before actual_start as is.
-        CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, 0,
+        CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
                                    new_elms, FAST_ELEMENTS, 0, actual_start);
         const int to_copy = len - actual_delete_count - actual_start;
-        CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS,
+        CopyObjectToObjectElements(elms, FAST_ELEMENTS,
                                    actual_start + actual_delete_count,
                                    new_elms, FAST_ELEMENTS,
                                    actual_start + item_count, to_copy);
@@ -973,14 +968,13 @@ BUILTIN(ArrayConcat) {
   if (result_len == 0) return result_array;
 
   // Copy data.
-  AssertNoAllocation no_gc;
   int start_pos = 0;
   FixedArray* result_elms(FixedArray::cast(result_array->elements()));
   for (int i = 0; i < n_arguments; i++) {
     JSArray* array = JSArray::cast(args[i]);
     int len = Smi::cast(array->length())->value();
     FixedArray* elms = FixedArray::cast(array->elements());
-    CopyObjectToObjectElements(&no_gc, elms, FAST_ELEMENTS, 0,
+    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
                                result_elms, FAST_ELEMENTS,
                                start_pos, len);
     start_pos += len;
index 331f6bc4b49162864f52c863497bfa020b453e52..f6a1697829eb52ea99a36df53eca5befe61bd0ad 100644 (file)
@@ -131,95 +131,135 @@ static Failure* ThrowArrayLengthRangeError(Heap* heap) {
 }
 
 
-void CopyObjectToObjectElements(AssertNoAllocation* no_gc,
-                                FixedArray* from_obj,
+void CopyObjectToObjectElements(FixedArray* from,
                                 ElementsKind from_kind,
                                 uint32_t from_start,
-                                FixedArray* to_obj,
+                                FixedArray* to,
                                 ElementsKind to_kind,
                                 uint32_t to_start,
-                                int copy_size) {
-  ASSERT(to_obj->map() != HEAP->fixed_cow_array_map());
+                                int raw_copy_size,
+                                WriteBarrierMode mode) {
+  ASSERT(to->map() != HEAP->fixed_cow_array_map());
   ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
   ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  if (copy_size == -1) {
-    copy_size = Min(from_obj->length() - from_start,
-                    to_obj->length() - to_start);
+  int copy_size = raw_copy_size;
+  if (raw_copy_size < 0) {
+    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = Min(from->length() - from_start,
+                    to->length() - to_start);
+#ifdef DEBUG
+    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+    // marked with the hole.
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        ASSERT(to->get(i)->IsTheHole());
+      }
+    }
+#endif
   }
-  ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
-          (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
+  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+         (copy_size + static_cast<int>(from_start)) <= from->length());
   if (copy_size == 0) return;
-  Address to = to_obj->address() + FixedArray::kHeaderSize;
-  Address from = from_obj->address() + FixedArray::kHeaderSize;
-  CopyWords(reinterpret_cast<Object**>(to) + to_start,
-            reinterpret_cast<Object**>(from) + from_start,
+  Address to_address = to->address() + FixedArray::kHeaderSize;
+  Address from_address = from->address() + FixedArray::kHeaderSize;
+  CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
+            reinterpret_cast<Object**>(from_address) + from_start,
             copy_size);
-  if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
-    Heap* heap = from_obj->GetHeap();
-    WriteBarrierMode mode = to_obj->GetWriteBarrierMode(*no_gc);
-    if (mode == UPDATE_WRITE_BARRIER) {
-      heap->RecordWrites(to_obj->address(),
-                         to_obj->OffsetOfElementAt(to_start),
+  if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS &&
+      mode == UPDATE_WRITE_BARRIER) {
+    Heap* heap = from->GetHeap();
+    if (!heap->InNewSpace(to)) {
+      heap->RecordWrites(to->address(),
+                         to->OffsetOfElementAt(to_start),
                          copy_size);
     }
-    heap->incremental_marking()->RecordWrites(to_obj);
+    heap->incremental_marking()->RecordWrites(to);
   }
 }
 
 
-
-
 static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
                                            uint32_t from_start,
                                            FixedArray* to,
                                            ElementsKind to_kind,
                                            uint32_t to_start,
-                                           int copy_size) {
+                                           int raw_copy_size,
+                                           WriteBarrierMode mode) {
+  int copy_size = raw_copy_size;
+  Heap* heap = from->GetHeap();
+  if (raw_copy_size < 0) {
+    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = from->max_number_key() + 1 - from_start;
+#ifdef DEBUG
+    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+    // marked with the hole.
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        ASSERT(to->get(i)->IsTheHole());
+      }
+    }
+#endif
+  }
+  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length());
   ASSERT(to != from);
   ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  ASSERT(copy_size == -1 ||
-         (copy_size + static_cast<int>(to_start)) <= to->length());
-  WriteBarrierMode mode = to_kind == FAST_ELEMENTS
-      ? UPDATE_WRITE_BARRIER
-      : SKIP_WRITE_BARRIER;
-  uint32_t copy_limit = (copy_size == -1)
-      ? to->length()
-      : Min(to_start + copy_size, static_cast<uint32_t>(to->length()));
-  for (int i = 0; i < from->Capacity(); ++i) {
-    Object* key = from->KeyAt(i);
-    if (key->IsNumber()) {
-      uint32_t entry = static_cast<uint32_t>(key->Number());
-      if (entry >= to_start && entry < copy_limit) {
-        Object* value = from->ValueAt(i);
-        ASSERT(to_kind == FAST_ELEMENTS || value->IsSmi());
-        to->set(entry, value, mode);
-      }
+  if (copy_size == 0) return;
+  for (int i = 0; i < copy_size; i++) {
+    int entry = from->FindEntry(i + from_start);
+    if (entry != SeededNumberDictionary::kNotFound) {
+      Object* value = from->ValueAt(entry);
+      ASSERT(!value->IsTheHole());
+      to->set(i + to_start, value, SKIP_WRITE_BARRIER);
+    } else {
+      to->set_the_hole(i + to_start);
+    }
+  }
+  if (to_kind == FAST_ELEMENTS) {
+    if (!heap->InNewSpace(to)) {
+      heap->RecordWrites(to->address(),
+                         to->OffsetOfElementAt(to_start),
+                         copy_size);
     }
+    heap->incremental_marking()->RecordWrites(to);
   }
 }
 
 
 MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
-    FixedDoubleArray* from_obj,
+    FixedDoubleArray* from,
     uint32_t from_start,
-    FixedArray* to_obj,
+    FixedArray* to,
     ElementsKind to_kind,
     uint32_t to_start,
-    int copy_size) {
+    int raw_copy_size) {
   ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
-  if (copy_size == -1) {
-    copy_size = Min(from_obj->length() - from_start,
-                    to_obj->length() - to_start);
+  int copy_size = raw_copy_size;
+  if (raw_copy_size < 0) {
+    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = Min(from->length() - from_start,
+                    to->length() - to_start);
+#ifdef DEBUG
+    // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+    // marked with the hole.
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        ASSERT(to->get(i)->IsTheHole());
+      }
+    }
+#endif
   }
-  ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
-          (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
-  if (copy_size == 0) return from_obj;
+  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+         (copy_size + static_cast<int>(from_start)) <= from->length());
+  if (copy_size == 0) return from;
   for (int i = 0; i < copy_size; ++i) {
     if (to_kind == FAST_SMI_ONLY_ELEMENTS) {
       UNIMPLEMENTED();
       return Failure::Exception();
     } else {
-      MaybeObject* maybe_value = from_obj->get(i + from_start);
+      MaybeObject* maybe_value = from->get(i + from_start);
       Object* value;
       ASSERT(to_kind == FAST_ELEMENTS);
       // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects
@@ -229,42 +269,109 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
       // can't be taken from new space.
       if (!maybe_value->ToObject(&value)) {
         ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory());
-        Heap* heap = from_obj->GetHeap();
+        Heap* heap = from->GetHeap();
         MaybeObject* maybe_value_object =
-            heap->AllocateHeapNumber(from_obj->get_scalar(i + from_start),
+            heap->AllocateHeapNumber(from->get_scalar(i + from_start),
                                      TENURED);
         if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
       }
-      to_obj->set(i + to_start, value, UPDATE_WRITE_BARRIER);
+      to->set(i + to_start, value, UPDATE_WRITE_BARRIER);
     }
   }
-  return to_obj;
+  return to;
 }
 
 
-static void CopyDoubleToDoubleElements(FixedDoubleArray* from_obj,
+static void CopyDoubleToDoubleElements(FixedDoubleArray* from,
                                        uint32_t from_start,
-                                       FixedDoubleArray* to_obj,
+                                       FixedDoubleArray* to,
                                        uint32_t to_start,
-                                       int copy_size) {
-  if (copy_size == -1) {
-    copy_size = Min(from_obj->length() - from_start,
-                    to_obj->length() - to_start);
+                                       int raw_copy_size) {
+  int copy_size = raw_copy_size;
+  if (raw_copy_size < 0) {
+    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = Min(from->length() - from_start,
+                    to->length() - to_start);
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        to->set_the_hole(i);
+      }
+    }
   }
-  ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
-          (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
+  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+         (copy_size + static_cast<int>(from_start)) <= from->length());
   if (copy_size == 0) return;
-  Address to = to_obj->address() + FixedDoubleArray::kHeaderSize;
-  Address from = from_obj->address() + FixedDoubleArray::kHeaderSize;
-  to += kDoubleSize * to_start;
-  from += kDoubleSize * from_start;
+  Address to_address = to->address() + FixedDoubleArray::kHeaderSize;
+  Address from_address = from->address() + FixedDoubleArray::kHeaderSize;
+  to_address += kDoubleSize * to_start;
+  from_address += kDoubleSize * from_start;
   int words_per_double = (kDoubleSize / kPointerSize);
-  CopyWords(reinterpret_cast<Object**>(to),
-            reinterpret_cast<Object**>(from),
+  CopyWords(reinterpret_cast<Object**>(to_address),
+            reinterpret_cast<Object**>(from_address),
             words_per_double * copy_size);
 }
 
 
+static void CopyObjectToDoubleElements(FixedArray* from,
+                                       uint32_t from_start,
+                                       FixedDoubleArray* to,
+                                       uint32_t to_start,
+                                       int raw_copy_size) {
+  int copy_size = raw_copy_size;
+  if (raw_copy_size < 0) {
+    ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+           raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = from->length() - from_start;
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        to->set_the_hole(i);
+      }
+    }
+  }
+  ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+         (copy_size + static_cast<int>(from_start)) <= from->length());
+  if (copy_size == 0) return;
+  for (int i = 0; i < copy_size; i++) {
+    Object* hole_or_object = from->get(i + from_start);
+    if (hole_or_object->IsTheHole()) {
+      to->set_the_hole(i + to_start);
+    } else {
+      to->set(i + to_start, hole_or_object->Number());
+    }
+  }
+}
+
+
+static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from,
+                                           uint32_t from_start,
+                                           FixedDoubleArray* to,
+                                           uint32_t to_start,
+                                           int raw_copy_size) {
+  int copy_size = raw_copy_size;
+  if (copy_size < 0) {
+    ASSERT(copy_size == ElementsAccessor::kCopyToEnd ||
+           copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+    copy_size = from->max_number_key() + 1 - from_start;
+    if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+      for (int i = to_start + copy_size; i < to->length(); ++i) {
+        to->set_the_hole(i);
+      }
+    }
+  }
+  ASSERT(copy_size + static_cast<int>(to_start) <= to->length());
+  if (copy_size == 0) return;
+  for (int i = 0; i < copy_size; i++) {
+    int entry = from->FindEntry(i + from_start);
+    if (entry != SeededNumberDictionary::kNotFound) {
+      to->set(i + to_start, from->ValueAt(entry)->Number());
+    } else {
+      to->set_the_hole(i + to_start);
+    }
+  }
+}
+
+
 // Base class for element handler implementations. Contains the
 // the common logic for objects with different ElementsKinds.
 // Subclasses must specialize method for which the element
@@ -369,7 +476,8 @@ class ElementsAccessorBase : public ElementsAccessor {
                                        FixedArrayBase* to,
                                        ElementsKind to_kind,
                                        uint32_t to_start,
-                                       int copy_size) {
+                                       int copy_size,
+                                       WriteBarrierMode mode) {
     UNREACHABLE();
     return NULL;
   }
@@ -380,12 +488,16 @@ class ElementsAccessorBase : public ElementsAccessor {
                                     ElementsKind to_kind,
                                     uint32_t to_start,
                                     int copy_size,
+                                    WriteBarrierMode mode,
                                     FixedArrayBase* from) {
     if (from == NULL) {
       from = from_holder->elements();
     }
+    if (from->length() == 0) {
+      return from;
+    }
     return ElementsAccessorSubclass::CopyElementsImpl(
-        from, from_start, to, to_kind, to_start, copy_size);
+        from, from_start, to, to_kind, to_start, copy_size, mode);
   }
 
   virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
@@ -622,16 +734,21 @@ class FastObjectElementsAccessor
                                        FixedArrayBase* to,
                                        ElementsKind to_kind,
                                        uint32_t to_start,
-                                       int copy_size) {
+                                       int copy_size,
+                                       WriteBarrierMode mode) {
     switch (to_kind) {
       case FAST_SMI_ONLY_ELEMENTS:
       case FAST_ELEMENTS: {
-        AssertNoAllocation no_gc;
         CopyObjectToObjectElements(
-            &no_gc, FixedArray::cast(from), ElementsTraits::Kind, from_start,
-            FixedArray::cast(to), to_kind, to_start, copy_size);
+            FixedArray::cast(from), ElementsTraits::Kind, from_start,
+            FixedArray::cast(to), to_kind, to_start, copy_size, mode);
         return from;
       }
+      case FAST_DOUBLE_ELEMENTS:
+        CopyObjectToDoubleElements(
+            FixedArray::cast(from), from_start,
+            FixedDoubleArray::cast(to), to_start, copy_size);
+        return from;
       default:
         UNREACHABLE();
     }
@@ -692,7 +809,8 @@ class FastDoubleElementsAccessor
                                        FixedArrayBase* to,
                                        ElementsKind to_kind,
                                        uint32_t to_start,
-                                       int copy_size) {
+                                       int copy_size,
+                                       WriteBarrierMode mode) {
     switch (to_kind) {
       case FAST_SMI_ONLY_ELEMENTS:
       case FAST_ELEMENTS:
@@ -989,13 +1107,19 @@ class DictionaryElementsAccessor
                                        FixedArrayBase* to,
                                        ElementsKind to_kind,
                                        uint32_t to_start,
-                                       int copy_size) {
+                                       int copy_size,
+                                       WriteBarrierMode mode) {
     switch (to_kind) {
       case FAST_SMI_ONLY_ELEMENTS:
       case FAST_ELEMENTS:
         CopyDictionaryToObjectElements(
             SeededNumberDictionary::cast(from), from_start,
-            FixedArray::cast(to), to_kind, to_start, copy_size);
+            FixedArray::cast(to), to_kind, to_start, copy_size, mode);
+        return from;
+      case FAST_DOUBLE_ELEMENTS:
+        CopyDictionaryToDoubleElements(
+            SeededNumberDictionary::cast(from), from_start,
+            FixedDoubleArray::cast(to), to_start, copy_size);
         return from;
       default:
         UNREACHABLE();
@@ -1128,12 +1252,13 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
                                        FixedArrayBase* to,
                                        ElementsKind to_kind,
                                        uint32_t to_start,
-                                       int copy_size) {
+                                       int copy_size,
+                                       WriteBarrierMode mode) {
     FixedArray* parameter_map = FixedArray::cast(from);
     FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
     ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
     return accessor->CopyElements(NULL, from_start, to, to_kind,
-                                  to_start, copy_size, arguments);
+                                  to_start, copy_size, mode, arguments);
   }
 
   static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
index 5b5be23b100abe8ead0f498ff1cddf3bbb3e4727..e853a8808e08c539c41a64354d19ed61117694b6 100644 (file)
@@ -88,6 +88,15 @@ class ElementsAccessor {
                               uint32_t key,
                               JSReceiver::DeleteMode mode) = 0;
 
+  // If kCopyToEnd is specified as the copy_size to CopyElements, it copies all
+  // of elements from source after source_start to the destination array.
+  static const int kCopyToEnd = -1;
+  // If kCopyToEndAndInitializeToHole is specified as the copy_size to
+  // CopyElements, it copies all of elements from source after source_start to
+  // destination array, padding any remaining uninitialized elements in the
+  // destination array with the hole.
+  static const int kCopyToEndAndInitializeToHole = -2;
+
   // Copy elements from one backing store to another. Typically, callers specify
   // the source JSObject or JSArray in source_holder. If the holder's backing
   // store is available, it can be passed in source and source_holder is
@@ -98,13 +107,16 @@ class ElementsAccessor {
                                     ElementsKind destination_kind,
                                     uint32_t destination_start,
                                     int copy_size,
+                                    WriteBarrierMode mode,
                                     FixedArrayBase* source = NULL) = 0;
 
   MaybeObject* CopyElements(JSObject* from_holder,
                             FixedArrayBase* to,
                             ElementsKind to_kind,
+                            WriteBarrierMode mode,
                             FixedArrayBase* from = NULL) {
-    return CopyElements(from_holder, 0, to, to_kind, 0, -1, from);
+    return CopyElements(from_holder, 0, to, to_kind, 0,
+                        kCopyToEndAndInitializeToHole, mode, from);
   }
 
   virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
@@ -146,14 +158,14 @@ class ElementsAccessor {
 };
 
 
-void CopyObjectToObjectElements(AssertNoAllocation* no_gc,
-                                FixedArray* from_obj,
+void CopyObjectToObjectElements(FixedArray* from_obj,
                                 ElementsKind from_kind,
                                 uint32_t from_start,
                                 FixedArray* to_obj,
                                 ElementsKind to_kind,
                                 uint32_t to_start,
-                                int copy_size);
+                                int copy_size,
+                                WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
 
 
 } }  // namespace v8::internal
index 3e558cfab6f2d9f85753ad2fd26f1502d3b93b76..f27a436120f5b3791ce3b8832f80517377f283e6 100644 (file)
@@ -1734,65 +1734,6 @@ bool FixedDoubleArray::is_the_hole(int index) {
 }
 
 
-void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
-  int old_length = from->length();
-  ASSERT(old_length < length());
-  if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
-    OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
-                FIELD_ADDR(from, kHeaderSize),
-                old_length * kDoubleSize);
-  } else {
-    for (int i = 0; i < old_length; ++i) {
-      if (from->is_the_hole(i)) {
-        set_the_hole(i);
-      } else {
-        set(i, from->get_scalar(i));
-      }
-    }
-  }
-  int offset = kHeaderSize + old_length * kDoubleSize;
-  for (int current = from->length(); current < length(); ++current) {
-    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
-    offset += kDoubleSize;
-  }
-}
-
-
-void FixedDoubleArray::Initialize(FixedArray* from) {
-  int old_length = from->length();
-  ASSERT(old_length <= length());
-  for (int i = 0; i < old_length; i++) {
-    Object* hole_or_object = from->get(i);
-    if (hole_or_object->IsTheHole()) {
-      set_the_hole(i);
-    } else {
-      set(i, hole_or_object->Number());
-    }
-  }
-  int offset = kHeaderSize + old_length * kDoubleSize;
-  for (int current = from->length(); current < length(); ++current) {
-    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
-    offset += kDoubleSize;
-  }
-}
-
-
-void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
-  int offset = kHeaderSize;
-  for (int current = 0; current < length(); ++current) {
-    WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
-    offset += kDoubleSize;
-  }
-  for (int i = 0; i < from->Capacity(); i++) {
-    Object* key = from->KeyAt(i);
-    if (key->IsNumber()) {
-      uint32_t entry = static_cast<uint32_t>(key->Number());
-      set(entry, from->ValueAt(i)->Number());
-    }
-  }
-}
-
-
 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
   Heap* heap = GetHeap();
   if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
index a0872c6a2492154f2320c4e9b926c0e4ebf310ec..9d20f6c503a68917fc94a134d0191ccc311aa969 100644 (file)
@@ -8448,23 +8448,23 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
     if (!maybe->To(&new_map)) return maybe;
   }
 
-  FixedArrayBase* old_elements_raw = elements();
+  FixedArrayBase* old_elements = elements();
   ElementsKind elements_kind = GetElementsKind();
   ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
   ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS)
       ? FAST_SMI_ONLY_ELEMENTS
       : FAST_ELEMENTS;
   //  int copy_size = Min(old_elements_raw->length(), new_elements->length());
-  accessor->CopyElements(this, new_elements, to_kind);
+  accessor->CopyElements(this, new_elements, to_kind, SKIP_WRITE_BARRIER);
   if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
     set_map_and_elements(new_map, new_elements);
   } else {
-    FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
+    FixedArray* parameter_map = FixedArray::cast(old_elements);
     parameter_map->set(1, new_elements);
   }
 
   if (FLAG_trace_elements_transitions) {
-    PrintElementsTransition(stdout, elements_kind, old_elements_raw,
+    PrintElementsTransition(stdout, elements_kind, old_elements,
                             GetElementsKind(), new_elements);
   }
 
@@ -8497,27 +8497,15 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
   }
 
   FixedArrayBase* old_elements = elements();
-  ElementsKind elements_kind(GetElementsKind());
-  AssertNoAllocation no_gc;
-  if (old_elements->length() != 0) {
-    switch (elements_kind) {
-      case FAST_SMI_ONLY_ELEMENTS:
-      case FAST_ELEMENTS: {
-        elems->Initialize(FixedArray::cast(old_elements));
-        break;
-      }
-      case FAST_DOUBLE_ELEMENTS: {
-        elems->Initialize(FixedDoubleArray::cast(old_elements));
-        break;
-      }
-      case DICTIONARY_ELEMENTS: {
-        elems->Initialize(SeededNumberDictionary::cast(old_elements));
-        break;
-      }
-      default:
-        UNREACHABLE();
-        break;
-    }
+  ElementsKind elements_kind = GetElementsKind();
+  ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
+  accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS,
+                         SKIP_WRITE_BARRIER);
+  if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
+    set_map_and_elements(new_map, elems);
+  } else {
+    FixedArray* parameter_map = FixedArray::cast(old_elements);
+    parameter_map->set(1, elems);
   }
 
   if (FLAG_trace_elements_transitions) {
@@ -8525,11 +8513,6 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
                             FAST_DOUBLE_ELEMENTS, elems);
   }
 
-  ASSERT(new_map->has_fast_double_elements());
-  set_map(new_map);
-  ASSERT(elems->IsFixedDoubleArray());
-  set_elements(elems);
-
   if (IsJSArray()) {
     JSArray::cast(this)->set_length(Smi::FromInt(length));
   }
index f45065e004af072313df9e6bf8686d3e62edcfec..f349cc7f9542ba159324e1d0542a1dacedd87c8d 100644 (file)
@@ -2338,10 +2338,6 @@ class FixedArray: public FixedArrayBase {
 // FixedDoubleArray describes fixed-sized arrays with element type double.
 class FixedDoubleArray: public FixedArrayBase {
  public:
-  inline void Initialize(FixedArray* from);
-  inline void Initialize(FixedDoubleArray* from);
-  inline void Initialize(SeededNumberDictionary* from);
-
   // Setter and getter for elements.
   inline double get_scalar(int index);
   MUST_USE_RESULT inline MaybeObject* get(int index);
index d8b9702bf3a7e759ec6723cf9169b37f679fac96..6e93e58620d04564d04255dcef9571b17540b104 100644 (file)
@@ -6769,6 +6769,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
         ascii = false;
       }
     } else {
+      ASSERT(!elt->IsTheHole());
       return isolate->Throw(isolate->heap()->illegal_argument_symbol());
     }
     if (increment > String::kMaxLength - position) {