Chromium Code Reviews| Index: src/builtins.cc |
| diff --git a/src/builtins.cc b/src/builtins.cc |
| index 474b76fc15567de1f04c4dfe65a5aa8edcb4143f..fff9f7d02f7fb0c23160a4b88e7130cce8a54359 100644 |
| --- a/src/builtins.cc |
| +++ b/src/builtins.cc |
| @@ -245,55 +245,54 @@ inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate, |
| return PrototypeHasNoElements(&iter); |
| } |
| - |
| -// Returns empty handle if not applicable. |
| +// Returns |false| if not applicable. |
| MUST_USE_RESULT |
| -inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( |
| - Isolate* isolate, Handle<Object> receiver, Arguments* args, |
| - int first_added_arg) { |
| - // We explicitly add a HandleScope to avoid creating several copies of the |
| - // same handle which would otherwise cause issue when left-trimming later-on. |
| - HandleScope scope(isolate); |
| - if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>(); |
| +inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate, |
| + Handle<Object> receiver, |
| + Arguments* args, |
| + int first_added_arg) { |
| + if (!receiver->IsJSArray()) return false; |
| Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| // If there may be elements accessors in the prototype chain, the fast path |
| // cannot be used if there arguments to add to the array. |
| Heap* heap = isolate->heap(); |
| if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) { |
| - return MaybeHandle<FixedArrayBase>(); |
| + return false; |
| } |
| - if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>(); |
| - if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>(); |
| - Handle<FixedArrayBase> elms(array->elements(), isolate); |
| - Map* map = elms->map(); |
| + if (array->map()->is_observed()) return false; |
| + if (!array->map()->is_extensible()) return false; |
| + Map* map = array->elements()->map(); |
| if (map == heap->fixed_array_map()) { |
| if (args == NULL || array->HasFastObjectElements()) { |
| - return scope.CloseAndEscape(elms); |
| + return true; |
| } |
| } else if (map == heap->fixed_cow_array_map()) { |
| - elms = JSObject::EnsureWritableFastElements(array); |
| + // Use a short-lived HandleScope to avoid creating several copies of the |
|
Toon Verwaest
2016/02/24 10:31:05
Push shouldn't need to EnsureWritableFastElements
|
| + // elements handle which would cause issues when left-trimming later-on. |
| + HandleScope scope(isolate); |
| + JSObject::EnsureWritableFastElements(array); |
| if (args == NULL || array->HasFastObjectElements()) { |
| - return scope.CloseAndEscape(elms); |
| + return true; |
| } |
| } else if (map == heap->fixed_double_array_map()) { |
| if (args == NULL) { |
| - return scope.CloseAndEscape(elms); |
| + return true; |
| } |
| } else { |
| - return MaybeHandle<FixedArrayBase>(); |
| + return false; |
| } |
| // Adding elements to the array prototype would break code that makes sure |
| // it has no elements. Handle that elsewhere. |
| if (isolate->IsAnyInitialArrayPrototype(array)) { |
| - return MaybeHandle<FixedArrayBase>(); |
| + return false; |
| } |
| // Need to ensure that the arguments passed in args can be contained in |
| // the array. |
| int args_length = args->length(); |
| if (first_added_arg >= args_length) { |
| - return scope.CloseAndEscape(elms); |
| + return true; |
| } |
| ElementsKind origin_kind = array->map()->elements_kind(); |
| @@ -316,10 +315,12 @@ inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( |
| } |
| } |
| if (target_kind != origin_kind) { |
| + // Use a short-lived HandleScope to avoid creating several copies of the |
| + // elements handle which would cause issues when left-trimming later-on. |
| + HandleScope scope(isolate); |
| JSObject::TransitionElementsKind(array, target_kind); |
| - elms = handle(array->elements(), isolate); |
| } |
| - return scope.CloseAndEscape(elms); |
| + return true; |
| } |
| @@ -359,10 +360,7 @@ BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } |
| BUILTIN(ArrayPush) { |
| HandleScope scope(isolate); |
| Handle<Object> receiver = args.receiver(); |
| - MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| - EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); |
| - Handle<FixedArrayBase> elms_obj; |
| - if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| + if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { |
| return CallJsIntrinsic(isolate, isolate->array_push(), args); |
| } |
| // Fast Elements Path |
| @@ -372,13 +370,14 @@ BUILTIN(ArrayPush) { |
| if (push_size == 0) { |
| return Smi::FromInt(len); |
| } |
| - if (push_size > 0 && |
| - JSArray::WouldChangeReadOnlyLength(array, len + push_size)) { |
| + DCHECK(push_size > 0); |
| + if (JSArray::HasReadOnlyLength(array)) { |
| return CallJsIntrinsic(isolate, isolate->array_push(), args); |
| } |
| DCHECK(!array->map()->is_observed()); |
| ElementsAccessor* accessor = array->GetElementsAccessor(); |
| - int new_length = accessor->Push(array, elms_obj, &args, push_size); |
| + int new_length = accessor->Push(array, handle(array->elements(), isolate), |
| + &args, push_size); |
| return Smi::FromInt(new_length); |
| } |
| @@ -386,10 +385,7 @@ BUILTIN(ArrayPush) { |
| BUILTIN(ArrayPop) { |
| HandleScope scope(isolate); |
| Handle<Object> receiver = args.receiver(); |
| - MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| - EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
| - Handle<FixedArrayBase> elms_obj; |
| - if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| + if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0)) { |
| return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
| } |
| @@ -406,7 +402,8 @@ BUILTIN(ArrayPop) { |
| Handle<Object> result; |
| if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
| // Fast Elements Path |
| - result = array->GetElementsAccessor()->Pop(array, elms_obj); |
| + result = array->GetElementsAccessor()->Pop( |
| + array, handle(array->elements(), isolate)); |
| } else { |
| // Use Slow Lookup otherwise |
| uint32_t new_length = len - 1; |
| @@ -422,10 +419,7 @@ BUILTIN(ArrayShift) { |
| HandleScope scope(isolate); |
| Heap* heap = isolate->heap(); |
| Handle<Object> receiver = args.receiver(); |
| - MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| - EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
| - Handle<FixedArrayBase> elms_obj; |
| - if (!maybe_elms_obj.ToHandle(&elms_obj) || |
| + if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0) || |
| !IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
| return CallJsIntrinsic(isolate, isolate->array_shift(), args); |
| } |
| @@ -439,7 +433,8 @@ BUILTIN(ArrayShift) { |
| return CallJsIntrinsic(isolate, isolate->array_shift(), args); |
| } |
| - Handle<Object> first = array->GetElementsAccessor()->Shift(array, elms_obj); |
| + Handle<Object> first = array->GetElementsAccessor()->Shift( |
| + array, handle(array->elements(), isolate)); |
| return *first; |
| } |
| @@ -447,10 +442,7 @@ BUILTIN(ArrayShift) { |
| BUILTIN(ArrayUnshift) { |
| HandleScope scope(isolate); |
| Handle<Object> receiver = args.receiver(); |
| - MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| - EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); |
| - Handle<FixedArrayBase> elms_obj; |
| - if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| + if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) { |
| return CallJsIntrinsic(isolate, isolate->array_unshift(), args); |
| } |
| Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| @@ -468,7 +460,8 @@ BUILTIN(ArrayUnshift) { |
| } |
| ElementsAccessor* accessor = array->GetElementsAccessor(); |
| - int new_length = accessor->Unshift(array, elms_obj, &args, to_add); |
| + int new_length = accessor->Unshift(array, handle(array->elements(), isolate), |
| + &args, to_add); |
| return Smi::FromInt(new_length); |
| } |
| @@ -570,10 +563,7 @@ BUILTIN(ArraySlice) { |
| BUILTIN(ArraySplice) { |
| HandleScope scope(isolate); |
| Handle<Object> receiver = args.receiver(); |
| - MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| - EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); |
| - Handle<FixedArrayBase> elms_obj; |
| - if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| + if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3)) { |
| return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
| } |
| // TODO(littledan): Look up @@species only once, not once here and |
| @@ -629,8 +619,9 @@ BUILTIN(ArraySplice) { |
| return CallJsIntrinsic(isolate, isolate->array_splice(), args); |
| } |
| ElementsAccessor* accessor = array->GetElementsAccessor(); |
| - Handle<JSArray> result_array = accessor->Splice( |
| - array, elms_obj, actual_start, actual_delete_count, &args, add_count); |
| + Handle<JSArray> result_array = |
| + accessor->Splice(array, handle(array->elements(), isolate), actual_start, |
| + actual_delete_count, &args, add_count); |
| return *result_array; |
| } |