| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index 9e04aaa7cca2447d665c872db882d65f7fe36159..42ef5ecc91230fdb74dee1f71a4063af9fd705c7 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -262,7 +262,7 @@ static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
|
| ElementsKind target_kind = origin_kind;
|
| {
|
| DisallowHeapAllocation no_gc;
|
| - int arg_count = args->length() - first_added_arg;
|
| + int arg_count = args_length - first_added_arg;
|
| Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
|
| for (int i = 0; i < arg_count; i++) {
|
| Object* arg = arguments[i];
|
| @@ -321,104 +321,22 @@ BUILTIN(ArrayPush) {
|
| if (!maybe_elms_obj.ToHandle(&elms_obj)) {
|
| return CallJsBuiltin(isolate, "$arrayPush", args);
|
| }
|
| -
|
| + // Fast Elements Path
|
| + int push_size = args.length() - 1;
|
| Handle<JSArray> array = Handle<JSArray>::cast(receiver);
|
| int len = Smi::cast(array->length())->value();
|
| - int to_add = args.length() - 1;
|
| - if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
|
| + if (push_size == 0) {
|
| + return Smi::FromInt(len);
|
| + }
|
| + if (push_size > 0 &&
|
| + JSArray::WouldChangeReadOnlyLength(array, len + push_size)) {
|
| return CallJsBuiltin(isolate, "$arrayPush", args);
|
| }
|
| DCHECK(!array->map()->is_observed());
|
| -
|
| - ElementsKind kind = array->GetElementsKind();
|
| -
|
| - if (IsFastSmiOrObjectElementsKind(kind)) {
|
| - Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
|
| - if (to_add == 0) {
|
| - return Smi::FromInt(len);
|
| - }
|
| - // Currently fixed arrays cannot grow too big, so
|
| - // we should never hit this case.
|
| - DCHECK(to_add <= (Smi::kMaxValue - len));
|
| -
|
| - int new_length = len + to_add;
|
| -
|
| - 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);
|
| -
|
| - ElementsAccessor* accessor = array->GetElementsAccessor();
|
| - accessor->CopyElements(
|
| - elms_obj, 0, kind, new_elms, 0,
|
| - ElementsAccessor::kCopyToEndAndInitializeToHole);
|
| -
|
| - elms = new_elms;
|
| - }
|
| -
|
| - // Add the provided values.
|
| - DisallowHeapAllocation no_gc;
|
| - WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
|
| - for (int index = 0; index < to_add; index++) {
|
| - elms->set(index + len, args[index + 1], mode);
|
| - }
|
| -
|
| - if (*elms != array->elements()) {
|
| - array->set_elements(*elms);
|
| - }
|
| -
|
| - // Set the length.
|
| - array->set_length(Smi::FromInt(new_length));
|
| - return Smi::FromInt(new_length);
|
| - } else {
|
| - int elms_len = elms_obj->length();
|
| - if (to_add == 0) {
|
| - return Smi::FromInt(len);
|
| - }
|
| - // Currently fixed arrays cannot grow too big, so
|
| - // we should never hit this case.
|
| - DCHECK(to_add <= (Smi::kMaxValue - len));
|
| -
|
| - int new_length = len + to_add;
|
| -
|
| - Handle<FixedDoubleArray> new_elms;
|
| -
|
| - if (new_length > elms_len) {
|
| - // New backing storage is needed.
|
| - int capacity = new_length + (new_length >> 1) + 16;
|
| - // Create new backing store; since capacity > 0, we can
|
| - // safely cast to FixedDoubleArray.
|
| - new_elms = Handle<FixedDoubleArray>::cast(
|
| - isolate->factory()->NewFixedDoubleArray(capacity));
|
| -
|
| - ElementsAccessor* accessor = array->GetElementsAccessor();
|
| - accessor->CopyElements(
|
| - elms_obj, 0, kind, new_elms, 0,
|
| - ElementsAccessor::kCopyToEndAndInitializeToHole);
|
| -
|
| - } else {
|
| - // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
|
| - // empty_fixed_array.
|
| - new_elms = Handle<FixedDoubleArray>::cast(elms_obj);
|
| - }
|
| -
|
| - // Add the provided values.
|
| - DisallowHeapAllocation no_gc;
|
| - int index;
|
| - for (index = 0; index < to_add; index++) {
|
| - Object* arg = args[index + 1];
|
| - new_elms->set(index + len, arg->Number());
|
| - }
|
| -
|
| - if (*new_elms != array->elements()) {
|
| - array->set_elements(*new_elms);
|
| - }
|
| -
|
| - // Set the length.
|
| - array->set_length(Smi::FromInt(new_length));
|
| - return Smi::FromInt(new_length);
|
| - }
|
| + ElementsAccessor* accessor = array->GetElementsAccessor();
|
| + int new_length = accessor->Push(array, elms_obj, &args[1], push_size,
|
| + ElementsAccessor::kDirectionReverse);
|
| + return Smi::FromInt(new_length);
|
| }
|
|
|
|
|
| @@ -503,7 +421,6 @@ BUILTIN(ArrayShift) {
|
|
|
| BUILTIN(ArrayUnshift) {
|
| HandleScope scope(isolate);
|
| - Heap* heap = isolate->heap();
|
| Handle<Object> receiver = args.receiver();
|
| MaybeHandle<FixedArrayBase> maybe_elms_obj =
|
| EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
|
| @@ -545,6 +462,7 @@ BUILTIN(ArrayUnshift) {
|
| array->set_elements(*elms);
|
| } else {
|
| DisallowHeapAllocation no_gc;
|
| + Heap* heap = isolate->heap();
|
| heap->MoveElements(*elms, to_add, 0, len);
|
| }
|
|
|
|
|