From 0b0b6f65a94927abd17e27951faf3b81946004ff Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Fri, 21 Mar 2014 11:22:16 +0000 Subject: [PATCH] ArraySplice builtin handlified. 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 | 110 ++++++++++++++++++++++++++------------------------------ src/elements.cc | 26 +++++++++++--- src/factory.cc | 11 +++--- src/factory.h | 19 +++++++++- 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/src/builtins.cc b/src/builtins.cc index 39e823a..8f30260 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -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 receiver = args.receiver(); + Handle 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::cast(receiver))) { return CallJsBuiltin(isolate, "ArraySplice", args); } - JSArray* array = JSArray::cast(receiver); + Handle elms_obj = Handle::cast(elms_or_null); + Handle array = Handle::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 arg1 = args.at(1); if (arg1->IsSmi()) { - relative_start = Smi::cast(arg1)->value(); + relative_start = Handle::cast(arg1)->value(); } else if (arg1->IsHeapNumber()) { - double start = HeapNumber::cast(arg1)->value(); + double start = Handle::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 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 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::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 elms = + Handle::cast(elms_obj); + MoveDoubleElements(*elms, delta, *elms, 0, actual_start); } else { - FixedArray* elms = FixedArray::cast(elms_obj); + Handle elms = Handle::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 elms = + Handle::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 elms = Handle::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 elms = Handle::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 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::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::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 elms = Handle::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 elms = Handle::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; } diff --git a/src/elements.cc b/src/elements.cc index 7730ce5..daf4b21 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -797,6 +797,23 @@ class ElementsAccessorBase : public ElementsAccessor { return NULL; } + // TODO(ishell): Temporary wrapper, remove when CopyElements handlified. + Handle CopyElementsHelper( + Handle from_holder, + uint32_t from_start, + ElementsKind from_kind, + Handle to, + uint32_t to_start, + int copy_size, + Handle 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 from_holder, uint32_t from_start, @@ -805,11 +822,10 @@ class ElementsAccessorBase : public ElementsAccessor { uint32_t to_start, int copy_size, Handle 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 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, diff --git a/src/factory.cc b/src/factory.cc index 00f0584..5e66202 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -1441,8 +1441,9 @@ Handle Factory::NewJSObjectFromMap( } -Handle Factory::NewJSArray(int capacity, - ElementsKind elements_kind, +Handle Factory::NewJSArray(ElementsKind elements_kind, + int length, + int capacity, PretenureFlag pretenure) { if (capacity != 0) { elements_kind = GetHoleyElementsKind(elements_kind); @@ -1450,7 +1451,7 @@ Handle 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 Factory::NewJSArray(int capacity, Handle Factory::NewJSArrayWithElements(Handle 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); } diff --git a/src/factory.h b/src/factory.h index daece18..5562ef4 100644 --- a/src/factory.h +++ b/src/factory.h @@ -355,14 +355,31 @@ class Factory { // JS arrays are pretenured when allocated by the parser. Handle NewJSArray( + ElementsKind elements_kind, + int length, + int capacity, + PretenureFlag pretenure = NOT_TENURED); + + Handle NewJSArray( int capacity, ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND, + PretenureFlag pretenure = NOT_TENURED) { + return NewJSArray(elements_kind, 0, capacity, pretenure); + } + + Handle NewJSArrayWithElements( + Handle elements, + ElementsKind elements_kind, + int length, PretenureFlag pretenure = NOT_TENURED); Handle NewJSArrayWithElements( Handle 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 array, -- 2.7.4