| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3648 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 3648 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
| 3649 // by calling the runtime system. | 3649 // by calling the runtime system. |
| 3650 __ bind(&slow); | 3650 __ bind(&slow); |
| 3651 __ pop(ebx); // Return address. | 3651 __ pop(ebx); // Return address. |
| 3652 __ push(edx); | 3652 __ push(edx); |
| 3653 __ push(ebx); | 3653 __ push(ebx); |
| 3654 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); | 3654 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); |
| 3655 } | 3655 } |
| 3656 | 3656 |
| 3657 | 3657 |
| 3658 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { | 3658 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { |
| 3659 // esp[0] : return address | 3659 // esp[0] : return address |
| 3660 // esp[4] : number of parameters | 3660 // esp[4] : number of parameters |
| 3661 // esp[8] : receiver displacement | 3661 // esp[8] : receiver displacement |
| 3662 // esp[12] : function | 3662 // esp[12] : function |
| 3663 | 3663 |
| 3664 // The displacement is used for skipping the return address and the | 3664 // Check if the calling frame is an arguments adaptor frame. |
| 3665 // frame pointer on the stack. It is the offset of the last | 3665 NearLabel runtime; |
| 3666 // parameter (if any) relative to the frame pointer. | 3666 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 3667 static const int kDisplacement = 2 * kPointerSize; | 3667 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
| 3668 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 3669 __ j(not_equal, &runtime); |
| 3670 |
| 3671 // Patch the arguments.length and the parameters pointer. |
| 3672 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 3673 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
| 3674 __ lea(edx, Operand(edx, ecx, times_2, |
| 3675 » » StandardFrameConstants::kCallerSPOffset)); |
| 3676 __ mov(Operand(esp, 2 * kPointerSize), edx); |
| 3677 |
| 3678 // Try the new space allocation. Start out with computing the size of |
| 3679 // the arguments object and the elements array. |
| 3680 __ bind(&runtime); |
| 3681 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); |
| 3682 } |
| 3683 |
| 3684 |
| 3685 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) { |
| 3686 // esp[0] : return address |
| 3687 // esp[4] : number of parameters (tagged) |
| 3688 // esp[8] : receiver displacement |
| 3689 // esp[12] : function |
| 3690 |
| 3691 // ebx = parameter count (tagged) |
| 3692 __ mov(ebx, Operand(esp, 1 * kPointerSize)); |
| 3693 |
| 3694 // Check if the calling frame is an arguments adaptor frame. |
| 3695 // TODO(rossberg): Factor out some of the bits that are shared with the other |
| 3696 // Generate* functions. |
| 3697 Label runtime; |
| 3698 NearLabel adaptor_frame, try_allocate; |
| 3699 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 3700 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
| 3701 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 3702 __ j(equal, &adaptor_frame); |
| 3703 |
| 3704 // No adaptor, parameter count = argument count. |
| 3705 __ mov(ecx, ebx); |
| 3706 __ jmp(&try_allocate); |
| 3707 |
| 3708 // We have an adaptor frame. Patch the parameters pointer. |
| 3709 __ bind(&adaptor_frame); |
| 3710 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 3711 __ lea(edx, Operand(edx, ecx, times_2, |
| 3712 » » StandardFrameConstants::kCallerSPOffset)); |
| 3713 __ mov(Operand(esp, 2 * kPointerSize), edx); |
| 3714 |
| 3715 // ebx = parameter count (tagged) |
| 3716 // ecx = argument count (tagged) |
| 3717 // esp[4] = parameter count (tagged) |
| 3718 // esp[8] = address of receiver argument |
| 3719 // Compute the mapped parameter count = min(ebx, ecx) in ebx. |
| 3720 __ cmp(ebx, Operand(ecx)); |
| 3721 __ j(less_equal, &try_allocate); |
| 3722 __ mov(ebx, ecx); |
| 3723 |
| 3724 __ bind(&try_allocate); |
| 3725 |
| 3726 // Save mapped parameter count. |
| 3727 __ push(ebx); |
| 3728 |
| 3729 // Compute the sizes of backing store, parameter map, and arguments object. |
| 3730 // 1. Parameter map, has 2 extra words containing context and backing store. |
| 3731 const int kParameterMapHeaderSize = |
| 3732 FixedArray::kHeaderSize + 2 * kPointerSize; |
| 3733 NearLabel no_parameter_map; |
| 3734 __ test(ebx, Operand(ebx)); |
| 3735 __ j(zero, &no_parameter_map); |
| 3736 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); |
| 3737 __ bind(&no_parameter_map); |
| 3738 |
| 3739 // 2. Backing store. |
| 3740 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); |
| 3741 |
| 3742 // 3. Arguments object. |
| 3743 __ add(Operand(ebx), Immediate(Heap::kArgumentsObjectSize)); |
| 3744 |
| 3745 // Do the allocation of all three objects in one go. |
| 3746 __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT); |
| 3747 |
| 3748 // eax = address of new object(s) (tagged) |
| 3749 // ecx = argument count (tagged) |
| 3750 // esp[0] = mapped parameter count (tagged) |
| 3751 // esp[8] = parameter count (tagged) |
| 3752 // esp[12] = address of receiver argument |
| 3753 // Get the arguments boilerplate from the current (global) context into edi. |
| 3754 NearLabel has_mapped_parameters, copy; |
| 3755 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 3756 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); |
| 3757 __ mov(ebx, Operand(esp, 0 * kPointerSize)); |
| 3758 __ test(ebx, Operand(ebx)); |
| 3759 __ j(not_zero, &has_mapped_parameters); |
| 3760 __ mov(edi, Operand(edi, |
| 3761 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX))); |
| 3762 __ jmp(©); |
| 3763 |
| 3764 __ bind(&has_mapped_parameters); |
| 3765 __ mov(edi, Operand(edi, |
| 3766 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); |
| 3767 __ bind(©); |
| 3768 |
| 3769 // eax = address of new object (tagged) |
| 3770 // ebx = mapped parameter count (tagged) |
| 3771 // ecx = argument count (tagged) |
| 3772 // edi = address of boilerplate object (tagged) |
| 3773 // esp[0] = mapped parameter count (tagged) |
| 3774 // esp[8] = parameter count (tagged) |
| 3775 // esp[12] = address of receiver argument |
| 3776 // Copy the JS object part. |
| 3777 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
| 3778 __ mov(edx, FieldOperand(edi, i)); |
| 3779 __ mov(FieldOperand(eax, i), edx); |
| 3780 } |
| 3781 |
| 3782 // Setup the callee in-object property. |
| 3783 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
| 3784 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
| 3785 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 3786 Heap::kArgumentsCalleeIndex * kPointerSize), |
| 3787 edx); |
| 3788 |
| 3789 // Use the length (smi tagged) and set that as an in-object property too. |
| 3790 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
| 3791 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 3792 Heap::kArgumentsLengthIndex * kPointerSize), |
| 3793 ecx); |
| 3794 |
| 3795 // Setup the elements pointer in the allocated arguments object. |
| 3796 // If we allocated a parameter map, edi will point there, otherwise to the |
| 3797 // backing store. |
| 3798 __ lea(edi, Operand(eax, Heap::kArgumentsObjectSize)); |
| 3799 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
| 3800 |
| 3801 // eax = address of new object (tagged) |
| 3802 // ebx = mapped parameter count (tagged) |
| 3803 // ecx = argument count (tagged) |
| 3804 // edi = address of parameter map or backing store (tagged) |
| 3805 // esp[0] = mapped parameter count (tagged) |
| 3806 // esp[8] = parameter count (tagged) |
| 3807 // esp[12] = address of receiver argument |
| 3808 // Free a register. |
| 3809 __ push(eax); |
| 3810 |
| 3811 // Initialize parameter map. If there are no mapped arguments, we're done. |
| 3812 Label skip_parameter_map; |
| 3813 __ test(ebx, Operand(ebx)); |
| 3814 __ j(zero, &skip_parameter_map); |
| 3815 |
| 3816 __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
| 3817 Immediate(FACTORY->non_strict_arguments_elements_map())); |
| 3818 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); |
| 3819 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); |
| 3820 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); |
| 3821 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); |
| 3822 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); |
| 3823 |
| 3824 // Copy the parameter slots and the holes in the arguments. |
| 3825 // We need to fill in mapped_parameter_count slots. They index the context, |
| 3826 // where parameters are stored in reverse order, at |
| 3827 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 |
| 3828 // The mapped parameter thus need to get indices |
| 3829 // MIN_CONTEXT_SLOTS+parameter_count-1 .. |
| 3830 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count |
| 3831 // We loop from right to left. |
| 3832 NearLabel parameters_loop, parameters_test; |
| 3833 __ push(ecx); |
| 3834 __ mov(eax, Operand(esp, 2 * kPointerSize)); |
| 3835 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); |
| 3836 __ add(ebx, Operand(esp, 4 * kPointerSize)); |
| 3837 __ sub(ebx, Operand(eax)); |
| 3838 __ mov(ecx, FACTORY->the_hole_value()); |
| 3839 __ mov(edx, edi); |
| 3840 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); |
| 3841 // eax = loop variable (tagged) |
| 3842 // ebx = mapping index (tagged) |
| 3843 // ecx = the hole value |
| 3844 // edx = address of parameter map (tagged) |
| 3845 // edi = address of backing store (tagged) |
| 3846 // esp[0] = argument count (tagged) |
| 3847 // esp[4] = address of new object (tagged) |
| 3848 // esp[8] = mapped parameter count (tagged) |
| 3849 // esp[16] = parameter count (tagged) |
| 3850 // esp[20] = address of receiver argument |
| 3851 __ jmp(¶meters_test); |
| 3852 |
| 3853 __ bind(¶meters_loop); |
| 3854 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); |
| 3855 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx); |
| 3856 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx); |
| 3857 __ add(Operand(ebx), Immediate(Smi::FromInt(1))); |
| 3858 __ bind(¶meters_test); |
| 3859 __ test(eax, Operand(eax)); |
| 3860 __ j(not_zero, ¶meters_loop); |
| 3861 __ pop(ecx); |
| 3862 |
| 3863 __ bind(&skip_parameter_map); |
| 3864 |
| 3865 // ecx = argument count (tagged) |
| 3866 // edi = address of backing store (tagged) |
| 3867 // esp[0] = address of new object (tagged) |
| 3868 // esp[4] = mapped parameter count (tagged) |
| 3869 // esp[12] = parameter count (tagged) |
| 3870 // esp[16] = address of receiver argument |
| 3871 // Copy arguments header and remaining slots (if there are any). |
| 3872 __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
| 3873 Immediate(FACTORY->fixed_array_map())); |
| 3874 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); |
| 3875 |
| 3876 NearLabel arguments_loop, arguments_test; |
| 3877 __ mov(ebx, Operand(esp, 1 * kPointerSize)); |
| 3878 __ mov(edx, Operand(esp, 4 * kPointerSize)); |
| 3879 __ sub(Operand(edx), ebx); // Is there a smarter way to do negative scaling? |
| 3880 __ sub(Operand(edx), ebx); |
| 3881 __ jmp(&arguments_test); |
| 3882 __ bind(&arguments_loop); |
| 3883 __ sub(Operand(edx), Immediate(kPointerSize)); |
| 3884 __ mov(eax, Operand(edx, 0)); |
| 3885 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax); |
| 3886 __ add(Operand(ebx), Immediate(Smi::FromInt(1))); |
| 3887 __ bind(&arguments_test); |
| 3888 __ cmp(ebx, Operand(ecx)); |
| 3889 __ j(less, &arguments_loop); |
| 3890 |
| 3891 // Restore. |
| 3892 __ pop(eax); // Address of arguments object. |
| 3893 __ pop(ebx); // Parameter count. |
| 3894 |
| 3895 // Return and remove the on-stack parameters. |
| 3896 __ ret(3 * kPointerSize); |
| 3897 |
| 3898 // Do the runtime call to allocate the arguments object. |
| 3899 __ bind(&runtime); |
| 3900 __ pop(eax); // Remove saved parameter count. |
| 3901 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. |
| 3902 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); |
| 3903 } |
| 3904 |
| 3905 |
| 3906 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
| 3907 // esp[0] : return address |
| 3908 // esp[4] : number of parameters |
| 3909 // esp[8] : receiver displacement |
| 3910 // esp[12] : function |
| 3668 | 3911 |
| 3669 // Check if the calling frame is an arguments adaptor frame. | 3912 // Check if the calling frame is an arguments adaptor frame. |
| 3670 Label adaptor_frame, try_allocate, runtime; | 3913 Label adaptor_frame, try_allocate, runtime; |
| 3671 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 3914 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 3672 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 3915 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
| 3673 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 3916 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 3674 __ j(equal, &adaptor_frame); | 3917 __ j(equal, &adaptor_frame); |
| 3675 | 3918 |
| 3676 // Get the length from the frame. | 3919 // Get the length from the frame. |
| 3677 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 3920 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
| 3678 __ jmp(&try_allocate); | 3921 __ jmp(&try_allocate); |
| 3679 | 3922 |
| 3680 // Patch the arguments.length and the parameters pointer. | 3923 // Patch the arguments.length and the parameters pointer. |
| 3681 __ bind(&adaptor_frame); | 3924 __ bind(&adaptor_frame); |
| 3682 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 3925 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 3683 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 3926 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
| 3684 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); | 3927 __ lea(edx, Operand(edx, ecx, times_2, |
| 3928 » » StandardFrameConstants::kCallerSPOffset)); |
| 3685 __ mov(Operand(esp, 2 * kPointerSize), edx); | 3929 __ mov(Operand(esp, 2 * kPointerSize), edx); |
| 3686 | 3930 |
| 3687 // Try the new space allocation. Start out with computing the size of | 3931 // Try the new space allocation. Start out with computing the size of |
| 3688 // the arguments object and the elements array. | 3932 // the arguments object and the elements array. |
| 3689 NearLabel add_arguments_object; | 3933 NearLabel add_arguments_object; |
| 3690 __ bind(&try_allocate); | 3934 __ bind(&try_allocate); |
| 3691 if (type_ == NEW_NON_STRICT) { | 3935 __ test(ecx, Operand(ecx)); |
| 3692 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); | 3936 __ j(zero, &add_arguments_object); |
| 3693 } else { | 3937 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
| 3694 __ test(ecx, Operand(ecx)); | 3938 __ bind(&add_arguments_object); |
| 3695 __ j(zero, &add_arguments_object); | 3939 __ add(Operand(ecx), Immediate(Heap::kArgumentsObjectSizeStrict)); |
| 3696 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | |
| 3697 __ bind(&add_arguments_object); | |
| 3698 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize())); | |
| 3699 | 3940 |
| 3700 // Do the allocation of both objects in one go. | 3941 // Do the allocation of both objects in one go. |
| 3701 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 3942 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
| 3702 | 3943 |
| 3703 // Get the arguments boilerplate from the current (global) context. | 3944 // Get the arguments boilerplate from the current (global) context. |
| 3704 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 3945 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 3705 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | 3946 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); |
| 3706 __ mov(edi, Operand(edi, | 3947 const int offset = |
| 3707 Context::SlotOffset(GetArgumentsBoilerplateIndex()))); | 3948 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); |
| 3949 __ mov(edi, Operand(edi, offset)); |
| 3708 | 3950 |
| 3709 // Copy the JS object part. | 3951 // Copy the JS object part. |
| 3710 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 3952 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
| 3711 __ mov(ebx, FieldOperand(edi, i)); | 3953 __ mov(ebx, FieldOperand(edi, i)); |
| 3712 __ mov(FieldOperand(eax, i), ebx); | 3954 __ mov(FieldOperand(eax, i), ebx); |
| 3713 } | 3955 } |
| 3714 | 3956 |
| 3715 if (type_ == NEW_NON_STRICT) { | 3957 // Get the length (smi tagged) and set that as an in-object property too. |
| 3716 // Setup the callee in-object property. | 3958 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
| 3717 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | 3959 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
| 3718 __ mov(ebx, Operand(esp, 3 * kPointerSize)); | 3960 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 3719 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 3961 Heap::kArgumentsLengthIndex * kPointerSize), |
| 3720 Heap::kArgumentsCalleeIndex * kPointerSize), | 3962 ecx); |
| 3721 ebx); | |
| 3722 } | |
| 3723 | 3963 |
| 3724 // Get the length (smi tagged) and set that as an in-object property too. | 3964 // If there are no actual arguments, we're done. |
| 3725 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 3965 Label done; |
| 3726 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 3966 __ test(ecx, Operand(ecx)); |
| 3727 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 3967 __ j(zero, &done); |
| 3728 Heap::kArgumentsLengthIndex * kPointerSize), | |
| 3729 ecx); | |
| 3730 | 3968 |
| 3731 // If there are no actual arguments, we're done. | 3969 // Get the parameters pointer from the stack. |
| 3732 Label done; | 3970 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
| 3733 __ test(ecx, Operand(ecx)); | |
| 3734 __ j(zero, &done); | |
| 3735 | 3971 |
| 3736 // Get the parameters pointer from the stack. | 3972 // Setup the elements pointer in the allocated arguments object and |
| 3737 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 3973 // initialize the header in the elements fixed array. |
| 3974 __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict)); |
| 3975 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
| 3976 __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
| 3977 Immediate(FACTORY->fixed_array_map())); |
| 3738 | 3978 |
| 3739 // Setup the elements pointer in the allocated arguments object and | 3979 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); |
| 3740 // initialize the header in the elements fixed array. | 3980 // Untag the length for the loop below. |
| 3741 __ lea(edi, Operand(eax, GetArgumentsObjectSize())); | 3981 __ SmiUntag(ecx); |
| 3742 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | |
| 3743 __ mov(FieldOperand(edi, FixedArray::kMapOffset), | |
| 3744 Immediate(FACTORY->fixed_array_map())); | |
| 3745 | 3982 |
| 3746 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); | 3983 // Copy the fixed array slots. |
| 3747 // Untag the length for the loop below. | 3984 NearLabel loop; |
| 3748 __ SmiUntag(ecx); | 3985 __ bind(&loop); |
| 3986 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. |
| 3987 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); |
| 3988 __ add(Operand(edi), Immediate(kPointerSize)); |
| 3989 __ sub(Operand(edx), Immediate(kPointerSize)); |
| 3990 __ dec(ecx); |
| 3991 __ j(not_zero, &loop); |
| 3749 | 3992 |
| 3750 // Copy the fixed array slots. | 3993 // Return and remove the on-stack parameters. |
| 3751 NearLabel loop; | 3994 __ bind(&done); |
| 3752 __ bind(&loop); | 3995 __ ret(3 * kPointerSize); |
| 3753 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. | |
| 3754 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); | |
| 3755 __ add(Operand(edi), Immediate(kPointerSize)); | |
| 3756 __ sub(Operand(edx), Immediate(kPointerSize)); | |
| 3757 __ dec(ecx); | |
| 3758 __ j(not_zero, &loop); | |
| 3759 | 3996 |
| 3760 // Return and remove the on-stack parameters. | 3997 // Do the runtime call to allocate the arguments object. |
| 3761 __ bind(&done); | 3998 __ bind(&runtime); |
| 3762 __ ret(3 * kPointerSize); | 3999 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); |
| 3763 | |
| 3764 // Do the runtime call to allocate the arguments object. | |
| 3765 __ bind(&runtime); | |
| 3766 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); | |
| 3767 } | |
| 3768 } | 4000 } |
| 3769 | 4001 |
| 3770 | 4002 |
| 3771 void RegExpExecStub::Generate(MacroAssembler* masm) { | 4003 void RegExpExecStub::Generate(MacroAssembler* masm) { |
| 3772 // Just jump directly to runtime if native RegExp is not selected at compile | 4004 // Just jump directly to runtime if native RegExp is not selected at compile |
| 3773 // time or if regexp entry in generated code is turned off runtime switch or | 4005 // time or if regexp entry in generated code is turned off runtime switch or |
| 3774 // at compilation. | 4006 // at compilation. |
| 3775 #ifdef V8_INTERPRETED_REGEXP | 4007 #ifdef V8_INTERPRETED_REGEXP |
| 3776 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 4008 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
| 3777 #else // V8_INTERPRETED_REGEXP | 4009 #else // V8_INTERPRETED_REGEXP |
| (...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6544 // Do a tail call to the rewritten stub. | 6776 // Do a tail call to the rewritten stub. |
| 6545 __ jmp(Operand(edi)); | 6777 __ jmp(Operand(edi)); |
| 6546 } | 6778 } |
| 6547 | 6779 |
| 6548 | 6780 |
| 6549 #undef __ | 6781 #undef __ |
| 6550 | 6782 |
| 6551 } } // namespace v8::internal | 6783 } } // namespace v8::internal |
| 6552 | 6784 |
| 6553 #endif // V8_TARGET_ARCH_IA32 | 6785 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |