Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 2645743002: [builtins] Port parameter and argument-related code stubs to CSA (Closed)
Patch Set: Remove stray change Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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(&parameters_test);
3968
3969 __ Bind(&parameters_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(&parameters_test);
3978 __ Cbnz(loop_count, &parameters_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698