ArraySplice builtin handlified.
authorishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 11:22:16 +0000 (11:22 +0000)
committerishell@chromium.org <ishell@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Mar 2014 11:22:16 +0000 (11:22 +0000)
R=yangguo@chromium.org

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

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

src/builtins.cc
src/elements.cc
src/factory.cc
src/factory.h

index 39e823a..8f30260 100644 (file)
@@ -820,20 +820,20 @@ BUILTIN(ArraySlice) {
 
 
 BUILTIN(ArraySplice) {
+  HandleScope scope(isolate);
   Heap* heap = isolate->heap();
-  Object* receiver = *args.receiver();
-  FixedArrayBase* elms_obj;
-  MaybeObject* maybe_elms =
-      EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3);
-  if (maybe_elms == NULL) {
-    return CallJsBuiltin(isolate, "ArraySplice", args);
-  }
-  if (!maybe_elms->To(&elms_obj)) return maybe_elms;
+  Handle<Object> receiver = args.receiver();
+  Handle<Object> elms_or_null =
+      EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 3);
+  RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null);
 
-  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
+  if ((*elms_or_null == NULL) ||
+      !IsJSArrayFastElementMovingAllowed(heap,
+                                         *Handle<JSArray>::cast(receiver))) {
     return CallJsBuiltin(isolate, "ArraySplice", args);
   }
-  JSArray* array = JSArray::cast(receiver);
+  Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
+  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   ASSERT(!array->map()->is_observed());
 
   int len = Smi::cast(array->length())->value();
@@ -842,11 +842,11 @@ BUILTIN(ArraySplice) {
 
   int relative_start = 0;
   if (n_arguments > 0) {
-    Object* arg1 = args[1];
+    Handle<Object> arg1 = args.at<Object>(1);
     if (arg1->IsSmi()) {
-      relative_start = Smi::cast(arg1)->value();
+      relative_start = Handle<Smi>::cast(arg1)->value();
     } else if (arg1->IsHeapNumber()) {
-      double start = HeapNumber::cast(arg1)->value();
+      double start = Handle<HeapNumber>::cast(arg1)->value();
       if (start < kMinInt || start > kMaxInt) {
         return CallJsBuiltin(isolate, "ArraySplice", args);
       }
@@ -891,72 +891,67 @@ BUILTIN(ArraySplice) {
   }
 
   if (new_length == 0) {
-    MaybeObject* maybe_array = heap->AllocateJSArrayWithElements(
+    Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
         elms_obj, elements_kind, actual_delete_count);
-    if (maybe_array->IsFailure()) return maybe_array;
     array->set_elements(heap->empty_fixed_array());
     array->set_length(Smi::FromInt(0));
-    return maybe_array;
+    return *result;
   }
 
-  JSArray* result_array = NULL;
-  MaybeObject* maybe_array =
-      heap->AllocateJSArrayAndStorage(elements_kind,
-                                      actual_delete_count,
-                                      actual_delete_count);
-  if (!maybe_array->To(&result_array)) return maybe_array;
+  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();
-    MaybeObject* maybe_failure = accessor->CopyElements(
-        NULL, actual_start, elements_kind, result_array->elements(),
-        0, actual_delete_count, elms_obj);
-    // Cannot fail since the origin and target array are of the same elements
-    // kind.
-    ASSERT(!maybe_failure->IsFailure());
-    USE(maybe_failure);
+    accessor->CopyElements(
+        Handle<JSObject>::null(), actual_start, elements_kind,
+        handle(result_array->elements()), 0, actual_delete_count, elms_obj);
   }
 
   bool elms_changed = false;
   if (item_count < actual_delete_count) {
     // Shrink the array.
-    const bool trim_array = !heap->lo_space()->Contains(elms_obj) &&
+    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()) {
-        FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
-        MoveDoubleElements(elms, delta, elms, 0, actual_start);
+        Handle<FixedDoubleArray> elms =
+            Handle<FixedDoubleArray>::cast(elms_obj);
+        MoveDoubleElements(*elms, delta, *elms, 0, actual_start);
       } else {
-        FixedArray* elms = FixedArray::cast(elms_obj);
+        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
         DisallowHeapAllocation no_gc;
-        heap->MoveElements(elms, delta, 0, actual_start);
+        heap->MoveElements(*elms, delta, 0, actual_start);
       }
 
-      elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);
+      elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta));
 
       elms_changed = true;
     } else {
       if (elms_obj->IsFixedDoubleArray()) {
-        FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
-        MoveDoubleElements(elms, actual_start + item_count,
-                           elms, actual_start + actual_delete_count,
+        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));
-        FillWithHoles(elms, new_length, len);
+        FillWithHoles(*elms, new_length, len);
       } else {
-        FixedArray* elms = FixedArray::cast(elms_obj);
+        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
         DisallowHeapAllocation no_gc;
-        heap->MoveElements(elms, actual_start + item_count,
+        heap->MoveElements(*elms, actual_start + item_count,
                            actual_start + actual_delete_count,
                            (len - actual_delete_count - actual_start));
-        FillWithHoles(heap, elms, new_length, len);
+        FillWithHoles(heap, *elms, new_length, len);
       }
     }
   } else if (item_count > actual_delete_count) {
-    FixedArray* elms = FixedArray::cast(elms_obj);
+    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
     // Currently fixed arrays cannot grow too big, so
     // we should never hit this case.
     ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
@@ -965,9 +960,8 @@ BUILTIN(ArraySplice) {
     if (new_length > elms->length()) {
       // New backing storage is needed.
       int capacity = new_length + (new_length >> 1) + 16;
-      FixedArray* new_elms;
-      MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
-      if (!maybe_obj->To(&new_elms)) return maybe_obj;
+      Handle<FixedArray> new_elms =
+          isolate->factory()->NewUninitializedFixedArray(capacity);
 
       DisallowHeapAllocation no_gc;
 
@@ -975,30 +969,26 @@ BUILTIN(ArraySplice) {
       ElementsAccessor* accessor = array->GetElementsAccessor();
       if (actual_start > 0) {
         // Copy the part before actual_start as is.
-        MaybeObject* maybe_failure = accessor->CopyElements(
-            NULL, 0, kind, new_elms, 0, actual_start, elms);
-        ASSERT(!maybe_failure->IsFailure());
-        USE(maybe_failure);
+        accessor->CopyElements(
+            Handle<JSObject>::null(), 0, kind, new_elms, 0, actual_start, elms);
       }
-      MaybeObject* maybe_failure = accessor->CopyElements(
-          NULL, actual_start + actual_delete_count, kind, new_elms,
-          actual_start + item_count,
+      accessor->CopyElements(
+          Handle<JSObject>::null(), actual_start + actual_delete_count, kind,
+          new_elms, actual_start + item_count,
           ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
-      ASSERT(!maybe_failure->IsFailure());
-      USE(maybe_failure);
 
       elms_obj = new_elms;
       elms_changed = true;
     } else {
       DisallowHeapAllocation no_gc;
-      heap->MoveElements(elms, actual_start + item_count,
+      heap->MoveElements(*elms, actual_start + item_count,
                          actual_start + actual_delete_count,
                          (len - actual_delete_count - actual_start));
     }
   }
 
   if (IsFastDoubleElementsKind(elements_kind)) {
-    FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
+    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()) {
@@ -1008,7 +998,7 @@ BUILTIN(ArraySplice) {
       }
     }
   } else {
-    FixedArray* elms = FixedArray::cast(elms_obj);
+    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++) {
@@ -1017,12 +1007,12 @@ BUILTIN(ArraySplice) {
   }
 
   if (elms_changed) {
-    array->set_elements(elms_obj);
+    array->set_elements(*elms_obj);
   }
   // Set the length.
   array->set_length(Smi::FromInt(new_length));
 
-  return result_array;
+  return *result_array;
 }
 
 
index 7730ce5..daf4b21 100644 (file)
@@ -797,6 +797,23 @@ class ElementsAccessorBase : public ElementsAccessor {
     return NULL;
   }
 
+  // TODO(ishell): Temporary wrapper, remove when CopyElements handlified.
+  Handle<Object> CopyElementsHelper(
+      Handle<JSObject> from_holder,
+      uint32_t from_start,
+      ElementsKind from_kind,
+      Handle<FixedArrayBase> to,
+      uint32_t to_start,
+      int copy_size,
+      Handle<FixedArrayBase> from) {
+    CALL_HEAP_FUNCTION(to->GetIsolate(),
+                       CopyElements(
+                           from_holder.is_null() ? NULL : *from_holder,
+                           from_start, from_kind, *to, to_start, copy_size,
+                           from.is_null() ? NULL : *from),
+                       Object);
+  }
+
   virtual void CopyElements(
       Handle<JSObject> from_holder,
       uint32_t from_start,
@@ -805,11 +822,10 @@ class ElementsAccessorBase : public ElementsAccessor {
       uint32_t to_start,
       int copy_size,
       Handle<FixedArrayBase> from) {
-    CALL_HEAP_FUNCTION_VOID(from_holder->GetIsolate(),
-                            CopyElements(
-                                from_holder.is_null() ? NULL : *from_holder,
-                                from_start, from_kind, *to, to_start, copy_size,
-                                from.is_null() ? NULL : *from));
+    Handle<Object> result = CopyElementsHelper(
+        from_holder, from_start, from_kind, to, to_start, copy_size, from);
+    ASSERT(!result.is_null());
+    USE(result);
   }
 
   MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
index 00f0584..5e66202 100644 (file)
@@ -1441,8 +1441,9 @@ Handle<JSObject> Factory::NewJSObjectFromMap(
 }
 
 
-Handle<JSArray> Factory::NewJSArray(int capacity,
-                                    ElementsKind elements_kind,
+Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
+                                    int length,
+                                    int capacity,
                                     PretenureFlag pretenure) {
   if (capacity != 0) {
     elements_kind = GetHoleyElementsKind(elements_kind);
@@ -1450,7 +1451,7 @@ Handle<JSArray> Factory::NewJSArray(int capacity,
   CALL_HEAP_FUNCTION(isolate(),
                      isolate()->heap()->AllocateJSArrayAndStorage(
                          elements_kind,
-                         0,
+                         length,
                          capacity,
                          INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE,
                          pretenure),
@@ -1460,12 +1461,14 @@ Handle<JSArray> Factory::NewJSArray(int capacity,
 
 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
                                                 ElementsKind elements_kind,
+                                                int length,
                                                 PretenureFlag pretenure) {
+  ASSERT(length <= elements->length());
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateJSArrayWithElements(*elements,
                                                      elements_kind,
-                                                     elements->length(),
+                                                     length,
                                                      pretenure),
       JSArray);
 }
index daece18..5562ef4 100644 (file)
@@ -355,14 +355,31 @@ class Factory {
 
   // JS arrays are pretenured when allocated by the parser.
   Handle<JSArray> NewJSArray(
+      ElementsKind elements_kind,
+      int length,
+      int capacity,
+      PretenureFlag pretenure = NOT_TENURED);
+
+  Handle<JSArray> NewJSArray(
       int capacity,
       ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
+      PretenureFlag pretenure = NOT_TENURED) {
+    return NewJSArray(elements_kind, 0, capacity, pretenure);
+  }
+
+  Handle<JSArray> NewJSArrayWithElements(
+      Handle<FixedArrayBase> elements,
+      ElementsKind elements_kind,
+      int length,
       PretenureFlag pretenure = NOT_TENURED);
 
   Handle<JSArray> NewJSArrayWithElements(
       Handle<FixedArrayBase> elements,
       ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
-      PretenureFlag pretenure = NOT_TENURED);
+      PretenureFlag pretenure = NOT_TENURED) {
+    return NewJSArrayWithElements(
+        elements, elements_kind, elements->length(), pretenure);
+  }
 
   void NewJSArrayStorage(
       Handle<JSArray> array,