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

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

Issue 1695633003: [runtime] Turn ArgumentAccessStub into FastNewSloppyArgumentsStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix MIPS dead code Created 4 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/full-codegen/x64/full-codegen-x64.cc ('k') | src/ia32/interface-descriptors-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 720
721 StubRuntimeCallHelper call_helper; 721 StubRuntimeCallHelper call_helper;
722 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); 722 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper);
723 723
724 __ bind(&miss); 724 __ bind(&miss);
725 PropertyAccessCompiler::TailCallBuiltin( 725 PropertyAccessCompiler::TailCallBuiltin(
726 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 726 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
727 } 727 }
728 728
729 729
730 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
731 // ecx : number of parameters (tagged)
732 // edx : parameters pointer
733 // edi : function
734 // esp[0] : return address
735
736 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
737 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
738 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
739
740 // Check if the calling frame is an arguments adaptor frame.
741 Label runtime;
742 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
743 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
744 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
745 __ j(not_equal, &runtime, Label::kNear);
746
747 // Patch the arguments.length and the parameters pointer.
748 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
749 __ lea(edx,
750 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
751
752 __ bind(&runtime);
753 __ pop(eax); // Pop return address.
754 __ push(edi); // Push function.
755 __ push(edx); // Push parameters pointer.
756 __ push(ecx); // Push parameter count.
757 __ push(eax); // Push return address.
758 __ TailCallRuntime(Runtime::kNewSloppyArguments);
759 }
760
761
762 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
763 // ecx : number of parameters (tagged)
764 // edx : parameters pointer
765 // edi : function
766 // esp[0] : return address
767
768 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
769 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
770 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
771
772 // Check if the calling frame is an arguments adaptor frame.
773 Label adaptor_frame, try_allocate, runtime;
774 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
775 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
776 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
777 __ j(equal, &adaptor_frame, Label::kNear);
778
779 // No adaptor, parameter count = argument count.
780 __ mov(ebx, ecx);
781 __ push(ecx);
782 __ jmp(&try_allocate, Label::kNear);
783
784 // We have an adaptor frame. Patch the parameters pointer.
785 __ bind(&adaptor_frame);
786 __ mov(ebx, ecx);
787 __ push(ecx);
788 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
789 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
790 __ lea(edx, Operand(edx, ecx, times_2,
791 StandardFrameConstants::kCallerSPOffset));
792
793 // ebx = parameter count (tagged)
794 // ecx = argument count (smi-tagged)
795 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
796 __ cmp(ebx, ecx);
797 __ j(less_equal, &try_allocate, Label::kNear);
798 __ mov(ebx, ecx);
799
800 // Save mapped parameter count and function.
801 __ bind(&try_allocate);
802 __ push(edi);
803 __ push(ebx);
804
805 // Compute the sizes of backing store, parameter map, and arguments object.
806 // 1. Parameter map, has 2 extra words containing context and backing store.
807 const int kParameterMapHeaderSize =
808 FixedArray::kHeaderSize + 2 * kPointerSize;
809 Label no_parameter_map;
810 __ test(ebx, ebx);
811 __ j(zero, &no_parameter_map, Label::kNear);
812 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
813 __ bind(&no_parameter_map);
814
815 // 2. Backing store.
816 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
817
818 // 3. Arguments object.
819 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
820
821 // Do the allocation of all three objects in one go.
822 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
823
824 // eax = address of new object(s) (tagged)
825 // ecx = argument count (smi-tagged)
826 // esp[0] = mapped parameter count (tagged)
827 // esp[4] = function
828 // esp[8] = parameter count (tagged)
829 // Get the arguments map from the current native context into edi.
830 Label has_mapped_parameters, instantiate;
831 __ mov(edi, NativeContextOperand());
832 __ mov(ebx, Operand(esp, 0 * kPointerSize));
833 __ test(ebx, ebx);
834 __ j(not_zero, &has_mapped_parameters, Label::kNear);
835 __ mov(
836 edi,
837 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
838 __ jmp(&instantiate, Label::kNear);
839
840 __ bind(&has_mapped_parameters);
841 __ mov(edi, Operand(edi, Context::SlotOffset(
842 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
843 __ bind(&instantiate);
844
845 // eax = address of new object (tagged)
846 // ebx = mapped parameter count (tagged)
847 // ecx = argument count (smi-tagged)
848 // edi = address of arguments map (tagged)
849 // esp[0] = mapped parameter count (tagged)
850 // esp[4] = function
851 // esp[8] = parameter count (tagged)
852 // Copy the JS object part.
853 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
854 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
855 masm->isolate()->factory()->empty_fixed_array());
856 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
857 masm->isolate()->factory()->empty_fixed_array());
858
859 // Set up the callee in-object property.
860 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
861 __ mov(edi, Operand(esp, 1 * kPointerSize));
862 __ AssertNotSmi(edi);
863 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
864
865 // Use the length (smi tagged) and set that as an in-object property too.
866 __ AssertSmi(ecx);
867 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
868
869 // Set up the elements pointer in the allocated arguments object.
870 // If we allocated a parameter map, edi will point there, otherwise to the
871 // backing store.
872 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
873 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
874
875 // eax = address of new object (tagged)
876 // ebx = mapped parameter count (tagged)
877 // ecx = argument count (tagged)
878 // edx = address of receiver argument
879 // edi = address of parameter map or backing store (tagged)
880 // esp[0] = mapped parameter count (tagged)
881 // esp[4] = function
882 // esp[8] = parameter count (tagged)
883 // Free two registers.
884 __ push(edx);
885 __ push(eax);
886
887 // Initialize parameter map. If there are no mapped arguments, we're done.
888 Label skip_parameter_map;
889 __ test(ebx, ebx);
890 __ j(zero, &skip_parameter_map);
891
892 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
893 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
894 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
895 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
896 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
897 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
898 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
899
900 // Copy the parameter slots and the holes in the arguments.
901 // We need to fill in mapped_parameter_count slots. They index the context,
902 // where parameters are stored in reverse order, at
903 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
904 // The mapped parameter thus need to get indices
905 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
906 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
907 // We loop from right to left.
908 Label parameters_loop, parameters_test;
909 __ push(ecx);
910 __ mov(eax, Operand(esp, 3 * kPointerSize));
911 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
912 __ add(ebx, Operand(esp, 5 * kPointerSize));
913 __ sub(ebx, eax);
914 __ mov(ecx, isolate()->factory()->the_hole_value());
915 __ mov(edx, edi);
916 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
917 // eax = loop variable (tagged)
918 // ebx = mapping index (tagged)
919 // ecx = the hole value
920 // edx = address of parameter map (tagged)
921 // edi = address of backing store (tagged)
922 // esp[0] = argument count (tagged)
923 // esp[4] = address of new object (tagged)
924 // esp[8] = address of receiver argument
925 // esp[12] = mapped parameter count (tagged)
926 // esp[16] = function
927 // esp[20] = parameter count (tagged)
928 __ jmp(&parameters_test, Label::kNear);
929
930 __ bind(&parameters_loop);
931 __ sub(eax, Immediate(Smi::FromInt(1)));
932 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
933 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
934 __ add(ebx, Immediate(Smi::FromInt(1)));
935 __ bind(&parameters_test);
936 __ test(eax, eax);
937 __ j(not_zero, &parameters_loop, Label::kNear);
938 __ pop(ecx);
939
940 __ bind(&skip_parameter_map);
941
942 // ecx = argument count (tagged)
943 // edi = address of backing store (tagged)
944 // esp[0] = address of new object (tagged)
945 // esp[4] = address of receiver argument
946 // esp[8] = mapped parameter count (tagged)
947 // esp[12] = function
948 // esp[16] = parameter count (tagged)
949 // Copy arguments header and remaining slots (if there are any).
950 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
951 Immediate(isolate()->factory()->fixed_array_map()));
952 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
953
954 Label arguments_loop, arguments_test;
955 __ mov(ebx, Operand(esp, 2 * kPointerSize));
956 __ mov(edx, Operand(esp, 1 * kPointerSize));
957 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
958 __ sub(edx, ebx);
959 __ jmp(&arguments_test, Label::kNear);
960
961 __ bind(&arguments_loop);
962 __ sub(edx, Immediate(kPointerSize));
963 __ mov(eax, Operand(edx, 0));
964 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
965 __ add(ebx, Immediate(Smi::FromInt(1)));
966
967 __ bind(&arguments_test);
968 __ cmp(ebx, ecx);
969 __ j(less, &arguments_loop, Label::kNear);
970
971 // Restore.
972 __ pop(eax); // Address of arguments object.
973 __ Drop(4);
974
975 // Return.
976 __ ret(0);
977
978 // Do the runtime call to allocate the arguments object.
979 __ bind(&runtime);
980 __ pop(eax); // Remove saved mapped parameter count.
981 __ pop(edi); // Pop saved function.
982 __ pop(eax); // Remove saved parameter count.
983 __ pop(eax); // Pop return address.
984 __ push(edi); // Push function.
985 __ push(edx); // Push parameters pointer.
986 __ push(ecx); // Push parameter count.
987 __ push(eax); // Push return address.
988 __ TailCallRuntime(Runtime::kNewSloppyArguments);
989 }
990
991
992 void RegExpExecStub::Generate(MacroAssembler* masm) { 730 void RegExpExecStub::Generate(MacroAssembler* masm) {
993 // Just jump directly to runtime if native RegExp is not selected at compile 731 // Just jump directly to runtime if native RegExp is not selected at compile
994 // time or if regexp entry in generated code is turned off runtime switch or 732 // time or if regexp entry in generated code is turned off runtime switch or
995 // at compilation. 733 // at compilation.
996 #ifdef V8_INTERPRETED_REGEXP 734 #ifdef V8_INTERPRETED_REGEXP
997 __ TailCallRuntime(Runtime::kRegExpExec); 735 __ TailCallRuntime(Runtime::kRegExpExec);
998 #else // V8_INTERPRETED_REGEXP 736 #else // V8_INTERPRETED_REGEXP
999 737
1000 // Stack frame on entry. 738 // Stack frame on entry.
1001 // esp[0]: return address 739 // esp[0]: return address
(...skipping 4148 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 __ CallRuntime(Runtime::kAllocateInNewSpace); 4888 __ CallRuntime(Runtime::kAllocateInNewSpace);
5151 __ mov(edx, eax); 4889 __ mov(edx, eax);
5152 __ Pop(ebx); 4890 __ Pop(ebx);
5153 __ Pop(eax); 4891 __ Pop(eax);
5154 } 4892 }
5155 __ jmp(&done_allocate); 4893 __ jmp(&done_allocate);
5156 } 4894 }
5157 } 4895 }
5158 4896
5159 4897
4898 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
4899 // ----------- S t a t e -------------
4900 // -- edi : function
4901 // -- esi : context
4902 // -- ebp : frame pointer
4903 // -- esp[0] : return address
4904 // -----------------------------------
4905 __ AssertFunction(edi);
4906
4907 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
4908 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
4909 __ mov(ecx,
4910 FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset));
4911 __ lea(edx, Operand(ebp, ecx, times_half_pointer_size,
4912 StandardFrameConstants::kCallerSPOffset));
4913
4914 // ecx : number of parameters (tagged)
4915 // edx : parameters pointer
4916 // edi : function
4917 // esp[0] : return address
4918
4919 // Check if the calling frame is an arguments adaptor frame.
4920 Label adaptor_frame, try_allocate, runtime;
4921 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
4922 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
4923 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
4924 __ j(equal, &adaptor_frame, Label::kNear);
4925
4926 // No adaptor, parameter count = argument count.
4927 __ mov(ebx, ecx);
4928 __ push(ecx);
4929 __ jmp(&try_allocate, Label::kNear);
4930
4931 // We have an adaptor frame. Patch the parameters pointer.
4932 __ bind(&adaptor_frame);
4933 __ mov(ebx, ecx);
4934 __ push(ecx);
4935 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
4936 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
4937 __ lea(edx, Operand(edx, ecx, times_2,
4938 StandardFrameConstants::kCallerSPOffset));
4939
4940 // ebx = parameter count (tagged)
4941 // ecx = argument count (smi-tagged)
4942 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
4943 __ cmp(ebx, ecx);
4944 __ j(less_equal, &try_allocate, Label::kNear);
4945 __ mov(ebx, ecx);
4946
4947 // Save mapped parameter count and function.
4948 __ bind(&try_allocate);
4949 __ push(edi);
4950 __ push(ebx);
4951
4952 // Compute the sizes of backing store, parameter map, and arguments object.
4953 // 1. Parameter map, has 2 extra words containing context and backing store.
4954 const int kParameterMapHeaderSize =
4955 FixedArray::kHeaderSize + 2 * kPointerSize;
4956 Label no_parameter_map;
4957 __ test(ebx, ebx);
4958 __ j(zero, &no_parameter_map, Label::kNear);
4959 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
4960 __ bind(&no_parameter_map);
4961
4962 // 2. Backing store.
4963 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
4964
4965 // 3. Arguments object.
4966 __ add(ebx, Immediate(JSSloppyArgumentsObject::kSize));
4967
4968 // Do the allocation of all three objects in one go.
4969 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
4970
4971 // eax = address of new object(s) (tagged)
4972 // ecx = argument count (smi-tagged)
4973 // esp[0] = mapped parameter count (tagged)
4974 // esp[4] = function
4975 // esp[8] = parameter count (tagged)
4976 // Get the arguments map from the current native context into edi.
4977 Label has_mapped_parameters, instantiate;
4978 __ mov(edi, NativeContextOperand());
4979 __ mov(ebx, Operand(esp, 0 * kPointerSize));
4980 __ test(ebx, ebx);
4981 __ j(not_zero, &has_mapped_parameters, Label::kNear);
4982 __ mov(
4983 edi,
4984 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
4985 __ jmp(&instantiate, Label::kNear);
4986
4987 __ bind(&has_mapped_parameters);
4988 __ mov(edi, Operand(edi, Context::SlotOffset(
4989 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
4990 __ bind(&instantiate);
4991
4992 // eax = address of new object (tagged)
4993 // ebx = mapped parameter count (tagged)
4994 // ecx = argument count (smi-tagged)
4995 // edi = address of arguments map (tagged)
4996 // esp[0] = mapped parameter count (tagged)
4997 // esp[4] = function
4998 // esp[8] = parameter count (tagged)
4999 // Copy the JS object part.
5000 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
5001 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
5002 masm->isolate()->factory()->empty_fixed_array());
5003 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
5004 masm->isolate()->factory()->empty_fixed_array());
5005
5006 // Set up the callee in-object property.
5007 STATIC_ASSERT(JSSloppyArgumentsObject::kCalleeIndex == 1);
5008 __ mov(edi, Operand(esp, 1 * kPointerSize));
5009 __ AssertNotSmi(edi);
5010 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kCalleeOffset), edi);
5011
5012 // Use the length (smi tagged) and set that as an in-object property too.
5013 __ AssertSmi(ecx);
5014 __ mov(FieldOperand(eax, JSSloppyArgumentsObject::kLengthOffset), ecx);
5015
5016 // Set up the elements pointer in the allocated arguments object.
5017 // If we allocated a parameter map, edi will point there, otherwise to the
5018 // backing store.
5019 __ lea(edi, Operand(eax, JSSloppyArgumentsObject::kSize));
5020 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
5021
5022 // eax = address of new object (tagged)
5023 // ebx = mapped parameter count (tagged)
5024 // ecx = argument count (tagged)
5025 // edx = address of receiver argument
5026 // edi = address of parameter map or backing store (tagged)
5027 // esp[0] = mapped parameter count (tagged)
5028 // esp[4] = function
5029 // esp[8] = parameter count (tagged)
5030 // Free two registers.
5031 __ push(edx);
5032 __ push(eax);
5033
5034 // Initialize parameter map. If there are no mapped arguments, we're done.
5035 Label skip_parameter_map;
5036 __ test(ebx, ebx);
5037 __ j(zero, &skip_parameter_map);
5038
5039 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
5040 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
5041 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
5042 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
5043 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
5044 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
5045 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
5046
5047 // Copy the parameter slots and the holes in the arguments.
5048 // We need to fill in mapped_parameter_count slots. They index the context,
5049 // where parameters are stored in reverse order, at
5050 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
5051 // The mapped parameter thus need to get indices
5052 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
5053 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
5054 // We loop from right to left.
5055 Label parameters_loop, parameters_test;
5056 __ push(ecx);
5057 __ mov(eax, Operand(esp, 3 * kPointerSize));
5058 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
5059 __ add(ebx, Operand(esp, 5 * kPointerSize));
5060 __ sub(ebx, eax);
5061 __ mov(ecx, isolate()->factory()->the_hole_value());
5062 __ mov(edx, edi);
5063 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
5064 // eax = loop variable (tagged)
5065 // ebx = mapping index (tagged)
5066 // ecx = the hole value
5067 // edx = address of parameter map (tagged)
5068 // edi = address of backing store (tagged)
5069 // esp[0] = argument count (tagged)
5070 // esp[4] = address of new object (tagged)
5071 // esp[8] = address of receiver argument
5072 // esp[12] = mapped parameter count (tagged)
5073 // esp[16] = function
5074 // esp[20] = parameter count (tagged)
5075 __ jmp(&parameters_test, Label::kNear);
5076
5077 __ bind(&parameters_loop);
5078 __ sub(eax, Immediate(Smi::FromInt(1)));
5079 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
5080 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
5081 __ add(ebx, Immediate(Smi::FromInt(1)));
5082 __ bind(&parameters_test);
5083 __ test(eax, eax);
5084 __ j(not_zero, &parameters_loop, Label::kNear);
5085 __ pop(ecx);
5086
5087 __ bind(&skip_parameter_map);
5088
5089 // ecx = argument count (tagged)
5090 // edi = address of backing store (tagged)
5091 // esp[0] = address of new object (tagged)
5092 // esp[4] = address of receiver argument
5093 // esp[8] = mapped parameter count (tagged)
5094 // esp[12] = function
5095 // esp[16] = parameter count (tagged)
5096 // Copy arguments header and remaining slots (if there are any).
5097 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
5098 Immediate(isolate()->factory()->fixed_array_map()));
5099 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
5100
5101 Label arguments_loop, arguments_test;
5102 __ mov(ebx, Operand(esp, 2 * kPointerSize));
5103 __ mov(edx, Operand(esp, 1 * kPointerSize));
5104 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
5105 __ sub(edx, ebx);
5106 __ jmp(&arguments_test, Label::kNear);
5107
5108 __ bind(&arguments_loop);
5109 __ sub(edx, Immediate(kPointerSize));
5110 __ mov(eax, Operand(edx, 0));
5111 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
5112 __ add(ebx, Immediate(Smi::FromInt(1)));
5113
5114 __ bind(&arguments_test);
5115 __ cmp(ebx, ecx);
5116 __ j(less, &arguments_loop, Label::kNear);
5117
5118 // Restore.
5119 __ pop(eax); // Address of arguments object.
5120 __ Drop(4);
5121
5122 // Return.
5123 __ ret(0);
5124
5125 // Do the runtime call to allocate the arguments object.
5126 __ bind(&runtime);
5127 __ pop(eax); // Remove saved mapped parameter count.
5128 __ pop(edi); // Pop saved function.
5129 __ pop(eax); // Remove saved parameter count.
5130 __ pop(eax); // Pop return address.
5131 __ push(edi); // Push function.
5132 __ push(edx); // Push parameters pointer.
5133 __ push(ecx); // Push parameter count.
5134 __ push(eax); // Push return address.
5135 __ TailCallRuntime(Runtime::kNewSloppyArguments);
5136 }
5137
5138
5160 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { 5139 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
5161 // ----------- S t a t e ------------- 5140 // ----------- S t a t e -------------
5162 // -- edi : function 5141 // -- edi : function
5163 // -- esi : context 5142 // -- esi : context
5164 // -- ebp : frame pointer 5143 // -- ebp : frame pointer
5165 // -- esp[0] : return address 5144 // -- esp[0] : return address
5166 // ----------------------------------- 5145 // -----------------------------------
5167 __ AssertFunction(edi); 5146 __ AssertFunction(edi);
5168 5147
5169 // For Ignition we need to skip all possible handler/stub frames until 5148 // For Ignition we need to skip all possible handler/stub frames until
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
5821 return_value_operand, NULL); 5800 return_value_operand, NULL);
5822 } 5801 }
5823 5802
5824 5803
5825 #undef __ 5804 #undef __
5826 5805
5827 } // namespace internal 5806 } // namespace internal
5828 } // namespace v8 5807 } // namespace v8
5829 5808
5830 #endif // V8_TARGET_ARCH_IA32 5809 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/full-codegen/x64/full-codegen-x64.cc ('k') | src/ia32/interface-descriptors-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698