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

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, 7 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
« no previous file with comments | « src/contexts.h ('k') | src/ia32/codegen-ia32.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 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 // 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(&copy);
3763
3764 __ bind(&has_mapped_parameters);
3765 __ mov(edi, Operand(edi,
3766 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX)));
3767 __ bind(&copy);
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(&parameters_test);
3852
3853 __ bind(&parameters_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(&parameters_test);
3859 __ test(eax, Operand(eax));
3860 __ j(not_zero, &parameters_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
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
OLDNEW
« no previous file with comments | « src/contexts.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698