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

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

Issue 6824081: Add a stub for allocating parameter maps. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/arguments/
Patch Set: '' Created 9 years, 8 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 | Annotate | Revision Log
OLDNEW
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
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 // The displacement is used for skipping the return address and the
3665 // frame pointer on the stack. It is the offset of the last 3665 // frame pointer on the stack. It is the offset of the last
3666 // parameter (if any) relative to the frame pointer. 3666 // parameter (if any) relative to the frame pointer.
3667 static const int kDisplacement = 2 * kPointerSize; 3667 static const int kDisplacement = 2 * kPointerSize;
3668 3668
3669 // Check if the calling frame is an arguments adaptor frame. 3669 // Check if the calling frame is an arguments adaptor frame.
3670 NearLabel runtime;
3671 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
Kevin Millikin (Chromium) 2011/04/27 11:49:28 I think some bit of this code is shared by all thr
rossberg 2011/04/27 23:18:00 Put in a TODO.
3672 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
3673 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3674 __ j(not_equal, &runtime);
3675
3676 // Patch the arguments.length and the parameters pointer.
3677 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3678 __ mov(Operand(esp, 1 * kPointerSize), ecx);
3679 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
3680 __ mov(Operand(esp, 2 * kPointerSize), edx);
3681
3682 // Try the new space allocation. Start out with computing the size of
3683 // the arguments object and the elements array.
3684 __ bind(&runtime);
3685 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
3686 }
3687
3688
3689 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
3690 // esp[0] : return address
3691 // esp[4] : number of parameters (tagged)
3692 // esp[8] : receiver displacement
3693 // esp[12] : function
3694
3695 // The displacement is used for skipping the return address and the
3696 // frame pointer on the stack. It is the offset of the last
3697 // parameter (if any) relative to the frame pointer.
3698 static const int kDisplacement = 2 * kPointerSize;
Kevin Millikin (Chromium) 2011/04/27 11:49:28 It strikes me that kDisplacement is really just St
rossberg 2011/04/27 23:18:00 Done.
3699
3700 // ebx = parameter count (tagged)
3701 __ mov(ebx, Operand(esp, 1 * kPointerSize));
Kevin Millikin (Chromium) 2011/04/27 11:49:28 We have just pushed this before the call. We coul
rossberg 2011/04/27 23:18:00 Does it matter much?
3702
3703 // Check if the calling frame is an arguments adaptor frame.
3704 Label runtime;
3705 NearLabel adaptor_frame, try_allocate;
3706 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3707 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
3708 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3709 __ j(equal, &adaptor_frame);
3710
3711 // No adaptor, parameter count = argument count.
3712 __ mov(ecx, ebx);
3713 __ jmp(&try_allocate);
3714
3715 // We have an adaptor frame. Patch the parameters pointer.
3716 __ bind(&adaptor_frame);
3717 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
Kevin Millikin (Chromium) 2011/04/27 11:49:28 Also, instead of computing the non-adaptor receive
rossberg 2011/04/27 23:18:00 True. I leave that for later.
3718 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
3719 __ mov(Operand(esp, 2 * kPointerSize), edx);
3720
3721 // ebx = parameter count (tagged)
3722 // ecx = argument count (tagged)
3723 // esp[4] = parameter count (tagged)
3724 // esp[8] = address of receiver argument
3725 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
3726 __ cmp(ebx, Operand(ecx));
3727 __ j(less_equal, &try_allocate);
3728 __ mov(ebx, ecx);
3729
3730 __ bind(&try_allocate);
3731
3732 // Save mapped parameter count.
3733 __ push(ebx);
3734
3735 // Compute the sizes of backing store, parameter map, and arguments object.
3736 // 1. Parameter map, has 2 extra words containing context and backing store.
3737 const int kParameterMapHeaderSize =
3738 FixedArray::kHeaderSize + 2 * kPointerSize;
3739 NearLabel no_parameter_map;
3740 __ test(ebx, Operand(ebx));
3741 __ j(zero, &no_parameter_map);
3742 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
3743 __ bind(&no_parameter_map);
3744
3745 // 2. Backing store.
3746 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
3747
3748 // 3. Arguments object.
3749 __ add(Operand(ebx), Immediate(GetArgumentsObjectSize()));
Kevin Millikin (Chromium) 2011/04/27 11:49:28 I think the size is a constant here.
rossberg 2011/04/27 23:18:00 Done (here and elsewhere).
3750
3751 // Do the allocation of all three objects in one go.
3752 __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT);
3753
3754 // eax = address of new object(s) (tagged)
3755 // ecx = argument count (tagged)
3756 // esp[0] = mapped parameter count (tagged)
3757 // esp[8] = parameter count (tagged)
3758 // esp[12] = address of receiver argument
3759 // Get the arguments boilerplate from the current (global) context into edi.
3760 NearLabel has_mapped_parameters, copy;
3761 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
3762 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
3763 __ mov(ebx, Operand(esp, 0 * kPointerSize));
3764 __ test(ebx, Operand(ebx));
3765 __ j(not_zero, &has_mapped_parameters);
3766 __ mov(edi, Operand(edi,
3767 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX)));
3768 __ jmp(&copy);
3769
3770 __ bind(&has_mapped_parameters);
3771 __ mov(edi, Operand(edi,
3772 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX)));
3773 __ bind(&copy);
3774
3775 // eax = address of new object (tagged)
3776 // ebx = mapped parameter count (tagged)
3777 // ecx = argument count (tagged)
3778 // edi = address of boilerplate object (tagged)
3779 // esp[0] = mapped parameter count (tagged)
3780 // esp[8] = parameter count (tagged)
3781 // esp[12] = address of receiver argument
3782 // Copy the JS object part.
3783 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
3784 __ mov(edx, FieldOperand(edi, i));
3785 __ mov(FieldOperand(eax, i), edx);
3786 }
3787
3788 // Setup the callee in-object property.
3789 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
3790 __ mov(edx, Operand(esp, 4 * kPointerSize));
3791 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3792 Heap::kArgumentsCalleeIndex * kPointerSize),
3793 edx);
3794
3795 // Use the length (smi tagged) and set that as an in-object property too.
3796 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
3797 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3798 Heap::kArgumentsLengthIndex * kPointerSize),
3799 ecx);
3800
3801 // Setup the elements pointer in the allocated arguments object.
3802 // If we allocated a parameter map, edi will point there, otherwise to the
3803 // backing store.
3804 __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
3805 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
3806
3807 // eax = address of new object (tagged)
3808 // ebx = mapped parameter count (tagged)
3809 // ecx = argument count (tagged)
3810 // edi = address of parameter map or backing store (tagged)
3811 // esp[0] = mapped parameter count (tagged)
3812 // esp[8] = parameter count (tagged)
3813 // esp[12] = address of receiver argument
3814 // Free a register.
3815 __ push(eax);
3816
3817 // Initialize parameter map. If there are no mapped arguments, we're done.
3818 Label skip_parameter_map;
3819 __ test(ebx, Operand(ebx));
3820 __ j(zero, &skip_parameter_map);
3821
3822 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3823 Immediate(FACTORY->non_strict_arguments_elements_map()));
3824 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
3825 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
3826 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
3827 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
3828 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
3829
3830 // Copy the parameter slots and the holes in the arguments.
3831 // We need to fill in mapped_parameter_count slots. The index the context,
3832 // where parameters are stored in reverse order, at
3833 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
3834 // The mapped parameter thus need to get indices
3835 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
3836 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
3837 // We loop from right to left.
3838 NearLabel parameters_loop, parameters_test;
3839 __ push(ecx);
Kevin Millikin (Chromium) 2011/04/27 11:49:28 It's unfortunate that the parameters are in the re
rossberg 2011/04/27 23:18:00 Yes, I felt that clarity was more important here.
3840 __ mov(eax, Operand(esp, 2 * kPointerSize));
3841 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
3842 __ add(ebx, Operand(esp, 4 * kPointerSize));
3843 __ sub(ebx, Operand(eax));
3844 __ mov(ecx, FACTORY->the_hole_value());
3845 __ mov(edx, edi);
3846 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
3847 // eax = loop variable (tagged)
3848 // ebx = mapping index (tagged)
3849 // ecx = the hole value
3850 // edx = address of parameter map (tagged)
3851 // edi = address of backing store (tagged)
3852 // esp[0] = argument count (tagged)
3853 // esp[4] = address of new object (tagged)
3854 // esp[8] = mapped parameter count (tagged)
3855 // esp[16] = parameter count (tagged)
3856 // esp[20] = address of receiver argument
3857 __ jmp(&parameters_test);
3858
3859 __ bind(&parameters_loop);
3860 __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
3861 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
3862 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
3863 __ add(Operand(ebx), Immediate(Smi::FromInt(1)));
3864 __ bind(&parameters_test);
3865 __ test(eax, Operand(eax));
3866 __ j(not_zero, &parameters_loop);
3867 __ pop(ecx);
3868
3869 __ bind(&skip_parameter_map);
3870
3871 // ecx = argument count (tagged)
3872 // edi = address of backing store (tagged)
3873 // esp[0] = address of new object (tagged)
3874 // esp[4] = mapped parameter count (tagged)
3875 // esp[12] = parameter count (tagged)
3876 // esp[16] = address of receiver argument
3877 // Copy arguments header and remaining slots (if there are any).
3878 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3879 Immediate(FACTORY->fixed_array_map()));
3880 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
3881
3882 NearLabel arguments_loop, arguments_test;
3883 __ mov(ebx, Operand(esp, 1 * kPointerSize));
3884 __ mov(edx, Operand(esp, 4 * kPointerSize));
3885 __ sub(Operand(edx), ebx); // Is there a smarter way to do negative scaling?
3886 __ sub(Operand(edx), ebx);
3887 __ jmp(&arguments_test);
3888 __ bind(&arguments_loop);
3889 __ sub(Operand(edx), Immediate(kPointerSize));
3890 __ mov(eax, Operand(edx, 0));
3891 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
3892 __ add(Operand(ebx), Immediate(Smi::FromInt(1)));
3893 __ bind(&arguments_test);
3894 __ cmp(ebx, Operand(ecx));
3895 __ j(less, &arguments_loop);
3896
3897 // Restore.
3898 __ pop(eax); // Address of arguments object.
3899 __ pop(ebx); // Parameter count.
3900
3901 // Return and remove the on-stack parameters.
3902 __ ret(3 * kPointerSize);
3903
3904 // Do the runtime call to allocate the arguments object.
3905 __ bind(&runtime);
3906 __ pop(eax); // Remove saved parameter count.
3907 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count.
3908 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1);
3909 }
3910
3911
3912 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
3913 // esp[0] : return address
3914 // esp[4] : number of parameters
3915 // esp[8] : receiver displacement
3916 // esp[12] : function
3917
3918 // The displacement is used for skipping the return address and the
3919 // frame pointer on the stack. It is the offset of the last
3920 // parameter (if any) relative to the frame pointer.
3921 static const int kDisplacement = 2 * kPointerSize;
3922
3923 // Check if the calling frame is an arguments adaptor frame.
3670 Label adaptor_frame, try_allocate, runtime; 3924 Label adaptor_frame, try_allocate, runtime;
3671 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3925 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
3672 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 3926 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
3673 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3927 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
3674 __ j(equal, &adaptor_frame); 3928 __ j(equal, &adaptor_frame);
3675 3929
3676 // Get the length from the frame. 3930 // Get the length from the frame.
3677 __ mov(ecx, Operand(esp, 1 * kPointerSize)); 3931 __ mov(ecx, Operand(esp, 1 * kPointerSize));
3678 __ jmp(&try_allocate); 3932 __ jmp(&try_allocate);
3679 3933
3680 // Patch the arguments.length and the parameters pointer. 3934 // Patch the arguments.length and the parameters pointer.
3681 __ bind(&adaptor_frame); 3935 __ bind(&adaptor_frame);
3682 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3936 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3683 __ mov(Operand(esp, 1 * kPointerSize), ecx); 3937 __ mov(Operand(esp, 1 * kPointerSize), ecx);
3684 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); 3938 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement));
3685 __ mov(Operand(esp, 2 * kPointerSize), edx); 3939 __ mov(Operand(esp, 2 * kPointerSize), edx);
3686 3940
3687 // Try the new space allocation. Start out with computing the size of 3941 // Try the new space allocation. Start out with computing the size of
3688 // the arguments object and the elements array. 3942 // the arguments object and the elements array.
3689 NearLabel add_arguments_object; 3943 NearLabel add_arguments_object;
3690 __ bind(&try_allocate); 3944 __ bind(&try_allocate);
3691 if (type_ == NEW_NON_STRICT) { 3945 __ test(ecx, Operand(ecx));
3692 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 3946 __ j(zero, &add_arguments_object);
3693 } else { 3947 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
3694 __ test(ecx, Operand(ecx)); 3948 __ bind(&add_arguments_object);
3695 __ j(zero, &add_arguments_object); 3949 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize()));
3696 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize));
3697 __ bind(&add_arguments_object);
3698 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize()));
3699 3950
3700 // Do the allocation of both objects in one go. 3951 // Do the allocation of both objects in one go.
3701 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); 3952 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT);
3702 3953
3703 // Get the arguments boilerplate from the current (global) context. 3954 // Get the arguments boilerplate from the current (global) context.
3704 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 3955 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
3705 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); 3956 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset));
3706 __ mov(edi, Operand(edi, 3957 const int offset =
3707 Context::SlotOffset(GetArgumentsBoilerplateIndex()))); 3958 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX);
3959 __ mov(edi, Operand(edi, offset));
3708 3960
3709 // Copy the JS object part. 3961 // Copy the JS object part.
3710 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 3962 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
3711 __ mov(ebx, FieldOperand(edi, i)); 3963 __ mov(ebx, FieldOperand(edi, i));
3712 __ mov(FieldOperand(eax, i), ebx); 3964 __ mov(FieldOperand(eax, i), ebx);
3713 } 3965 }
3714 3966
3715 if (type_ == NEW_NON_STRICT) { 3967 // Get the length (smi tagged) and set that as an in-object property too.
3716 // Setup the callee in-object property. 3968 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
3717 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 3969 __ mov(ecx, Operand(esp, 1 * kPointerSize));
3718 __ mov(ebx, Operand(esp, 3 * kPointerSize)); 3970 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
3719 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 3971 Heap::kArgumentsLengthIndex * kPointerSize),
3720 Heap::kArgumentsCalleeIndex * kPointerSize), 3972 ecx);
3721 ebx);
3722 }
3723 3973
3724 // Get the length (smi tagged) and set that as an in-object property too. 3974 // If there are no actual arguments, we're done.
3725 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 3975 Label done;
3726 __ mov(ecx, Operand(esp, 1 * kPointerSize)); 3976 __ test(ecx, Operand(ecx));
3727 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 3977 __ j(zero, &done);
3728 Heap::kArgumentsLengthIndex * kPointerSize),
3729 ecx);
3730 3978
3731 // If there are no actual arguments, we're done. 3979 // Get the parameters pointer from the stack.
3732 Label done; 3980 __ mov(edx, Operand(esp, 2 * kPointerSize));
3733 __ test(ecx, Operand(ecx));
3734 __ j(zero, &done);
3735 3981
3736 // Get the parameters pointer from the stack. 3982 // Setup the elements pointer in the allocated arguments object and
3737 __ mov(edx, Operand(esp, 2 * kPointerSize)); 3983 // initialize the header in the elements fixed array.
3984 __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
3985 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
3986 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3987 Immediate(FACTORY->fixed_array_map()));
3738 3988
3739 // Setup the elements pointer in the allocated arguments object and 3989 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
3740 // initialize the header in the elements fixed array. 3990 // Untag the length for the loop below.
3741 __ lea(edi, Operand(eax, GetArgumentsObjectSize())); 3991 __ SmiUntag(ecx);
3742 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
3743 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
3744 Immediate(FACTORY->fixed_array_map()));
3745 3992
3746 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 3993 // Copy the fixed array slots.
3747 // Untag the length for the loop below. 3994 NearLabel loop;
3748 __ SmiUntag(ecx); 3995 __ bind(&loop);
3996 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
3997 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
3998 __ add(Operand(edi), Immediate(kPointerSize));
3999 __ sub(Operand(edx), Immediate(kPointerSize));
4000 __ dec(ecx);
4001 __ j(not_zero, &loop);
3749 4002
3750 // Copy the fixed array slots. 4003 // Return and remove the on-stack parameters.
3751 NearLabel loop; 4004 __ bind(&done);
3752 __ bind(&loop); 4005 __ 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 4006
3760 // Return and remove the on-stack parameters. 4007 // Do the runtime call to allocate the arguments object.
3761 __ bind(&done); 4008 __ bind(&runtime);
3762 __ ret(3 * kPointerSize); 4009 __ 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 } 4010 }
3769 4011
3770 4012
3771 void RegExpExecStub::Generate(MacroAssembler* masm) { 4013 void RegExpExecStub::Generate(MacroAssembler* masm) {
3772 // Just jump directly to runtime if native RegExp is not selected at compile 4014 // 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 4015 // time or if regexp entry in generated code is turned off runtime switch or
3774 // at compilation. 4016 // at compilation.
3775 #ifdef V8_INTERPRETED_REGEXP 4017 #ifdef V8_INTERPRETED_REGEXP
3776 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 4018 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
3777 #else // V8_INTERPRETED_REGEXP 4019 #else // V8_INTERPRETED_REGEXP
(...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after
6544 // Do a tail call to the rewritten stub. 6786 // Do a tail call to the rewritten stub.
6545 __ jmp(Operand(edi)); 6787 __ jmp(Operand(edi));
6546 } 6788 }
6547 6789
6548 6790
6549 #undef __ 6791 #undef __
6550 6792
6551 } } // namespace v8::internal 6793 } } // namespace v8::internal
6552 6794
6553 #endif // V8_TARGET_ARCH_IA32 6795 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/code-stubs.h ('K') | « src/contexts.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698