Revert of Moving ArraySplice Builtin to ElementsAccessor (patchset #6 id:100001 of...
authorcbruni <cbruni@chromium.org>
Thu, 20 Aug 2015 13:50:59 +0000 (06:50 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 20 Aug 2015 13:51:15 +0000 (13:51 +0000)
Reason for revert:
failing bot http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20arm64%20-%20sim%20-%20MSAN/builds/3827

Original issue's description:
> - remove the Backing-Store speficic code from builtins.cc and put it in elements.cc.
> - adding tests to improve coverage of the splice method
>
> BUG=
>
> Committed: https://crrev.com/8533d4b5433d3a9e9fb1015f206997bd6d869fe3
> Cr-Commit-Position: refs/heads/master@{#30269}

TBR=mvstanton@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

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

Cr-Commit-Position: refs/heads/master@{#30271}

src/builtins.cc
src/elements.cc
src/elements.h
test/mjsunit/array-natives-elements.js
test/mjsunit/array-splice.js

index 6fe2d24..4bc61b8 100644 (file)
@@ -176,27 +176,6 @@ BUILTIN(EmptyFunction) {
 }
 
 
-// TODO(cbruni): check if this is a suitable method on Object
-bool ClampedToInteger(Object* object, int* out) {
-  // This is an extended version of ECMA-262 9.4, but additionally
-  // clamps values to [kMinInt, kMaxInt]
-  if (object->IsSmi()) {
-    *out = Smi::cast(object)->value();
-    return true;
-  } else if (object->IsHeapNumber()) {
-    *out = FastD2IChecked(HeapNumber::cast(object)->value());
-    return true;
-  } else if (object->IsUndefined()) {
-    *out = 0;
-    return true;
-  } else if (object->IsBoolean()) {
-    *out = (Oddball::cast(object)->kind() == Oddball::kTrue) ? 1 : 0;
-    return true;
-  }
-  return false;
-}
-
-
 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index,
                                FixedDoubleArray* src, int src_index, int len) {
   if (len == 0) return;
@@ -642,6 +621,7 @@ BUILTIN(ArraySlice) {
 
 BUILTIN(ArraySplice) {
   HandleScope scope(isolate);
+  Heap* heap = isolate->heap();
   Handle<Object> receiver = args.receiver();
   MaybeHandle<FixedArrayBase> maybe_elms_obj =
       EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
@@ -652,51 +632,209 @@ BUILTIN(ArraySplice) {
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   DCHECK(!array->map()->is_observed());
 
-  int argument_count = args.length() - 1;
+  int len = Smi::cast(array->length())->value();
+
+  int n_arguments = args.length() - 1;
+
   int relative_start = 0;
-  if (argument_count > 0) {
+  if (n_arguments > 0) {
     DisallowHeapAllocation no_gc;
-    if (!ClampedToInteger(args[1], &relative_start)) {
+    Object* arg1 = args[1];
+    if (arg1->IsSmi()) {
+      relative_start = Smi::cast(arg1)->value();
+    } else if (arg1->IsHeapNumber()) {
+      double start = HeapNumber::cast(arg1)->value();
+      if (start < kMinInt || start > kMaxInt) {
+        AllowHeapAllocation allow_allocation;
+        return CallJsBuiltin(isolate, "$arraySplice", args);
+      }
+      relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
+    } else if (!arg1->IsUndefined()) {
       AllowHeapAllocation allow_allocation;
       return CallJsBuiltin(isolate, "$arraySplice", args);
     }
   }
-  int len = Smi::cast(array->length())->value();
-  // clip relative start to [0, len]
   int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
                                           : Min(relative_start, len);
 
+  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
+  // given as a request to delete all the elements from the start.
+  // And it differs from the case of undefined delete count.
+  // This does not follow ECMA-262, but we do the same for
+  // compatibility.
   int actual_delete_count;
-  if (argument_count == 1) {
-    // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
-    // given as a request to delete all the elements from the start.
-    // And it differs from the case of undefined delete count.
-    // This does not follow ECMA-262, but we do the same for compatibility.
+  if (n_arguments == 1) {
     DCHECK(len - actual_start >= 0);
     actual_delete_count = len - actual_start;
   } else {
-    int delete_count = 0;
-    DisallowHeapAllocation no_gc;
-    if (argument_count > 1) {
-      if (!ClampedToInteger(args[2], &delete_count)) {
+    int value = 0;  // ToInteger(undefined) == 0
+    if (n_arguments > 1) {
+      DisallowHeapAllocation no_gc;
+      Object* arg2 = args[2];
+      if (arg2->IsSmi()) {
+        value = Smi::cast(arg2)->value();
+      } else {
         AllowHeapAllocation allow_allocation;
         return CallJsBuiltin(isolate, "$arraySplice", args);
       }
     }
-    actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
+    actual_delete_count = Min(Max(value, 0), len - actual_start);
   }
 
-  int add_count = (argument_count > 1) ? (argument_count - 2) : 0;
-  int new_length = len - actual_delete_count + add_count;
+  ElementsKind elements_kind = array->GetElementsKind();
+
+  int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
+  int new_length = len - actual_delete_count + item_count;
+
+  // For double mode we do not support changing the length.
+  if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
+    return CallJsBuiltin(isolate, "$arraySplice", args);
+  }
 
   if (new_length != len && JSArray::HasReadOnlyLength(array)) {
     AllowHeapAllocation allow_allocation;
     return CallJsBuiltin(isolate, "$arraySplice", args);
   }
-  ElementsAccessor* accessor = array->GetElementsAccessor();
-  Handle<JSArray> result = accessor->Splice(
-      array, elms_obj, actual_start, actual_delete_count, args, add_count);
-  return *result;
+
+  if (new_length == 0) {
+    Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
+        elms_obj, elements_kind, actual_delete_count);
+    array->set_elements(heap->empty_fixed_array());
+    array->set_length(Smi::FromInt(0));
+    return *result;
+  }
+
+  Handle<JSArray> result_array =
+      isolate->factory()->NewJSArray(elements_kind,
+                                     actual_delete_count,
+                                     actual_delete_count);
+
+  if (actual_delete_count > 0) {
+    DisallowHeapAllocation no_gc;
+    ElementsAccessor* accessor = array->GetElementsAccessor();
+    accessor->CopyElements(
+        elms_obj, actual_start, elements_kind,
+        handle(result_array->elements(), isolate), 0, actual_delete_count);
+  }
+
+  bool elms_changed = false;
+  if (item_count < actual_delete_count) {
+    // Shrink the array.
+    const bool trim_array = !heap->lo_space()->Contains(*elms_obj) &&
+      ((actual_start + item_count) <
+          (len - actual_delete_count - actual_start));
+    if (trim_array) {
+      const int delta = actual_delete_count - item_count;
+
+      if (elms_obj->IsFixedDoubleArray()) {
+        Handle<FixedDoubleArray> elms =
+            Handle<FixedDoubleArray>::cast(elms_obj);
+        MoveDoubleElements(*elms, delta, *elms, 0, actual_start);
+      } else {
+        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+        DisallowHeapAllocation no_gc;
+        heap->MoveElements(*elms, delta, 0, actual_start);
+      }
+
+      if (heap->CanMoveObjectStart(*elms_obj)) {
+        // On the fast path we move the start of the object in memory.
+        elms_obj = handle(heap->LeftTrimFixedArray(*elms_obj, delta));
+      } else {
+        // This is the slow path. We are going to move the elements to the left
+        // by copying them. For trimmed values we store the hole.
+        if (elms_obj->IsFixedDoubleArray()) {
+          Handle<FixedDoubleArray> elms =
+              Handle<FixedDoubleArray>::cast(elms_obj);
+          MoveDoubleElements(*elms, 0, *elms, delta, len - delta);
+          elms->FillWithHoles(len - delta, len);
+        } else {
+          Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+          DisallowHeapAllocation no_gc;
+          heap->MoveElements(*elms, 0, delta, len - delta);
+          elms->FillWithHoles(len - delta, len);
+        }
+      }
+      elms_changed = true;
+    } else {
+      if (elms_obj->IsFixedDoubleArray()) {
+        Handle<FixedDoubleArray> elms =
+            Handle<FixedDoubleArray>::cast(elms_obj);
+        MoveDoubleElements(*elms, actual_start + item_count,
+                           *elms, actual_start + actual_delete_count,
+                           (len - actual_delete_count - actual_start));
+        elms->FillWithHoles(new_length, len);
+      } else {
+        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+        DisallowHeapAllocation no_gc;
+        heap->MoveElements(*elms, actual_start + item_count,
+                           actual_start + actual_delete_count,
+                           (len - actual_delete_count - actual_start));
+        elms->FillWithHoles(new_length, len);
+      }
+    }
+  } else if (item_count > actual_delete_count) {
+    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+    // Currently fixed arrays cannot grow too big, so
+    // we should never hit this case.
+    DCHECK((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
+
+    // Check if array need to grow.
+    if (new_length > elms->length()) {
+      // New backing storage is needed.
+      int capacity = new_length + (new_length >> 1) + 16;
+      Handle<FixedArray> new_elms =
+          isolate->factory()->NewUninitializedFixedArray(capacity);
+
+      DisallowHeapAllocation no_gc;
+
+      ElementsKind kind = array->GetElementsKind();
+      ElementsAccessor* accessor = array->GetElementsAccessor();
+      if (actual_start > 0) {
+        // Copy the part before actual_start as is.
+        accessor->CopyElements(
+            elms, 0, kind, new_elms, 0, actual_start);
+      }
+      accessor->CopyElements(
+          elms, actual_start + actual_delete_count, kind,
+          new_elms, actual_start + item_count,
+          ElementsAccessor::kCopyToEndAndInitializeToHole);
+
+      elms_obj = new_elms;
+      elms_changed = true;
+    } else {
+      DisallowHeapAllocation no_gc;
+      heap->MoveElements(*elms, actual_start + item_count,
+                         actual_start + actual_delete_count,
+                         (len - actual_delete_count - actual_start));
+    }
+  }
+
+  if (IsFastDoubleElementsKind(elements_kind)) {
+    Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
+    for (int k = actual_start; k < actual_start + item_count; k++) {
+      Object* arg = args[3 + k - actual_start];
+      if (arg->IsSmi()) {
+        elms->set(k, Smi::cast(arg)->value());
+      } else {
+        elms->set(k, HeapNumber::cast(arg)->value());
+      }
+    }
+  } else {
+    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
+    DisallowHeapAllocation no_gc;
+    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
+    for (int k = actual_start; k < actual_start + item_count; k++) {
+      elms->set(k, args[3 + k - actual_start], mode);
+    }
+  }
+
+  if (elms_changed) {
+    array->set_elements(*elms_obj);
+  }
+  // Set the length.
+  array->set_length(Smi::FromInt(new_length));
+
+  return *result_array;
 }
 
 
index e133f8f..e0fb6fb 100644 (file)
@@ -115,6 +115,7 @@ static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
                   Object);
 }
 
+
 static void CopyObjectToObjectElements(FixedArrayBase* from_base,
                                        ElementsKind from_kind,
                                        uint32_t from_start,
@@ -585,23 +586,6 @@ class ElementsAccessorBase : public ElementsAccessor {
     return 0;
   }
 
-  virtual Handle<JSArray> Splice(Handle<JSArray> receiver,
-                                 Handle<FixedArrayBase> backing_store,
-                                 uint32_t start, uint32_t delete_count,
-                                 Arguments args, uint32_t add_count) {
-    return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start,
-                                                delete_count, args, add_count);
-  }
-
-  static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver,
-                                    Handle<FixedArrayBase> backing_store,
-                                    uint32_t start, uint32_t delete_count,
-                                    Arguments args, uint32_t add_count) {
-    UNREACHABLE();
-    return Handle<JSArray>();
-  }
-
-
   virtual void SetLength(Handle<JSArray> array, uint32_t length) final {
     ElementsAccessorSubclass::SetLengthImpl(array, length,
                                             handle(array->elements()));
@@ -613,31 +597,23 @@ class ElementsAccessorBase : public ElementsAccessor {
   static Handle<FixedArrayBase> ConvertElementsWithCapacity(
       Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
       ElementsKind from_kind, uint32_t capacity) {
-    return ConvertElementsWithCapacity(
-        object, old_elements, from_kind, capacity,
-        ElementsAccessor::kCopyToEndAndInitializeToHole);
-  }
-
-  static Handle<FixedArrayBase> ConvertElementsWithCapacity(
-      Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
-      ElementsKind from_kind, uint32_t capacity, int copy_size) {
     Isolate* isolate = object->GetIsolate();
-    Handle<FixedArrayBase> new_elements;
+    Handle<FixedArrayBase> elements;
     if (IsFastDoubleElementsKind(kind())) {
-      new_elements = isolate->factory()->NewFixedDoubleArray(capacity);
+      elements = isolate->factory()->NewFixedDoubleArray(capacity);
     } else {
-      new_elements = isolate->factory()->NewUninitializedFixedArray(capacity);
+      elements = isolate->factory()->NewUninitializedFixedArray(capacity);
     }
 
-    int packed_size = kPackedSizeNotKnown;
+    int packed = kPackedSizeNotKnown;
     if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) {
-      packed_size = Smi::cast(JSArray::cast(*object)->length())->value();
+      packed = Smi::cast(JSArray::cast(*object)->length())->value();
     }
 
     ElementsAccessorSubclass::CopyElementsImpl(
-        *old_elements, 0, *new_elements, from_kind, 0, packed_size, copy_size);
-
-    return new_elements;
+        *old_elements, 0, *elements, from_kind, 0, packed,
+        ElementsAccessor::kCopyToEndAndInitializeToHole);
+    return elements;
   }
 
   static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
@@ -1203,7 +1179,8 @@ class FastElementsAccessor
           receiver, backing_store, KindTraits::Kind, capacity);
     } else {
       // push_size is > 0 and new_length <= elms_len, so backing_store cannot be
-      // the empty_fixed_array.
+      // the
+      // empty_fixed_array.
       new_elms = backing_store;
     }
 
@@ -1226,132 +1203,6 @@ class FastElementsAccessor
     receiver->set_length(Smi::FromInt(new_length));
     return new_length;
   }
-
-  static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
-                           int dst_index, int src_index, int len,
-                           int hole_start, int hole_end) {
-    UNREACHABLE();
-  }
-
-  static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver,
-                                    Handle<FixedArrayBase> backing_store,
-                                    uint32_t start, uint32_t delete_count,
-                                    Arguments args, uint32_t add_count) {
-    Isolate* isolate = receiver->GetIsolate();
-    Heap* heap = isolate->heap();
-    const uint32_t len = Smi::cast(receiver->length())->value();
-    const uint32_t new_length = len - delete_count + add_count;
-
-    if (new_length == 0) {
-      receiver->set_elements(heap->empty_fixed_array());
-      receiver->set_length(Smi::FromInt(0));
-      return isolate->factory()->NewJSArrayWithElements(
-          backing_store, KindTraits::Kind, delete_count);
-    }
-
-    // construct the result array which holds the deleted elements
-    Handle<JSArray> deleted_elements = isolate->factory()->NewJSArray(
-        KindTraits::Kind, delete_count, delete_count);
-    if (delete_count > 0) {
-      DisallowHeapAllocation no_gc;
-      FastElementsAccessorSubclass::CopyElementsImpl(
-          *backing_store, start, deleted_elements->elements(), KindTraits::Kind,
-          0, kPackedSizeNotKnown, delete_count);
-    }
-
-    // delete and move elements to make space for add_count new elements
-    bool elms_changed = false;
-    if (add_count < delete_count) {
-      elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count,
-                                      add_count, len, new_length);
-    } else if (add_count > delete_count) {
-      elms_changed =
-          SpliceGrowStep(receiver, backing_store, isolate, heap, start,
-                         delete_count, add_count, len, new_length);
-    }
-
-    // Copy new Elements from args
-    if (IsFastDoubleElementsKind(KindTraits::Kind)) {
-      for (uint32_t index = start; index < start + add_count; index++) {
-        Object* arg = args[3 + index - start];
-        FastElementsAccessorSubclass::SetImpl(*backing_store, index, arg);
-      }
-    } else {
-      // FastSmiOrObjectElementsKind
-      Handle<FixedArray> elms = Handle<FixedArray>::cast(backing_store);
-      DisallowHeapAllocation no_gc;
-      WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
-      for (uint32_t index = start; index < start + add_count; index++) {
-        elms->set(index, args[3 + index - start], mode);
-      }
-    }
-
-    if (elms_changed) {
-      receiver->set_elements(*backing_store);
-    }
-    receiver->set_length(Smi::FromInt(new_length));
-    return deleted_elements;
-  }
-
- private:
-  static bool SpliceShrinkStep(Handle<FixedArrayBase>& backing_store,
-                               Heap* heap, uint32_t start,
-                               uint32_t delete_count, uint32_t add_count,
-                               uint32_t len, uint32_t new_length) {
-    const int move_left_count = len - delete_count - start;
-    const int move_left_dst_index = start + add_count;
-    const bool left_trim_array = heap->CanMoveObjectStart(*backing_store) &&
-                                 (move_left_dst_index < move_left_count);
-    if (left_trim_array) {
-      const int delta = delete_count - add_count;
-      // shift from before the insertion point to the right
-      FastElementsAccessorSubclass::MoveElements(heap, backing_store, delta, 0,
-                                                 start, 0, 0);
-      backing_store = handle(heap->LeftTrimFixedArray(*backing_store, delta));
-      return true;
-    } else {
-      // No left-trim needed or possible (in this case we left-move and store
-      // the hole)
-      FastElementsAccessorSubclass::MoveElements(
-          heap, backing_store, move_left_dst_index, start + delete_count,
-          move_left_count, new_length, len);
-    }
-    return false;
-  }
-
-
-  static bool SpliceGrowStep(Handle<JSArray> receiver,
-                             Handle<FixedArrayBase>& backing_store,
-                             Isolate* isolate, Heap* heap, uint32_t start,
-                             uint32_t delete_count, uint32_t add_count,
-                             uint32_t len, uint32_t new_length) {
-    // Currently fixed arrays cannot grow too big, so
-    // we should never hit this case.
-    DCHECK((add_count - delete_count) <= (Smi::kMaxValue - len));
-    // Check if backing_store needs to grow.
-    if (new_length > static_cast<uint32_t>(backing_store->length())) {
-      // New backing storage is needed.
-      int capacity = new_length + (new_length >> 1) + 16;
-      // partially copy all elements up to start
-      Handle<FixedArrayBase> new_elms =
-          FastElementsAccessorSubclass::ConvertElementsWithCapacity(
-              receiver, backing_store, KindTraits::Kind, capacity, start);
-      // Copy the trailing elements after start + delete_count
-      FastElementsAccessorSubclass::CopyElementsImpl(
-          *backing_store, start + delete_count, *new_elms, KindTraits::Kind,
-          start + add_count, kPackedSizeNotKnown,
-          ElementsAccessor::kCopyToEndAndInitializeToHole);
-
-      backing_store = new_elms;
-      return true;
-    } else {
-      DisallowHeapAllocation no_gc;
-      FastElementsAccessorSubclass::MoveElements(
-          heap, backing_store, start + add_count, start + delete_count,
-          (len - delete_count - start), 0, 0);
-    }
-    return false;
-  }
 };
 
 
@@ -1370,18 +1221,6 @@ class FastSmiOrObjectElementsAccessor
     return backing_store->get(index);
   }
 
-  static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
-                           int dst_index, int src_index, int len,
-                           int hole_start, int hole_end) {
-    if (len == 0) return;
-    Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store);
-    DisallowHeapAllocation no_gc;
-    heap->MoveElements(*dst_elms, dst_index, src_index, len);
-    if (hole_start != hole_end) {
-      dst_elms->FillWithHoles(hole_start, hole_end);
-    }
-  }
-
   // NOTE: this method violates the handlified function signature convention:
   // raw pointer parameters in the function that allocates.
   // See ElementsAccessor::CopyElements() for details.
@@ -1482,19 +1321,6 @@ class FastDoubleElementsAccessor
       : FastElementsAccessor<FastElementsAccessorSubclass,
                              KindTraits>(name) {}
 
-  static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
-                           int dst_index, int src_index, int len,
-                           int hole_start, int hole_end) {
-    if (len == 0) return;
-    Handle<FixedDoubleArray> dst_elms =
-        Handle<FixedDoubleArray>::cast(backing_store);
-    MemMove(dst_elms->data_start() + dst_index,
-            dst_elms->data_start() + src_index, len * kDoubleSize);
-    if (hole_start != hole_end) {
-      dst_elms->FillWithHoles(hole_start, hole_end);
-    }
-  }
-
   static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
                                FixedArrayBase* to, ElementsKind from_kind,
                                uint32_t to_start, int packed_size,
index 16be8ec..0131f0b 100644 (file)
@@ -131,11 +131,6 @@ class ElementsAccessor {
                         Handle<FixedArrayBase> backing_store, Object** objects,
                         uint32_t start, int direction) = 0;
 
-  virtual Handle<JSArray> Splice(Handle<JSArray> receiver,
-                                 Handle<FixedArrayBase> backing_store,
-                                 uint32_t start, uint32_t delete_count,
-                                 Arguments args, uint32_t add_count) = 0;
-
  protected:
   friend class LookupIterator;
 
index 01a6f21..a19a931 100644 (file)
@@ -151,6 +151,7 @@ function array_natives_test() {
   assertTrue(%HasFastSmiElements(a3));
   assertEquals([1], a3r);
   assertEquals([2, 2, 3], a3);
+
   a3 = [1.1,2,3];
   a3r = a3.splice(0, 0);
   assertTrue(%HasFastDoubleElements(a3r));
@@ -165,12 +166,13 @@ function array_natives_test() {
   assertEquals([2, 3], a3);
   a3 = [1.1,2,3];
   a3r = a3.splice(0, 0, 2);
-  assertTrue(%HasFastDoubleElements(a3r));
+  // Commented out since handled in js, which takes the best fit.
+  // assertTrue(%HasFastDoubleElements(a3r));
+  assertTrue(%HasFastSmiElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2, 1.1, 2, 3], a3);
   a3 = [1.1,2,3];
-  assertTrue(%HasFastDoubleElements(a3));
   a3r = a3.splice(0, 1, 2);
   assertTrue(%HasFastDoubleElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
@@ -178,7 +180,9 @@ function array_natives_test() {
   assertEquals([2, 2, 3], a3);
   a3 = [1.1,2,3];
   a3r = a3.splice(0, 0, 2.1);
-  assertTrue(%HasFastDoubleElements(a3r));
+  // Commented out since handled in js, which takes the best fit.
+  // assertTrue(%HasFastDoubleElements(a3r));
+  assertTrue(%HasFastSmiElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2.1, 1.1, 2, 3], a3);
@@ -190,7 +194,9 @@ function array_natives_test() {
   assertEquals([2.2, 2, 3], a3);
   a3 = [1,2,3];
   a3r = a3.splice(0, 0, 2.1);
-  assertTrue(%HasFastDoubleElements(a3r));
+  // Commented out since handled in js, which takes the best fit.
+  // assertTrue(%HasFastDoubleElements(a3r));
+  assertTrue(%HasFastSmiElements(a3r));
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([], a3r);
   assertEquals([2.1, 1, 2, 3], a3);
@@ -200,6 +206,7 @@ function array_natives_test() {
   assertTrue(%HasFastDoubleElements(a3));
   assertEquals([1], a3r);
   assertEquals([2.2, 2, 3], a3);
+
   a3 = [{},2,3];
   a3r = a3.splice(0, 0);
   assertTrue(%HasFastObjectElements(a3r));
@@ -224,6 +231,7 @@ function array_natives_test() {
   assertTrue(%HasFastObjectElements(a3));
   assertEquals([1], a3r);
   assertEquals([{}, 2, 3], a3);
+
   a3 = [1.1,2,3];
   a3r = a3.splice(0, 0, {});
   assertTrue(%HasFastObjectElements(a3r));
@@ -236,35 +244,6 @@ function array_natives_test() {
   assertTrue(%HasFastObjectElements(a3));
   assertEquals([1.1], a3r);
   assertEquals([{}, 2, 3], a3);
-  // Splice large objects
-  var a3 = new Array(1024 * 1024);
-  a3[1024*1024-1] = 1;
-  var a3r;
-  a3r = a3.splice(-1, 1);
-  assertTrue(%HasFastSmiElements(a3r));
-  assertTrue(%HasFastSmiElements(a3));
-  assertEquals([1], a3r);
-  assertEquals(new Array(1024 * 1024 - 1), a3);
-  var a3 = new Array(1024 * 1024);
-  a3[0] = 1;
-  var a3r;
-  a3r = a3.splice(0, 1);
-  assertTrue(%HasFastSmiElements(a3r));
-  assertTrue(%HasFastSmiElements(a3));
-  assertEquals([1], a3r);
-  assertEquals(new Array(1024 * 1024 - 1), a3);
-  // Splice array with large enough backing store
-  a3 = [1.1, 2.2, 3.3];
-  a3r = a3.splice(2, 1);
-  assertTrue(%HasFastDoubleElements(a3r));
-  assertTrue(%HasFastDoubleElements(a3));
-  assertEquals([3.3], a3r);
-  assertEquals([1.1, 2.2], a3);
-  a3r = a3.splice(1, 1, 4.4, 5.5);
-  assertTrue(%HasFastDoubleElements(a3r));
-  assertTrue(%HasFastDoubleElements(a3));
-  assertEquals([2.2], a3r);
-  assertEquals([1.1, 4.4, 5.5], a3);
 
   // Pop
   var a4 = [1,2,3];
index f683350..be2b106 100644 (file)
     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
 
     array = [1, 2, 3, 4, 5, 6, 7];
-    spliced = array.splice(-1e100);
-    assertEquals([], array);
-    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
-
-    array = [1, 2, 3, 4, 5, 6, 7];
     spliced = array.splice(-3);
     assertEquals([1, 2, 3, 4], array);
     assertEquals([5, 6, 7], spliced);
     assertEquals([], spliced);
 
     array = [1, 2, 3, 4, 5, 6, 7];
-    spliced = array.splice(1e100);
-    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
-    assertEquals([], spliced);
-
-    array = [1, 2, 3, 4, 5, 6, 7];
     spliced = array.splice(0, -100);
     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
     assertEquals([], spliced);
 
     array = [1, 2, 3, 4, 5, 6, 7];
-    spliced = array.splice(0, -1e100);
-    assertEquals([1, 2, 3, 4, 5, 6, 7], array);
-    assertEquals([], spliced);
-
-    array = [1, 2, 3, 4, 5, 6, 7];
     spliced = array.splice(0, -3);
     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
     assertEquals([], spliced);
     assertEquals([], array);
     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
 
-    array = [1, 2, 3, 4, 5, 6, 7];
-    spliced = array.splice(0, 1e100);
-    assertEquals([], array);
-    assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
-
     // Some exotic cases.
     obj = { toString: function() { throw 'Exception'; } };