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

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: Review feedback 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
« no previous file with comments | « src/arm/interface-descriptors-arm.cc ('k') | src/arm64/interface-descriptors-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3332 matching lines...) Expand 10 before | Expand all | Expand 10 after
3343 } 3343 }
3344 3344
3345 Label fast_elements_case; 3345 Label fast_elements_case;
3346 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); 3346 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case);
3347 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 3347 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
3348 3348
3349 __ Bind(&fast_elements_case); 3349 __ Bind(&fast_elements_case);
3350 GenerateCase(masm, FAST_ELEMENTS); 3350 GenerateCase(masm, FAST_ELEMENTS);
3351 } 3351 }
3352 3352
3353 void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
3354 // ----------- S t a t e -------------
3355 // -- x1 : function
3356 // -- cp : context
3357 // -- fp : frame pointer
3358 // -- lr : return address
3359 // -----------------------------------
3360 __ AssertFunction(x1);
3361
3362 // Make x2 point to the JavaScript frame.
3363 __ Mov(x2, fp);
3364 if (skip_stub_frame()) {
3365 // For Ignition we need to skip the handler/stub frame to reach the
3366 // JavaScript frame for the function.
3367 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
3368 }
3369 if (FLAG_debug_code) {
3370 Label ok;
3371 __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset));
3372 __ Cmp(x3, x1);
3373 __ B(eq, &ok);
3374 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3375 __ Bind(&ok);
3376 }
3377
3378 // Check if we have rest parameters (only possible if we have an
3379 // arguments adaptor frame below the function frame).
3380 Label no_rest_parameters;
3381 __ Ldr(x2, MemOperand(x2, CommonFrameConstants::kCallerFPOffset));
3382 __ Ldr(x3, MemOperand(x2, CommonFrameConstants::kContextOrFrameTypeOffset));
3383 __ Cmp(x3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3384 __ B(ne, &no_rest_parameters);
3385
3386 // Check if the arguments adaptor frame contains more arguments than
3387 // specified by the function's internal formal parameter count.
3388 Label rest_parameters;
3389 __ Ldrsw(x0, UntagSmiMemOperand(
3390 x2, ArgumentsAdaptorFrameConstants::kLengthOffset));
3391 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
3392 __ Ldrsw(
3393 x3, FieldMemOperand(x3, SharedFunctionInfo::kFormalParameterCountOffset));
3394 __ Subs(x0, x0, x3);
3395 __ B(gt, &rest_parameters);
3396
3397 // Return an empty rest parameter array.
3398 __ Bind(&no_rest_parameters);
3399 {
3400 // ----------- S t a t e -------------
3401 // -- cp : context
3402 // -- lr : return address
3403 // -----------------------------------
3404
3405 // Allocate an empty rest parameter array.
3406 Label allocate, done_allocate;
3407 __ Allocate(JSArray::kSize, x0, x1, x2, &allocate, NO_ALLOCATION_FLAGS);
3408 __ Bind(&done_allocate);
3409
3410 // Setup the rest parameter array in x0.
3411 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1);
3412 __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset));
3413 __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex);
3414 __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset));
3415 __ Str(x1, FieldMemOperand(x0, JSArray::kElementsOffset));
3416 __ Mov(x1, Smi::kZero);
3417 __ Str(x1, FieldMemOperand(x0, JSArray::kLengthOffset));
3418 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3419 __ Ret();
3420
3421 // Fall back to %AllocateInNewSpace.
3422 __ Bind(&allocate);
3423 {
3424 FrameScope scope(masm, StackFrame::INTERNAL);
3425 __ Push(Smi::FromInt(JSArray::kSize));
3426 __ CallRuntime(Runtime::kAllocateInNewSpace);
3427 }
3428 __ B(&done_allocate);
3429 }
3430
3431 __ Bind(&rest_parameters);
3432 {
3433 // Compute the pointer to the first rest parameter (skippping the receiver).
3434 __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2));
3435 __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize);
3436
3437 // ----------- S t a t e -------------
3438 // -- cp : context
3439 // -- x0 : number of rest parameters
3440 // -- x1 : function
3441 // -- x2 : pointer to first rest parameters
3442 // -- lr : return address
3443 // -----------------------------------
3444
3445 // Allocate space for the rest parameter array plus the backing store.
3446 Label allocate, done_allocate;
3447 __ Mov(x6, JSArray::kSize + FixedArray::kHeaderSize);
3448 __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2));
3449 __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS);
3450 __ Bind(&done_allocate);
3451
3452 // Compute arguments.length in x6.
3453 __ SmiTag(x6, x0);
3454
3455 // Setup the elements array in x3.
3456 __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex);
3457 __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset));
3458 __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset));
3459 __ Add(x4, x3, FixedArray::kHeaderSize);
3460 {
3461 Label loop, done_loop;
3462 __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2));
3463 __ Bind(&loop);
3464 __ Cmp(x4, x0);
3465 __ B(eq, &done_loop);
3466 __ Ldr(x5, MemOperand(x2, 0 * kPointerSize));
3467 __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize));
3468 __ Sub(x2, x2, Operand(1 * kPointerSize));
3469 __ Add(x4, x4, Operand(1 * kPointerSize));
3470 __ B(&loop);
3471 __ Bind(&done_loop);
3472 }
3473
3474 // Setup the rest parameter array in x0.
3475 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, x1);
3476 __ Str(x1, FieldMemOperand(x0, JSArray::kMapOffset));
3477 __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex);
3478 __ Str(x1, FieldMemOperand(x0, JSArray::kPropertiesOffset));
3479 __ Str(x3, FieldMemOperand(x0, JSArray::kElementsOffset));
3480 __ Str(x6, FieldMemOperand(x0, JSArray::kLengthOffset));
3481 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3482 __ Ret();
3483
3484 // Fall back to %AllocateInNewSpace (if not too big).
3485 Label too_big_for_new_space;
3486 __ Bind(&allocate);
3487 __ Cmp(x6, Operand(kMaxRegularHeapObjectSize));
3488 __ B(gt, &too_big_for_new_space);
3489 {
3490 FrameScope scope(masm, StackFrame::INTERNAL);
3491 __ SmiTag(x0);
3492 __ SmiTag(x6);
3493 __ Push(x0, x2, x6);
3494 __ CallRuntime(Runtime::kAllocateInNewSpace);
3495 __ Mov(x3, x0);
3496 __ Pop(x2, x0);
3497 __ SmiUntag(x0);
3498 }
3499 __ B(&done_allocate);
3500
3501 // Fall back to %NewRestParameter.
3502 __ Bind(&too_big_for_new_space);
3503 __ Push(x1);
3504 __ TailCallRuntime(Runtime::kNewRestParameter);
3505 }
3506 }
3507
3508
3509 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
3510 // ----------- S t a t e -------------
3511 // -- x1 : function
3512 // -- cp : context
3513 // -- fp : frame pointer
3514 // -- lr : return address
3515 // -----------------------------------
3516 __ AssertFunction(x1);
3517
3518 // Make x6 point to the JavaScript frame.
3519 __ Mov(x6, fp);
3520 if (skip_stub_frame()) {
3521 // For Ignition we need to skip the handler/stub frame to reach the
3522 // JavaScript frame for the function.
3523 __ Ldr(x6, MemOperand(x6, StandardFrameConstants::kCallerFPOffset));
3524 }
3525 if (FLAG_debug_code) {
3526 Label ok;
3527 __ Ldr(x3, MemOperand(x6, StandardFrameConstants::kFunctionOffset));
3528 __ Cmp(x3, x1);
3529 __ B(eq, &ok);
3530 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3531 __ Bind(&ok);
3532 }
3533
3534 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
3535 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
3536 __ Ldrsw(
3537 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset));
3538 __ Add(x3, x6, Operand(x2, LSL, kPointerSizeLog2));
3539 __ Add(x3, x3, Operand(StandardFrameConstants::kCallerSPOffset));
3540 __ SmiTag(x2);
3541
3542 // x1 : function
3543 // x2 : number of parameters (tagged)
3544 // x3 : parameters pointer
3545 // x6 : JavaScript frame pointer
3546 //
3547 // Returns pointer to result object in x0.
3548
3549 // Make an untagged copy of the parameter count.
3550 // Note: arg_count_smi is an alias of param_count_smi.
3551 Register function = x1;
3552 Register arg_count_smi = x2;
3553 Register param_count_smi = x2;
3554 Register recv_arg = x3;
3555 Register param_count = x7;
3556 __ SmiUntag(param_count, param_count_smi);
3557
3558 // Check if the calling frame is an arguments adaptor frame.
3559 Register caller_fp = x11;
3560 Register caller_ctx = x12;
3561 Label runtime;
3562 Label adaptor_frame, try_allocate;
3563 __ Ldr(caller_fp, MemOperand(x6, StandardFrameConstants::kCallerFPOffset));
3564 __ Ldr(
3565 caller_ctx,
3566 MemOperand(caller_fp, CommonFrameConstants::kContextOrFrameTypeOffset));
3567 __ Cmp(caller_ctx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3568 __ B(eq, &adaptor_frame);
3569
3570 // No adaptor, parameter count = argument count.
3571
3572 // x1 function function pointer
3573 // x2 arg_count_smi number of function arguments (smi)
3574 // x3 recv_arg pointer to receiver arguments
3575 // x4 mapped_params number of mapped params, min(params, args) (uninit)
3576 // x7 param_count number of function parameters
3577 // x11 caller_fp caller's frame pointer
3578 // x14 arg_count number of function arguments (uninit)
3579
3580 Register arg_count = x14;
3581 Register mapped_params = x4;
3582 __ Mov(arg_count, param_count);
3583 __ Mov(mapped_params, param_count);
3584 __ B(&try_allocate);
3585
3586 // We have an adaptor frame. Patch the parameters pointer.
3587 __ Bind(&adaptor_frame);
3588 __ Ldr(arg_count_smi,
3589 MemOperand(caller_fp,
3590 ArgumentsAdaptorFrameConstants::kLengthOffset));
3591 __ SmiUntag(arg_count, arg_count_smi);
3592 __ Add(x10, caller_fp, Operand(arg_count, LSL, kPointerSizeLog2));
3593 __ Add(recv_arg, x10, StandardFrameConstants::kCallerSPOffset);
3594
3595 // Compute the mapped parameter count = min(param_count, arg_count)
3596 __ Cmp(param_count, arg_count);
3597 __ Csel(mapped_params, param_count, arg_count, lt);
3598
3599 __ Bind(&try_allocate);
3600
3601 // x0 alloc_obj pointer to allocated objects: param map, backing
3602 // store, arguments (uninit)
3603 // x1 function function pointer
3604 // x2 arg_count_smi number of function arguments (smi)
3605 // x3 recv_arg pointer to receiver arguments
3606 // x4 mapped_params number of mapped parameters, min(params, args)
3607 // x7 param_count number of function parameters
3608 // x10 size size of objects to allocate (uninit)
3609 // x14 arg_count number of function arguments
3610
3611 // Compute the size of backing store, parameter map, and arguments object.
3612 // 1. Parameter map, has two extra words containing context and backing
3613 // store.
3614 const int kParameterMapHeaderSize =
3615 FixedArray::kHeaderSize + 2 * kPointerSize;
3616
3617 // Calculate the parameter map size, assuming it exists.
3618 Register size = x10;
3619 __ Mov(size, Operand(mapped_params, LSL, kPointerSizeLog2));
3620 __ Add(size, size, kParameterMapHeaderSize);
3621
3622 // If there are no mapped parameters, set the running size total to zero.
3623 // Otherwise, use the parameter map size calculated earlier.
3624 __ Cmp(mapped_params, 0);
3625 __ CzeroX(size, eq);
3626
3627 // 2. Add the size of the backing store and arguments object.
3628 __ Add(size, size, Operand(arg_count, LSL, kPointerSizeLog2));
3629 __ Add(size, size, FixedArray::kHeaderSize + JSSloppyArgumentsObject::kSize);
3630
3631 // Do the allocation of all three objects in one go. Assign this to x0, as it
3632 // will be returned to the caller.
3633 Register alloc_obj = x0;
3634 __ Allocate(size, alloc_obj, x11, x12, &runtime, NO_ALLOCATION_FLAGS);
3635
3636 // Get the arguments boilerplate from the current (global) context.
3637
3638 // x0 alloc_obj pointer to allocated objects (param map, backing
3639 // store, arguments)
3640 // x1 function function pointer
3641 // x2 arg_count_smi number of function arguments (smi)
3642 // x3 recv_arg pointer to receiver arguments
3643 // x4 mapped_params number of mapped parameters, min(params, args)
3644 // x7 param_count number of function parameters
3645 // x11 sloppy_args_map offset to args (or aliased args) map (uninit)
3646 // x14 arg_count number of function arguments
3647
3648 Register global_ctx = x10;
3649 Register sloppy_args_map = x11;
3650 Register aliased_args_map = x10;
3651 __ Ldr(global_ctx, NativeContextMemOperand());
3652
3653 __ Ldr(sloppy_args_map,
3654 ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
3655 __ Ldr(
3656 aliased_args_map,
3657 ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX));
3658 __ Cmp(mapped_params, 0);
3659 __ CmovX(sloppy_args_map, aliased_args_map, ne);
3660
3661 // Copy the JS object part.
3662 __ Str(sloppy_args_map, FieldMemOperand(alloc_obj, JSObject::kMapOffset));
3663 __ LoadRoot(x10, Heap::kEmptyFixedArrayRootIndex);
3664 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kPropertiesOffset));
3665 __ Str(x10, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
3666
3667 // Set up the callee in-object property.
3668 __ AssertNotSmi(function);
3669 __ Str(function,
3670 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kCalleeOffset));
3671
3672 // Use the length and set that as an in-object property.
3673 __ Str(arg_count_smi,
3674 FieldMemOperand(alloc_obj, JSSloppyArgumentsObject::kLengthOffset));
3675
3676 // Set up the elements pointer in the allocated arguments object.
3677 // If we allocated a parameter map, "elements" will point there, otherwise
3678 // it will point to the backing store.
3679
3680 // x0 alloc_obj pointer to allocated objects (param map, backing
3681 // store, arguments)
3682 // x1 function function pointer
3683 // x2 arg_count_smi number of function arguments (smi)
3684 // x3 recv_arg pointer to receiver arguments
3685 // x4 mapped_params number of mapped parameters, min(params, args)
3686 // x5 elements pointer to parameter map or backing store (uninit)
3687 // x6 backing_store pointer to backing store (uninit)
3688 // x7 param_count number of function parameters
3689 // x14 arg_count number of function arguments
3690
3691 Register elements = x5;
3692 __ Add(elements, alloc_obj, JSSloppyArgumentsObject::kSize);
3693 __ Str(elements, FieldMemOperand(alloc_obj, JSObject::kElementsOffset));
3694
3695 // Initialize parameter map. If there are no mapped arguments, we're done.
3696 Label skip_parameter_map;
3697 __ Cmp(mapped_params, 0);
3698 // Set up backing store address, because it is needed later for filling in
3699 // the unmapped arguments.
3700 Register backing_store = x6;
3701 __ CmovX(backing_store, elements, eq);
3702 __ B(eq, &skip_parameter_map);
3703
3704 __ LoadRoot(x10, Heap::kSloppyArgumentsElementsMapRootIndex);
3705 __ Str(x10, FieldMemOperand(elements, FixedArray::kMapOffset));
3706 __ Add(x10, mapped_params, 2);
3707 __ SmiTag(x10);
3708 __ Str(x10, FieldMemOperand(elements, FixedArray::kLengthOffset));
3709 __ Str(cp, FieldMemOperand(elements,
3710 FixedArray::kHeaderSize + 0 * kPointerSize));
3711 __ Add(x10, elements, Operand(mapped_params, LSL, kPointerSizeLog2));
3712 __ Add(x10, x10, kParameterMapHeaderSize);
3713 __ Str(x10, FieldMemOperand(elements,
3714 FixedArray::kHeaderSize + 1 * kPointerSize));
3715
3716 // Copy the parameter slots and the holes in the arguments.
3717 // We need to fill in mapped_parameter_count slots. Then index the context,
3718 // where parameters are stored in reverse order, at:
3719 //
3720 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS + parameter_count - 1
3721 //
3722 // The mapped parameter thus needs to get indices:
3723 //
3724 // MIN_CONTEXT_SLOTS + parameter_count - 1 ..
3725 // MIN_CONTEXT_SLOTS + parameter_count - mapped_parameter_count
3726 //
3727 // We loop from right to left.
3728
3729 // x0 alloc_obj pointer to allocated objects (param map, backing
3730 // store, arguments)
3731 // x1 function function pointer
3732 // x2 arg_count_smi number of function arguments (smi)
3733 // x3 recv_arg pointer to receiver arguments
3734 // x4 mapped_params number of mapped parameters, min(params, args)
3735 // x5 elements pointer to parameter map or backing store (uninit)
3736 // x6 backing_store pointer to backing store (uninit)
3737 // x7 param_count number of function parameters
3738 // x11 loop_count parameter loop counter (uninit)
3739 // x12 index parameter index (smi, uninit)
3740 // x13 the_hole hole value (uninit)
3741 // x14 arg_count number of function arguments
3742
3743 Register loop_count = x11;
3744 Register index = x12;
3745 Register the_hole = x13;
3746 Label parameters_loop, parameters_test;
3747 __ Mov(loop_count, mapped_params);
3748 __ Add(index, param_count, static_cast<int>(Context::MIN_CONTEXT_SLOTS));
3749 __ Sub(index, index, mapped_params);
3750 __ SmiTag(index);
3751 __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
3752 __ Add(backing_store, elements, Operand(loop_count, LSL, kPointerSizeLog2));
3753 __ Add(backing_store, backing_store, kParameterMapHeaderSize);
3754
3755 __ B(&parameters_test);
3756
3757 __ Bind(&parameters_loop);
3758 __ Sub(loop_count, loop_count, 1);
3759 __ Mov(x10, Operand(loop_count, LSL, kPointerSizeLog2));
3760 __ Add(x10, x10, kParameterMapHeaderSize - kHeapObjectTag);
3761 __ Str(index, MemOperand(elements, x10));
3762 __ Sub(x10, x10, kParameterMapHeaderSize - FixedArray::kHeaderSize);
3763 __ Str(the_hole, MemOperand(backing_store, x10));
3764 __ Add(index, index, Smi::FromInt(1));
3765 __ Bind(&parameters_test);
3766 __ Cbnz(loop_count, &parameters_loop);
3767
3768 __ Bind(&skip_parameter_map);
3769 // Copy arguments header and remaining slots (if there are any.)
3770 __ LoadRoot(x10, Heap::kFixedArrayMapRootIndex);
3771 __ Str(x10, FieldMemOperand(backing_store, FixedArray::kMapOffset));
3772 __ Str(arg_count_smi, FieldMemOperand(backing_store,
3773 FixedArray::kLengthOffset));
3774
3775 // x0 alloc_obj pointer to allocated objects (param map, backing
3776 // store, arguments)
3777 // x1 function function pointer
3778 // x2 arg_count_smi number of function arguments (smi)
3779 // x3 recv_arg pointer to receiver arguments
3780 // x4 mapped_params number of mapped parameters, min(params, args)
3781 // x6 backing_store pointer to backing store (uninit)
3782 // x14 arg_count number of function arguments
3783
3784 Label arguments_loop, arguments_test;
3785 __ Mov(x10, mapped_params);
3786 __ Sub(recv_arg, recv_arg, Operand(x10, LSL, kPointerSizeLog2));
3787 __ B(&arguments_test);
3788
3789 __ Bind(&arguments_loop);
3790 __ Sub(recv_arg, recv_arg, kPointerSize);
3791 __ Ldr(x11, MemOperand(recv_arg));
3792 __ Add(x12, backing_store, Operand(x10, LSL, kPointerSizeLog2));
3793 __ Str(x11, FieldMemOperand(x12, FixedArray::kHeaderSize));
3794 __ Add(x10, x10, 1);
3795
3796 __ Bind(&arguments_test);
3797 __ Cmp(x10, arg_count);
3798 __ B(lt, &arguments_loop);
3799
3800 __ Ret();
3801
3802 // Do the runtime call to allocate the arguments object.
3803 __ Bind(&runtime);
3804 __ Push(function, recv_arg, arg_count_smi);
3805 __ TailCallRuntime(Runtime::kNewSloppyArguments);
3806 }
3807
3808
3809 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
3810 // ----------- S t a t e -------------
3811 // -- x1 : function
3812 // -- cp : context
3813 // -- fp : frame pointer
3814 // -- lr : return address
3815 // -----------------------------------
3816 __ AssertFunction(x1);
3817
3818 // Make x2 point to the JavaScript frame.
3819 __ Mov(x2, fp);
3820 if (skip_stub_frame()) {
3821 // For Ignition we need to skip the handler/stub frame to reach the
3822 // JavaScript frame for the function.
3823 __ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
3824 }
3825 if (FLAG_debug_code) {
3826 Label ok;
3827 __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kFunctionOffset));
3828 __ Cmp(x3, x1);
3829 __ B(eq, &ok);
3830 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3831 __ Bind(&ok);
3832 }
3833
3834 // Check if we have an arguments adaptor frame below the function frame.
3835 Label arguments_adaptor, arguments_done;
3836 __ Ldr(x3, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
3837 __ Ldr(x4, MemOperand(x3, CommonFrameConstants::kContextOrFrameTypeOffset));
3838 __ Cmp(x4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3839 __ B(eq, &arguments_adaptor);
3840 {
3841 __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
3842 __ Ldrsw(x0, FieldMemOperand(
3843 x4, SharedFunctionInfo::kFormalParameterCountOffset));
3844 __ Add(x2, x2, Operand(x0, LSL, kPointerSizeLog2));
3845 __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize);
3846 }
3847 __ B(&arguments_done);
3848 __ Bind(&arguments_adaptor);
3849 {
3850 __ Ldrsw(x0, UntagSmiMemOperand(
3851 x3, ArgumentsAdaptorFrameConstants::kLengthOffset));
3852 __ Add(x2, x3, Operand(x0, LSL, kPointerSizeLog2));
3853 __ Add(x2, x2, StandardFrameConstants::kCallerSPOffset - 1 * kPointerSize);
3854 }
3855 __ Bind(&arguments_done);
3856
3857 // ----------- S t a t e -------------
3858 // -- cp : context
3859 // -- x0 : number of rest parameters
3860 // -- x1 : function
3861 // -- x2 : pointer to first rest parameters
3862 // -- lr : return address
3863 // -----------------------------------
3864
3865 // Allocate space for the strict arguments object plus the backing store.
3866 Label allocate, done_allocate;
3867 __ Mov(x6, JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize);
3868 __ Add(x6, x6, Operand(x0, LSL, kPointerSizeLog2));
3869 __ Allocate(x6, x3, x4, x5, &allocate, NO_ALLOCATION_FLAGS);
3870 __ Bind(&done_allocate);
3871
3872 // Compute arguments.length in x6.
3873 __ SmiTag(x6, x0);
3874
3875 // Setup the elements array in x3.
3876 __ LoadRoot(x1, Heap::kFixedArrayMapRootIndex);
3877 __ Str(x1, FieldMemOperand(x3, FixedArray::kMapOffset));
3878 __ Str(x6, FieldMemOperand(x3, FixedArray::kLengthOffset));
3879 __ Add(x4, x3, FixedArray::kHeaderSize);
3880 {
3881 Label loop, done_loop;
3882 __ Add(x0, x4, Operand(x0, LSL, kPointerSizeLog2));
3883 __ Bind(&loop);
3884 __ Cmp(x4, x0);
3885 __ B(eq, &done_loop);
3886 __ Ldr(x5, MemOperand(x2, 0 * kPointerSize));
3887 __ Str(x5, FieldMemOperand(x4, 0 * kPointerSize));
3888 __ Sub(x2, x2, Operand(1 * kPointerSize));
3889 __ Add(x4, x4, Operand(1 * kPointerSize));
3890 __ B(&loop);
3891 __ Bind(&done_loop);
3892 }
3893
3894 // Setup the strict arguments object in x0.
3895 __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, x1);
3896 __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kMapOffset));
3897 __ LoadRoot(x1, Heap::kEmptyFixedArrayRootIndex);
3898 __ Str(x1, FieldMemOperand(x0, JSStrictArgumentsObject::kPropertiesOffset));
3899 __ Str(x3, FieldMemOperand(x0, JSStrictArgumentsObject::kElementsOffset));
3900 __ Str(x6, FieldMemOperand(x0, JSStrictArgumentsObject::kLengthOffset));
3901 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
3902 __ Ret();
3903
3904 // Fall back to %AllocateInNewSpace (if not too big).
3905 Label too_big_for_new_space;
3906 __ Bind(&allocate);
3907 __ Cmp(x6, Operand(kMaxRegularHeapObjectSize));
3908 __ B(gt, &too_big_for_new_space);
3909 {
3910 FrameScope scope(masm, StackFrame::INTERNAL);
3911 __ SmiTag(x0);
3912 __ SmiTag(x6);
3913 __ Push(x0, x2, x6);
3914 __ CallRuntime(Runtime::kAllocateInNewSpace);
3915 __ Mov(x3, x0);
3916 __ Pop(x2, x0);
3917 __ SmiUntag(x0);
3918 }
3919 __ B(&done_allocate);
3920
3921 // Fall back to %NewStrictArguments.
3922 __ Bind(&too_big_for_new_space);
3923 __ Push(x1);
3924 __ TailCallRuntime(Runtime::kNewStrictArguments);
3925 }
3926
3927
3928 // The number of register that CallApiFunctionAndReturn will need to save on 3353 // The number of register that CallApiFunctionAndReturn will need to save on
3929 // the stack. The space for these registers need to be allocated in the 3354 // the stack. The space for these registers need to be allocated in the
3930 // ExitFrame before calling CallApiFunctionAndReturn. 3355 // ExitFrame before calling CallApiFunctionAndReturn.
3931 static const int kCallApiFunctionSpillSpace = 4; 3356 static const int kCallApiFunctionSpillSpace = 4;
3932 3357
3933 3358
3934 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { 3359 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
3935 return static_cast<int>(ref0.address() - ref1.address()); 3360 return static_cast<int>(ref0.address() - ref1.address());
3936 } 3361 }
3937 3362
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
4266 kStackUnwindSpace, NULL, spill_offset, 3691 kStackUnwindSpace, NULL, spill_offset,
4267 return_value_operand, NULL); 3692 return_value_operand, NULL);
4268 } 3693 }
4269 3694
4270 #undef __ 3695 #undef __
4271 3696
4272 } // namespace internal 3697 } // namespace internal
4273 } // namespace v8 3698 } // namespace v8
4274 3699
4275 #endif // V8_TARGET_ARCH_ARM64 3700 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm/interface-descriptors-arm.cc ('k') | src/arm64/interface-descriptors-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698