| OLD | NEW | 
|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 | 
| 6 | 6 | 
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" | 
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" | 
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" | 
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" | 
| (...skipping 3544 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3555   } | 3555   } | 
| 3556 | 3556 | 
| 3557   Label fast_elements_case; | 3557   Label fast_elements_case; | 
| 3558   __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); | 3558   __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); | 
| 3559   GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 3559   GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 
| 3560 | 3560 | 
| 3561   __ Bind(&fast_elements_case); | 3561   __ Bind(&fast_elements_case); | 
| 3562   GenerateCase(masm, FAST_ELEMENTS); | 3562   GenerateCase(masm, FAST_ELEMENTS); | 
| 3563 } | 3563 } | 
| 3564 | 3564 | 
| 3565 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |  | 
| 3566   // ----------- S t a t e ------------- |  | 
| 3567   //  -- x1 : function |  | 
| 3568   //  -- cp : context |  | 
| 3569   //  -- fp : frame pointer |  | 
| 3570   //  -- lr : return address |  | 
| 3571   // ----------------------------------- |  | 
| 3572   __ AssertFunction(x1); |  | 
| 3573 |  | 
| 3574   // Make x2 point to the JavaScript frame. |  | 
| 3575   __ Mov(x2, fp); |  | 
| 3576   if (skip_stub_frame()) { |  | 
| 3577     // For Ignition we need to skip the handler/stub frame to reach the |  | 
| 3578     // JavaScript frame for the function. |  | 
| 3579     __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |  | 
| 3580   } |  | 
| 3581   if (FLAG_debug_code) { |  | 
| 3582     Label ok; |  | 
| 3583     __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset)); |  | 
| 3584     __ Cmp(x3, x1); |  | 
| 3585     __ B(eq, &ok); |  | 
| 3586     __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |  | 
| 3587     __ Bind(&ok); |  | 
| 3588   } |  | 
| 3589 |  | 
| 3590   // Check if we have rest parameters (only possible if we have an |  | 
| 3591   // arguments adaptor frame below the function frame). |  | 
| 3592   Label no_rest_parameters; |  | 
| 3593   __ Ldr(x2, MemOperand(x2, CommonFrameConstants::kCallerFPOffset)); |  | 
| 3594   __ Ldr(x3, MemOperand(x2, CommonFrameConstants::kContextOrFrameTypeOffset)); |  | 
| 3595   __ Cmp(x3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
| 3596   __ B(ne, &no_rest_parameters); |  | 
| 3597 |  | 
| 3598   // Check if the arguments adaptor frame contains more arguments than |  | 
| 3599   // specified by the function's internal formal parameter count. |  | 
| 3600   Label rest_parameters; |  | 
| 3601   __ Ldrsw(x0, UntagSmiMemOperand( |  | 
| 3602                    x2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |  | 
| 3603   __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |  | 
| 3604   __ Ldrsw( |  | 
| 3605       x3, FieldMemOperand(x3, SharedFunctionInfo::kFormalParameterCountOffset)); |  | 
| 3606   __ Subs(x0, x0, x3); |  | 
| 3607   __ B(gt, &rest_parameters); |  | 
| 3608 |  | 
| 3609   // Return an empty rest parameter array. |  | 
| 3610   __ Bind(&no_rest_parameters); |  | 
| 3611   { |  | 
| 3612     // ----------- S t a t e ------------- |  | 
| 3613     //  -- cp : context |  | 
| 3614     //  -- lr : return address |  | 
| 3615     // ----------------------------------- |  | 
| 3616 |  | 
| 3617     // Allocate an empty rest parameter array. |  | 
| 3618     Label allocate, done_allocate; |  | 
| 3619     __ Allocate(JSArray::kSize, x0, x1, x2, &allocate, NO_ALLOCATION_FLAGS); |  | 
| 3620     __ Bind(&done_allocate); |  | 
| 3621 |  | 
| 3622     // Setup the rest parameter array in x0. |  | 
| 3623     __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |  | 
| 3624     __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |  | 
| 3625     __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |  | 
| 3626     __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |  | 
| 3627     __ Str(x1, FieldMemOperand(x0, JSArray::kElementsOffset)); |  | 
| 3628     __ Mov(x1, Smi::kZero); |  | 
| 3629     __ Str(x1, FieldMemOperand(x0, JSArray::kLengthOffset)); |  | 
| 3630     STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |  | 
| 3631     __ Ret(); |  | 
| 3632 |  | 
| 3633     // Fall back to %AllocateInNewSpace. |  | 
| 3634     __ Bind(&allocate); |  | 
| 3635     { |  | 
| 3636       FrameScope scope(masm, StackFrame::INTERNAL); |  | 
| 3637       __ Push(Smi::FromInt(JSArray::kSize)); |  | 
| 3638       __ CallRuntime(Runtime::kAllocateInNewSpace); |  | 
| 3639     } |  | 
| 3640     __ B(&done_allocate); |  | 
| 3641   } |  | 
| 3642 |  | 
| 3643   __ Bind(&rest_parameters); |  | 
| 3644   { |  | 
| 3645     // Compute the pointer to the first rest parameter (skippping the receiver). |  | 
| 3646     __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 3647     __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |  | 
| 3648 |  | 
| 3649     // ----------- S t a t e ------------- |  | 
| 3650     //  -- cp : context |  | 
| 3651     //  -- x0 : number of rest parameters |  | 
| 3652     //  -- x1 : function |  | 
| 3653     //  -- x2 : pointer to first rest parameters |  | 
| 3654     //  -- lr : return address |  | 
| 3655     // ----------------------------------- |  | 
| 3656 |  | 
| 3657     // Allocate space for the rest parameter array plus the backing store. |  | 
| 3658     Label allocate, done_allocate; |  | 
| 3659     __ Mov(x6, JSArray::kSize + FixedArray::kHeaderSize); |  | 
| 3660     __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 3661     __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS); |  | 
| 3662     __ Bind(&done_allocate); |  | 
| 3663 |  | 
| 3664     // Compute arguments.length in x6. |  | 
| 3665     __ SmiTag(x6, x0); |  | 
| 3666 |  | 
| 3667     // Setup the elements array in x3. |  | 
| 3668     __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex); |  | 
| 3669     __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset)); |  | 
| 3670     __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset)); |  | 
| 3671     __ Add(x4, x3, FixedArray::kHeaderSize); |  | 
| 3672     { |  | 
| 3673       Label loop, done_loop; |  | 
| 3674       __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 3675       __ Bind(&loop); |  | 
| 3676       __ Cmp(x4, x0); |  | 
| 3677       __ B(eq, &done_loop); |  | 
| 3678       __ Ldr(x5, MemOperand(x2, 0 * kPointerSize)); |  | 
| 3679       __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize)); |  | 
| 3680       __ Sub(x2, x2, Operand(1 * kPointerSize)); |  | 
| 3681       __ Add(x4, x4, Operand(1 * kPointerSize)); |  | 
| 3682       __ B(&loop); |  | 
| 3683       __ Bind(&done_loop); |  | 
| 3684     } |  | 
| 3685 |  | 
| 3686     // Setup the rest parameter array in x0. |  | 
| 3687     __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1); |  | 
| 3688     __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset)); |  | 
| 3689     __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |  | 
| 3690     __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset)); |  | 
| 3691     __ Str(x3, FieldMemOperand(x0, JSArray::kElementsOffset)); |  | 
| 3692     __ Str(x6, FieldMemOperand(x0, JSArray::kLengthOffset)); |  | 
| 3693     STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |  | 
| 3694     __ Ret(); |  | 
| 3695 |  | 
| 3696     // Fall back to %AllocateInNewSpace (if not too big). |  | 
| 3697     Label too_big_for_new_space; |  | 
| 3698     __ Bind(&allocate); |  | 
| 3699     __ Cmp(x6, Operand(kMaxRegularHeapObjectSize)); |  | 
| 3700     __ B(gt, &too_big_for_new_space); |  | 
| 3701     { |  | 
| 3702       FrameScope scope(masm, StackFrame::INTERNAL); |  | 
| 3703       __ SmiTag(x0); |  | 
| 3704       __ SmiTag(x6); |  | 
| 3705       __ Push(x0, x2, x6); |  | 
| 3706       __ CallRuntime(Runtime::kAllocateInNewSpace); |  | 
| 3707       __ Mov(x3, x0); |  | 
| 3708       __ Pop(x2, x0); |  | 
| 3709       __ SmiUntag(x0); |  | 
| 3710     } |  | 
| 3711     __ B(&done_allocate); |  | 
| 3712 |  | 
| 3713     // Fall back to %NewRestParameter. |  | 
| 3714     __ Bind(&too_big_for_new_space); |  | 
| 3715     __ Push(x1); |  | 
| 3716     __ TailCallRuntime(Runtime::kNewRestParameter); |  | 
| 3717   } |  | 
| 3718 } |  | 
| 3719 |  | 
| 3720 |  | 
| 3721 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { |  | 
| 3722   // ----------- S t a t e ------------- |  | 
| 3723   //  -- x1 : function |  | 
| 3724   //  -- cp : context |  | 
| 3725   //  -- fp : frame pointer |  | 
| 3726   //  -- lr : return address |  | 
| 3727   // ----------------------------------- |  | 
| 3728   __ AssertFunction(x1); |  | 
| 3729 |  | 
| 3730   // Make x6 point to the JavaScript frame. |  | 
| 3731   __ Mov(x6, fp); |  | 
| 3732   if (skip_stub_frame()) { |  | 
| 3733     // For Ignition we need to skip the handler/stub frame to reach the |  | 
| 3734     // JavaScript frame for the function. |  | 
| 3735     __ Ldr(x6, MemOperand(x6, StandardFrameConstants::kCallerFPOffset)); |  | 
| 3736   } |  | 
| 3737   if (FLAG_debug_code) { |  | 
| 3738     Label ok; |  | 
| 3739     __ Ldr(x3, MemOperand(x6, StandardFrameConstants::kFunctionOffset)); |  | 
| 3740     __ Cmp(x3, x1); |  | 
| 3741     __ B(eq, &ok); |  | 
| 3742     __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |  | 
| 3743     __ Bind(&ok); |  | 
| 3744   } |  | 
| 3745 |  | 
| 3746   // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub. |  | 
| 3747   __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |  | 
| 3748   __ Ldrsw( |  | 
| 3749       x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset)); |  | 
| 3750   __ Add(x3, x6, Operand(x2, LSL, kPointerSizeLog2)); |  | 
| 3751   __ Add(x3, x3, Operand(StandardFrameConstants::kCallerSPOffset)); |  | 
| 3752   __ SmiTag(x2); |  | 
| 3753 |  | 
| 3754   // x1 : function |  | 
| 3755   // x2 : number of parameters (tagged) |  | 
| 3756   // x3 : parameters pointer |  | 
| 3757   // x6 : JavaScript frame pointer |  | 
| 3758   // |  | 
| 3759   // Returns pointer to result object in x0. |  | 
| 3760 |  | 
| 3761   // Make an untagged copy of the parameter count. |  | 
| 3762   // Note: arg_count_smi is an alias of param_count_smi. |  | 
| 3763   Register function = x1; |  | 
| 3764   Register arg_count_smi = x2; |  | 
| 3765   Register param_count_smi = x2; |  | 
| 3766   Register recv_arg = x3; |  | 
| 3767   Register param_count = x7; |  | 
| 3768   __ SmiUntag(param_count, param_count_smi); |  | 
| 3769 |  | 
| 3770   // Check if the calling frame is an arguments adaptor frame. |  | 
| 3771   Register caller_fp = x11; |  | 
| 3772   Register caller_ctx = x12; |  | 
| 3773   Label runtime; |  | 
| 3774   Label adaptor_frame, try_allocate; |  | 
| 3775   __ Ldr(caller_fp, MemOperand(x6, StandardFrameConstants::kCallerFPOffset)); |  | 
| 3776   __ Ldr( |  | 
| 3777       caller_ctx, |  | 
| 3778       MemOperand(caller_fp, CommonFrameConstants::kContextOrFrameTypeOffset)); |  | 
| 3779   __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
| 3780   __ B(eq, &adaptor_frame); |  | 
| 3781 |  | 
| 3782   // No adaptor, parameter count = argument count. |  | 
| 3783 |  | 
| 3784   //   x1   function      function pointer |  | 
| 3785   //   x2   arg_count_smi number of function arguments (smi) |  | 
| 3786   //   x3   recv_arg      pointer to receiver arguments |  | 
| 3787   //   x4   mapped_params number of mapped params, min(params, args) (uninit) |  | 
| 3788   //   x7   param_count   number of function parameters |  | 
| 3789   //   x11  caller_fp     caller's frame pointer |  | 
| 3790   //   x14  arg_count     number of function arguments (uninit) |  | 
| 3791 |  | 
| 3792   Register arg_count = x14; |  | 
| 3793   Register mapped_params = x4; |  | 
| 3794   __ Mov(arg_count, param_count); |  | 
| 3795   __ Mov(mapped_params, param_count); |  | 
| 3796   __ B(&try_allocate); |  | 
| 3797 |  | 
| 3798   // We have an adaptor frame. Patch the parameters pointer. |  | 
| 3799   __ Bind(&adaptor_frame); |  | 
| 3800   __ Ldr(arg_count_smi, |  | 
| 3801          MemOperand(caller_fp, |  | 
| 3802                     ArgumentsAdaptorFrameConstants::kLengthOffset)); |  | 
| 3803   __ SmiUntag(arg_count, arg_count_smi); |  | 
| 3804   __ Add(x10, caller_fp, Operand(arg_count, LSL, kPointerSizeLog2)); |  | 
| 3805   __ Add(recv_arg, x10, StandardFrameConstants::kCallerSPOffset); |  | 
| 3806 |  | 
| 3807   // Compute the mapped parameter count = min(param_count, arg_count) |  | 
| 3808   __ Cmp(param_count, arg_count); |  | 
| 3809   __ Csel(mapped_params, param_count, arg_count, lt); |  | 
| 3810 |  | 
| 3811   __ Bind(&try_allocate); |  | 
| 3812 |  | 
| 3813   //   x0   alloc_obj     pointer to allocated objects: param map, backing |  | 
| 3814   //                      store, arguments (uninit) |  | 
| 3815   //   x1   function      function pointer |  | 
| 3816   //   x2   arg_count_smi number of function arguments (smi) |  | 
| 3817   //   x3   recv_arg      pointer to receiver arguments |  | 
| 3818   //   x4   mapped_params number of mapped parameters, min(params, args) |  | 
| 3819   //   x7   param_count   number of function parameters |  | 
| 3820   //   x10  size          size of objects to allocate (uninit) |  | 
| 3821   //   x14  arg_count     number of function arguments |  | 
| 3822 |  | 
| 3823   // Compute the size of backing store, parameter map, and arguments object. |  | 
| 3824   // 1. Parameter map, has two extra words containing context and backing |  | 
| 3825   // store. |  | 
| 3826   const int kParameterMapHeaderSize = |  | 
| 3827       FixedArray::kHeaderSize + 2 * kPointerSize; |  | 
| 3828 |  | 
| 3829   // Calculate the parameter map size, assuming it exists. |  | 
| 3830   Register size = x10; |  | 
| 3831   __ Mov(size, Operand(mapped_params, LSL, kPointerSizeLog2)); |  | 
| 3832   __ Add(size, size, kParameterMapHeaderSize); |  | 
| 3833 |  | 
| 3834   // If there are no mapped parameters, set the running size total to zero. |  | 
| 3835   // Otherwise, use the parameter map size calculated earlier. |  | 
| 3836   __ Cmp(mapped_params, 0); |  | 
| 3837   __ CzeroX(size, eq); |  | 
| 3838 |  | 
| 3839   // 2. Add the size of the backing store and arguments object. |  | 
| 3840   __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2)); |  | 
| 3841   __ Add(size, size, FixedArray::kHeaderSize + JSSloppyArgumentsObject::kSize); |  | 
| 3842 |  | 
| 3843   // Do the allocation of all three objects in one go. Assign this to x0, as it |  | 
| 3844   // will be returned to the caller. |  | 
| 3845   Register alloc_obj = x0; |  | 
| 3846   __ Allocate(size, alloc_obj, x11, x12, &runtime, NO_ALLOCATION_FLAGS); |  | 
| 3847 |  | 
| 3848   // Get the arguments boilerplate from the current (global) context. |  | 
| 3849 |  | 
| 3850   //   x0   alloc_obj       pointer to allocated objects (param map, backing |  | 
| 3851   //                        store, arguments) |  | 
| 3852   //   x1   function        function pointer |  | 
| 3853   //   x2   arg_count_smi   number of function arguments (smi) |  | 
| 3854   //   x3   recv_arg        pointer to receiver arguments |  | 
| 3855   //   x4   mapped_params   number of mapped parameters, min(params, args) |  | 
| 3856   //   x7   param_count     number of function parameters |  | 
| 3857   //   x11  sloppy_args_map offset to args (or aliased args) map (uninit) |  | 
| 3858   //   x14  arg_count       number of function arguments |  | 
| 3859 |  | 
| 3860   Register global_ctx = x10; |  | 
| 3861   Register sloppy_args_map = x11; |  | 
| 3862   Register aliased_args_map = x10; |  | 
| 3863   __ Ldr(global_ctx, NativeContextMemOperand()); |  | 
| 3864 |  | 
| 3865   __ Ldr(sloppy_args_map, |  | 
| 3866          ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); |  | 
| 3867   __ Ldr( |  | 
| 3868       aliased_args_map, |  | 
| 3869       ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)); |  | 
| 3870   __ Cmp(mapped_params, 0); |  | 
| 3871   __ CmovX(sloppy_args_map, aliased_args_map, ne); |  | 
| 3872 |  | 
| 3873   // Copy the JS object part. |  | 
| 3874   __ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset)); |  | 
| 3875   __ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex); |  | 
| 3876   __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset)); |  | 
| 3877   __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |  | 
| 3878 |  | 
| 3879   // Set up the callee in-object property. |  | 
| 3880   __ AssertNotSmi(function); |  | 
| 3881   __ Str(function, |  | 
| 3882          FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kCalleeOffset)); |  | 
| 3883 |  | 
| 3884   // Use the length and set that as an in-object property. |  | 
| 3885   __ Str(arg_count_smi, |  | 
| 3886          FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kLengthOffset)); |  | 
| 3887 |  | 
| 3888   // Set up the elements pointer in the allocated arguments object. |  | 
| 3889   // If we allocated a parameter map, "elements" will point there, otherwise |  | 
| 3890   // it will point to the backing store. |  | 
| 3891 |  | 
| 3892   //   x0   alloc_obj     pointer to allocated objects (param map, backing |  | 
| 3893   //                      store, arguments) |  | 
| 3894   //   x1   function      function pointer |  | 
| 3895   //   x2   arg_count_smi number of function arguments (smi) |  | 
| 3896   //   x3   recv_arg      pointer to receiver arguments |  | 
| 3897   //   x4   mapped_params number of mapped parameters, min(params, args) |  | 
| 3898   //   x5   elements      pointer to parameter map or backing store (uninit) |  | 
| 3899   //   x6   backing_store pointer to backing store (uninit) |  | 
| 3900   //   x7   param_count   number of function parameters |  | 
| 3901   //   x14  arg_count     number of function arguments |  | 
| 3902 |  | 
| 3903   Register elements = x5; |  | 
| 3904   __ Add(elements, alloc_obj, JSSloppyArgumentsObject::kSize); |  | 
| 3905   __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset)); |  | 
| 3906 |  | 
| 3907   // Initialize parameter map. If there are no mapped arguments, we're done. |  | 
| 3908   Label skip_parameter_map; |  | 
| 3909   __ Cmp(mapped_params, 0); |  | 
| 3910   // Set up backing store address, because it is needed later for filling in |  | 
| 3911   // the unmapped arguments. |  | 
| 3912   Register backing_store = x6; |  | 
| 3913   __ CmovX(backing_store, elements, eq); |  | 
| 3914   __ B(eq, &skip_parameter_map); |  | 
| 3915 |  | 
| 3916   __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex); |  | 
| 3917   __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset)); |  | 
| 3918   __ Add(x10, mapped_params, 2); |  | 
| 3919   __ SmiTag(x10); |  | 
| 3920   __ Str(x10, FieldMemOperand(elements, FixedArray::kLengthOffset)); |  | 
| 3921   __ Str(cp, FieldMemOperand(elements, |  | 
| 3922                              FixedArray::kHeaderSize + 0 * kPointerSize)); |  | 
| 3923   __ Add(x10, elements, Operand(mapped_params, LSL, kPointerSizeLog2)); |  | 
| 3924   __ Add(x10, x10, kParameterMapHeaderSize); |  | 
| 3925   __ Str(x10, FieldMemOperand(elements, |  | 
| 3926                               FixedArray::kHeaderSize + 1 * kPointerSize)); |  | 
| 3927 |  | 
| 3928   // Copy the parameter slots and the holes in the arguments. |  | 
| 3929   // We need to fill in mapped_parameter_count slots. Then index the context, |  | 
| 3930   // where parameters are stored in reverse order, at: |  | 
| 3931   // |  | 
| 3932   //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS + parameter_count - 1 |  | 
| 3933   // |  | 
| 3934   // The mapped parameter thus needs to get indices: |  | 
| 3935   // |  | 
| 3936   //   MIN_CONTEXT_SLOTS + parameter_count - 1 .. |  | 
| 3937   //     MIN_CONTEXT_SLOTS + parameter_count - mapped_parameter_count |  | 
| 3938   // |  | 
| 3939   // We loop from right to left. |  | 
| 3940 |  | 
| 3941   //   x0   alloc_obj     pointer to allocated objects (param map, backing |  | 
| 3942   //                      store, arguments) |  | 
| 3943   //   x1   function      function pointer |  | 
| 3944   //   x2   arg_count_smi number of function arguments (smi) |  | 
| 3945   //   x3   recv_arg      pointer to receiver arguments |  | 
| 3946   //   x4   mapped_params number of mapped parameters, min(params, args) |  | 
| 3947   //   x5   elements      pointer to parameter map or backing store (uninit) |  | 
| 3948   //   x6   backing_store pointer to backing store (uninit) |  | 
| 3949   //   x7   param_count   number of function parameters |  | 
| 3950   //   x11  loop_count    parameter loop counter (uninit) |  | 
| 3951   //   x12  index         parameter index (smi, uninit) |  | 
| 3952   //   x13  the_hole      hole value (uninit) |  | 
| 3953   //   x14  arg_count     number of function arguments |  | 
| 3954 |  | 
| 3955   Register loop_count = x11; |  | 
| 3956   Register index = x12; |  | 
| 3957   Register the_hole = x13; |  | 
| 3958   Label parameters_loop, parameters_test; |  | 
| 3959   __ Mov(loop_count, mapped_params); |  | 
| 3960   __ Add(index, param_count, static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |  | 
| 3961   __ Sub(index, index, mapped_params); |  | 
| 3962   __ SmiTag(index); |  | 
| 3963   __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex); |  | 
| 3964   __ Add(backing_store, elements, Operand(loop_count, LSL, kPointerSizeLog2)); |  | 
| 3965   __ Add(backing_store, backing_store, kParameterMapHeaderSize); |  | 
| 3966 |  | 
| 3967   __ B(¶meters_test); |  | 
| 3968 |  | 
| 3969   __ Bind(¶meters_loop); |  | 
| 3970   __ Sub(loop_count, loop_count, 1); |  | 
| 3971   __ Mov(x10, Operand(loop_count, LSL, kPointerSizeLog2)); |  | 
| 3972   __ Add(x10, x10, kParameterMapHeaderSize - kHeapObjectTag); |  | 
| 3973   __ Str(index, MemOperand(elements, x10)); |  | 
| 3974   __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize); |  | 
| 3975   __ Str(the_hole, MemOperand(backing_store, x10)); |  | 
| 3976   __ Add(index, index, Smi::FromInt(1)); |  | 
| 3977   __ Bind(¶meters_test); |  | 
| 3978   __ Cbnz(loop_count, ¶meters_loop); |  | 
| 3979 |  | 
| 3980   __ Bind(&skip_parameter_map); |  | 
| 3981   // Copy arguments header and remaining slots (if there are any.) |  | 
| 3982   __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex); |  | 
| 3983   __ Str(x10, FieldMemOperand(backing_store, FixedArray::kMapOffset)); |  | 
| 3984   __ Str(arg_count_smi, FieldMemOperand(backing_store, |  | 
| 3985                                         FixedArray::kLengthOffset)); |  | 
| 3986 |  | 
| 3987   //   x0   alloc_obj     pointer to allocated objects (param map, backing |  | 
| 3988   //                      store, arguments) |  | 
| 3989   //   x1   function      function pointer |  | 
| 3990   //   x2   arg_count_smi number of function arguments (smi) |  | 
| 3991   //   x3   recv_arg      pointer to receiver arguments |  | 
| 3992   //   x4   mapped_params number of mapped parameters, min(params, args) |  | 
| 3993   //   x6   backing_store pointer to backing store (uninit) |  | 
| 3994   //   x14  arg_count     number of function arguments |  | 
| 3995 |  | 
| 3996   Label arguments_loop, arguments_test; |  | 
| 3997   __ Mov(x10, mapped_params); |  | 
| 3998   __ Sub(recv_arg, recv_arg, Operand(x10, LSL, kPointerSizeLog2)); |  | 
| 3999   __ B(&arguments_test); |  | 
| 4000 |  | 
| 4001   __ Bind(&arguments_loop); |  | 
| 4002   __ Sub(recv_arg, recv_arg, kPointerSize); |  | 
| 4003   __ Ldr(x11, MemOperand(recv_arg)); |  | 
| 4004   __ Add(x12, backing_store, Operand(x10, LSL, kPointerSizeLog2)); |  | 
| 4005   __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize)); |  | 
| 4006   __ Add(x10, x10, 1); |  | 
| 4007 |  | 
| 4008   __ Bind(&arguments_test); |  | 
| 4009   __ Cmp(x10, arg_count); |  | 
| 4010   __ B(lt, &arguments_loop); |  | 
| 4011 |  | 
| 4012   __ Ret(); |  | 
| 4013 |  | 
| 4014   // Do the runtime call to allocate the arguments object. |  | 
| 4015   __ Bind(&runtime); |  | 
| 4016   __ Push(function, recv_arg, arg_count_smi); |  | 
| 4017   __ TailCallRuntime(Runtime::kNewSloppyArguments); |  | 
| 4018 } |  | 
| 4019 |  | 
| 4020 |  | 
| 4021 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { |  | 
| 4022   // ----------- S t a t e ------------- |  | 
| 4023   //  -- x1 : function |  | 
| 4024   //  -- cp : context |  | 
| 4025   //  -- fp : frame pointer |  | 
| 4026   //  -- lr : return address |  | 
| 4027   // ----------------------------------- |  | 
| 4028   __ AssertFunction(x1); |  | 
| 4029 |  | 
| 4030   // Make x2 point to the JavaScript frame. |  | 
| 4031   __ Mov(x2, fp); |  | 
| 4032   if (skip_stub_frame()) { |  | 
| 4033     // For Ignition we need to skip the handler/stub frame to reach the |  | 
| 4034     // JavaScript frame for the function. |  | 
| 4035     __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |  | 
| 4036   } |  | 
| 4037   if (FLAG_debug_code) { |  | 
| 4038     Label ok; |  | 
| 4039     __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset)); |  | 
| 4040     __ Cmp(x3, x1); |  | 
| 4041     __ B(eq, &ok); |  | 
| 4042     __ Abort(kInvalidFrameForFastNewRestArgumentsStub); |  | 
| 4043     __ Bind(&ok); |  | 
| 4044   } |  | 
| 4045 |  | 
| 4046   // Check if we have an arguments adaptor frame below the function frame. |  | 
| 4047   Label arguments_adaptor, arguments_done; |  | 
| 4048   __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kCallerFPOffset)); |  | 
| 4049   __ Ldr(x4, MemOperand(x3, CommonFrameConstants::kContextOrFrameTypeOffset)); |  | 
| 4050   __ Cmp(x4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |  | 
| 4051   __ B(eq, &arguments_adaptor); |  | 
| 4052   { |  | 
| 4053     __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |  | 
| 4054     __ Ldrsw(x0, FieldMemOperand( |  | 
| 4055                      x4, SharedFunctionInfo::kFormalParameterCountOffset)); |  | 
| 4056     __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 4057     __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |  | 
| 4058   } |  | 
| 4059   __ B(&arguments_done); |  | 
| 4060   __ Bind(&arguments_adaptor); |  | 
| 4061   { |  | 
| 4062     __ Ldrsw(x0, UntagSmiMemOperand( |  | 
| 4063                      x3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |  | 
| 4064     __ Add(x2, x3, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 4065     __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize); |  | 
| 4066   } |  | 
| 4067   __ Bind(&arguments_done); |  | 
| 4068 |  | 
| 4069   // ----------- S t a t e ------------- |  | 
| 4070   //  -- cp : context |  | 
| 4071   //  -- x0 : number of rest parameters |  | 
| 4072   //  -- x1 : function |  | 
| 4073   //  -- x2 : pointer to first rest parameters |  | 
| 4074   //  -- lr : return address |  | 
| 4075   // ----------------------------------- |  | 
| 4076 |  | 
| 4077   // Allocate space for the strict arguments object plus the backing store. |  | 
| 4078   Label allocate, done_allocate; |  | 
| 4079   __ Mov(x6, JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize); |  | 
| 4080   __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 4081   __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS); |  | 
| 4082   __ Bind(&done_allocate); |  | 
| 4083 |  | 
| 4084   // Compute arguments.length in x6. |  | 
| 4085   __ SmiTag(x6, x0); |  | 
| 4086 |  | 
| 4087   // Setup the elements array in x3. |  | 
| 4088   __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex); |  | 
| 4089   __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset)); |  | 
| 4090   __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset)); |  | 
| 4091   __ Add(x4, x3, FixedArray::kHeaderSize); |  | 
| 4092   { |  | 
| 4093     Label loop, done_loop; |  | 
| 4094     __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2)); |  | 
| 4095     __ Bind(&loop); |  | 
| 4096     __ Cmp(x4, x0); |  | 
| 4097     __ B(eq, &done_loop); |  | 
| 4098     __ Ldr(x5, MemOperand(x2, 0 * kPointerSize)); |  | 
| 4099     __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize)); |  | 
| 4100     __ Sub(x2, x2, Operand(1 * kPointerSize)); |  | 
| 4101     __ Add(x4, x4, Operand(1 * kPointerSize)); |  | 
| 4102     __ B(&loop); |  | 
| 4103     __ Bind(&done_loop); |  | 
| 4104   } |  | 
| 4105 |  | 
| 4106   // Setup the strict arguments object in x0. |  | 
| 4107   __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, x1); |  | 
| 4108   __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kMapOffset)); |  | 
| 4109   __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex); |  | 
| 4110   __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kPropertiesOffset)); |  | 
| 4111   __ Str(x3, FieldMemOperand(x0, JSStrictArgumentsObject::kElementsOffset)); |  | 
| 4112   __ Str(x6, FieldMemOperand(x0, JSStrictArgumentsObject::kLengthOffset)); |  | 
| 4113   STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize); |  | 
| 4114   __ Ret(); |  | 
| 4115 |  | 
| 4116   // Fall back to %AllocateInNewSpace (if not too big). |  | 
| 4117   Label too_big_for_new_space; |  | 
| 4118   __ Bind(&allocate); |  | 
| 4119   __ Cmp(x6, Operand(kMaxRegularHeapObjectSize)); |  | 
| 4120   __ B(gt, &too_big_for_new_space); |  | 
| 4121   { |  | 
| 4122     FrameScope scope(masm, StackFrame::INTERNAL); |  | 
| 4123     __ SmiTag(x0); |  | 
| 4124     __ SmiTag(x6); |  | 
| 4125     __ Push(x0, x2, x6); |  | 
| 4126     __ CallRuntime(Runtime::kAllocateInNewSpace); |  | 
| 4127     __ Mov(x3, x0); |  | 
| 4128     __ Pop(x2, x0); |  | 
| 4129     __ SmiUntag(x0); |  | 
| 4130   } |  | 
| 4131   __ B(&done_allocate); |  | 
| 4132 |  | 
| 4133   // Fall back to %NewStrictArguments. |  | 
| 4134   __ Bind(&too_big_for_new_space); |  | 
| 4135   __ Push(x1); |  | 
| 4136   __ TailCallRuntime(Runtime::kNewStrictArguments); |  | 
| 4137 } |  | 
| 4138 |  | 
| 4139 |  | 
| 4140 // The number of register that CallApiFunctionAndReturn will need to save on | 3565 // The number of register that CallApiFunctionAndReturn will need to save on | 
| 4141 // the stack. The space for these registers need to be allocated in the | 3566 // the stack. The space for these registers need to be allocated in the | 
| 4142 // ExitFrame before calling CallApiFunctionAndReturn. | 3567 // ExitFrame before calling CallApiFunctionAndReturn. | 
| 4143 static const int kCallApiFunctionSpillSpace = 4; | 3568 static const int kCallApiFunctionSpillSpace = 4; | 
| 4144 | 3569 | 
| 4145 | 3570 | 
| 4146 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 3571 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 
| 4147   return static_cast<int>(ref0.address() - ref1.address()); | 3572   return static_cast<int>(ref0.address() - ref1.address()); | 
| 4148 } | 3573 } | 
| 4149 | 3574 | 
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4478                            kStackUnwindSpace, NULL, spill_offset, | 3903                            kStackUnwindSpace, NULL, spill_offset, | 
| 4479                            return_value_operand, NULL); | 3904                            return_value_operand, NULL); | 
| 4480 } | 3905 } | 
| 4481 | 3906 | 
| 4482 #undef __ | 3907 #undef __ | 
| 4483 | 3908 | 
| 4484 }  // namespace internal | 3909 }  // namespace internal | 
| 4485 }  // namespace v8 | 3910 }  // namespace v8 | 
| 4486 | 3911 | 
| 4487 #endif  // V8_TARGET_ARCH_ARM64 | 3912 #endif  // V8_TARGET_ARCH_ARM64 | 
| OLD | NEW | 
|---|