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

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

Issue 1348773002: [turbofan] Call ArgumentsAccessStub to materialize arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 3 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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 // by calling the runtime system. 785 // by calling the runtime system.
786 __ bind(&slow); 786 __ bind(&slow);
787 __ pop(ebx); // Return address. 787 __ pop(ebx); // Return address.
788 __ push(edx); 788 __ push(edx);
789 __ push(ebx); 789 __ push(ebx);
790 __ TailCallRuntime(Runtime::kArguments, 1, 1); 790 __ TailCallRuntime(Runtime::kArguments, 1, 1);
791 } 791 }
792 792
793 793
794 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { 794 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
795 // ecx : number of parameters (tagged)
796 // edx : parameters pointer
797 // edi : function
795 // esp[0] : return address 798 // esp[0] : return address
796 // esp[4] : number of parameters 799
797 // esp[8] : receiver displacement 800 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
798 // esp[12] : function 801 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
802 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
799 803
800 // Check if the calling frame is an arguments adaptor frame. 804 // Check if the calling frame is an arguments adaptor frame.
801 Label runtime; 805 Label runtime;
802 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 806 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
803 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 807 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
804 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 808 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
805 __ j(not_equal, &runtime, Label::kNear); 809 __ j(not_equal, &runtime, Label::kNear);
806 810
807 // Patch the arguments.length and the parameters pointer. 811 // Patch the arguments.length and the parameters pointer.
808 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 812 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
809 __ mov(Operand(esp, 1 * kPointerSize), ecx); 813 __ lea(edx,
810 __ lea(edx, Operand(edx, ecx, times_2, 814 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
811 StandardFrameConstants::kCallerSPOffset));
812 __ mov(Operand(esp, 2 * kPointerSize), edx);
813 815
814 __ bind(&runtime); 816 __ bind(&runtime);
817 __ pop(eax); // Pop return address.
818 __ push(edi); // Push function.
819 __ push(edx); // Push parameters pointer.
820 __ push(ecx); // Push parameter count.
821 __ push(eax); // Push return address.
815 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 822 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
816 } 823 }
817 824
818 825
819 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { 826 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
827 // ecx : number of parameters (tagged)
828 // edx : parameters pointer
829 // edi : function
820 // esp[0] : return address 830 // esp[0] : return address
821 // esp[4] : number of parameters (tagged)
822 // esp[8] : receiver displacement
823 // esp[12] : function
824 831
825 // ebx = parameter count (tagged) 832 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
826 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 833 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
834 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
827 835
828 // Check if the calling frame is an arguments adaptor frame. 836 // Check if the calling frame is an arguments adaptor frame.
829 // TODO(rossberg): Factor out some of the bits that are shared with the other 837 Label adaptor_frame, try_allocate, runtime;
830 // Generate* functions. 838 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
831 Label runtime; 839 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
832 Label adaptor_frame, try_allocate; 840 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
833 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
834 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
835 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
836 __ j(equal, &adaptor_frame, Label::kNear); 841 __ j(equal, &adaptor_frame, Label::kNear);
837 842
838 // No adaptor, parameter count = argument count. 843 // No adaptor, parameter count = argument count.
839 __ mov(ecx, ebx); 844 __ mov(ebx, ecx);
845 __ push(ecx);
840 __ jmp(&try_allocate, Label::kNear); 846 __ jmp(&try_allocate, Label::kNear);
841 847
842 // We have an adaptor frame. Patch the parameters pointer. 848 // We have an adaptor frame. Patch the parameters pointer.
843 __ bind(&adaptor_frame); 849 __ bind(&adaptor_frame);
850 __ mov(ebx, ecx);
851 __ push(ecx);
852 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
844 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 853 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
845 __ lea(edx, Operand(edx, ecx, times_2, 854 __ lea(edx, Operand(edx, ecx, times_2,
846 StandardFrameConstants::kCallerSPOffset)); 855 StandardFrameConstants::kCallerSPOffset));
847 __ mov(Operand(esp, 2 * kPointerSize), edx);
848 856
849 // ebx = parameter count (tagged) 857 // ebx = parameter count (tagged)
850 // ecx = argument count (smi-tagged) 858 // ecx = argument count (smi-tagged)
851 // esp[4] = parameter count (tagged)
852 // esp[8] = address of receiver argument
853 // Compute the mapped parameter count = min(ebx, ecx) in ebx. 859 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
854 __ cmp(ebx, ecx); 860 __ cmp(ebx, ecx);
855 __ j(less_equal, &try_allocate, Label::kNear); 861 __ j(less_equal, &try_allocate, Label::kNear);
856 __ mov(ebx, ecx); 862 __ mov(ebx, ecx);
857 863
864 // Save mapped parameter count and function.
858 __ bind(&try_allocate); 865 __ bind(&try_allocate);
859 866 __ push(edi);
860 // Save mapped parameter count.
861 __ push(ebx); 867 __ push(ebx);
862 868
863 // Compute the sizes of backing store, parameter map, and arguments object. 869 // Compute the sizes of backing store, parameter map, and arguments object.
864 // 1. Parameter map, has 2 extra words containing context and backing store. 870 // 1. Parameter map, has 2 extra words containing context and backing store.
865 const int kParameterMapHeaderSize = 871 const int kParameterMapHeaderSize =
866 FixedArray::kHeaderSize + 2 * kPointerSize; 872 FixedArray::kHeaderSize + 2 * kPointerSize;
867 Label no_parameter_map; 873 Label no_parameter_map;
868 __ test(ebx, ebx); 874 __ test(ebx, ebx);
869 __ j(zero, &no_parameter_map, Label::kNear); 875 __ j(zero, &no_parameter_map, Label::kNear);
870 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); 876 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
871 __ bind(&no_parameter_map); 877 __ bind(&no_parameter_map);
872 878
873 // 2. Backing store. 879 // 2. Backing store.
874 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); 880 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
875 881
876 // 3. Arguments object. 882 // 3. Arguments object.
877 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); 883 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize));
878 884
879 // Do the allocation of all three objects in one go. 885 // Do the allocation of all three objects in one go.
880 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); 886 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
881 887
882 // eax = address of new object(s) (tagged) 888 // eax = address of new object(s) (tagged)
883 // ecx = argument count (smi-tagged) 889 // ecx = argument count (smi-tagged)
884 // esp[0] = mapped parameter count (tagged) 890 // esp[0] = mapped parameter count (tagged)
891 // esp[4] = function
885 // esp[8] = parameter count (tagged) 892 // esp[8] = parameter count (tagged)
886 // esp[12] = address of receiver argument
887 // Get the arguments map from the current native context into edi. 893 // Get the arguments map from the current native context into edi.
888 Label has_mapped_parameters, instantiate; 894 Label has_mapped_parameters, instantiate;
889 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 895 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
890 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); 896 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
891 __ mov(ebx, Operand(esp, 0 * kPointerSize)); 897 __ mov(ebx, Operand(esp, 0 * kPointerSize));
892 __ test(ebx, ebx); 898 __ test(ebx, ebx);
893 __ j(not_zero, &has_mapped_parameters, Label::kNear); 899 __ j(not_zero, &has_mapped_parameters, Label::kNear);
894 __ mov( 900 __ mov(
895 edi, 901 edi,
896 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); 902 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
897 __ jmp(&instantiate, Label::kNear); 903 __ jmp(&instantiate, Label::kNear);
898 904
899 __ bind(&has_mapped_parameters); 905 __ bind(&has_mapped_parameters);
900 __ mov(edi, Operand(edi, Context::SlotOffset( 906 __ mov(edi, Operand(edi, Context::SlotOffset(
901 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX))); 907 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
902 __ bind(&instantiate); 908 __ bind(&instantiate);
903 909
904 // eax = address of new object (tagged) 910 // eax = address of new object (tagged)
905 // ebx = mapped parameter count (tagged) 911 // ebx = mapped parameter count (tagged)
906 // ecx = argument count (smi-tagged) 912 // ecx = argument count (smi-tagged)
907 // edi = address of arguments map (tagged) 913 // edi = address of arguments map (tagged)
908 // esp[0] = mapped parameter count (tagged) 914 // esp[0] = mapped parameter count (tagged)
915 // esp[4] = function
909 // esp[8] = parameter count (tagged) 916 // esp[8] = parameter count (tagged)
910 // esp[12] = address of receiver argument
911 // Copy the JS object part. 917 // Copy the JS object part.
912 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 918 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
913 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 919 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
914 masm->isolate()->factory()->empty_fixed_array()); 920 masm->isolate()->factory()->empty_fixed_array());
915 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 921 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
916 masm->isolate()->factory()->empty_fixed_array()); 922 masm->isolate()->factory()->empty_fixed_array());
917 923
918 // Set up the callee in-object property. 924 // Set up the callee in-object property.
919 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 925 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
920 __ mov(edx, Operand(esp, 4 * kPointerSize)); 926 __ mov(edi, Operand(esp, 1 * kPointerSize));
921 __ AssertNotSmi(edx); 927 __ AssertNotSmi(edi);
922 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 928 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
923 Heap::kArgumentsCalleeIndex * kPointerSize), 929 Heap::kArgumentsCalleeIndex * kPointerSize),
924 edx); 930 edi);
925 931
926 // Use the length (smi tagged) and set that as an in-object property too. 932 // Use the length (smi tagged) and set that as an in-object property too.
927 __ AssertSmi(ecx); 933 __ AssertSmi(ecx);
928 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 934 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
929 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 935 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
930 Heap::kArgumentsLengthIndex * kPointerSize), 936 Heap::kArgumentsLengthIndex * kPointerSize),
931 ecx); 937 ecx);
932 938
933 // Set up the elements pointer in the allocated arguments object. 939 // Set up the elements pointer in the allocated arguments object.
934 // If we allocated a parameter map, edi will point there, otherwise to the 940 // If we allocated a parameter map, edi will point there, otherwise to the
935 // backing store. 941 // backing store.
936 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); 942 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize));
937 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 943 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
938 944
939 // eax = address of new object (tagged) 945 // eax = address of new object (tagged)
940 // ebx = mapped parameter count (tagged) 946 // ebx = mapped parameter count (tagged)
941 // ecx = argument count (tagged) 947 // ecx = argument count (tagged)
948 // edx = address of receiver argument
942 // edi = address of parameter map or backing store (tagged) 949 // edi = address of parameter map or backing store (tagged)
943 // esp[0] = mapped parameter count (tagged) 950 // esp[0] = mapped parameter count (tagged)
951 // esp[4] = function
944 // esp[8] = parameter count (tagged) 952 // esp[8] = parameter count (tagged)
945 // esp[12] = address of receiver argument 953 // Free two registers.
946 // Free a register. 954 __ push(edx);
947 __ push(eax); 955 __ push(eax);
948 956
949 // Initialize parameter map. If there are no mapped arguments, we're done. 957 // Initialize parameter map. If there are no mapped arguments, we're done.
950 Label skip_parameter_map; 958 Label skip_parameter_map;
951 __ test(ebx, ebx); 959 __ test(ebx, ebx);
952 __ j(zero, &skip_parameter_map); 960 __ j(zero, &skip_parameter_map);
953 961
954 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 962 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
955 Immediate(isolate()->factory()->sloppy_arguments_elements_map())); 963 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
956 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); 964 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
957 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); 965 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
958 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); 966 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
959 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); 967 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
960 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); 968 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
961 969
962 // Copy the parameter slots and the holes in the arguments. 970 // Copy the parameter slots and the holes in the arguments.
963 // We need to fill in mapped_parameter_count slots. They index the context, 971 // We need to fill in mapped_parameter_count slots. They index the context,
964 // where parameters are stored in reverse order, at 972 // where parameters are stored in reverse order, at
965 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 973 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
966 // The mapped parameter thus need to get indices 974 // The mapped parameter thus need to get indices
967 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 975 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
968 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 976 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
969 // We loop from right to left. 977 // We loop from right to left.
970 Label parameters_loop, parameters_test; 978 Label parameters_loop, parameters_test;
971 __ push(ecx); 979 __ push(ecx);
972 __ mov(eax, Operand(esp, 2 * kPointerSize)); 980 __ mov(eax, Operand(esp, 3 * kPointerSize));
973 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); 981 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
974 __ add(ebx, Operand(esp, 4 * kPointerSize)); 982 __ add(ebx, Operand(esp, 5 * kPointerSize));
975 __ sub(ebx, eax); 983 __ sub(ebx, eax);
976 __ mov(ecx, isolate()->factory()->the_hole_value()); 984 __ mov(ecx, isolate()->factory()->the_hole_value());
977 __ mov(edx, edi); 985 __ mov(edx, edi);
978 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); 986 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
979 // eax = loop variable (tagged) 987 // eax = loop variable (tagged)
980 // ebx = mapping index (tagged) 988 // ebx = mapping index (tagged)
981 // ecx = the hole value 989 // ecx = the hole value
982 // edx = address of parameter map (tagged) 990 // edx = address of parameter map (tagged)
983 // edi = address of backing store (tagged) 991 // edi = address of backing store (tagged)
984 // esp[0] = argument count (tagged) 992 // esp[0] = argument count (tagged)
985 // esp[4] = address of new object (tagged) 993 // esp[4] = address of new object (tagged)
986 // esp[8] = mapped parameter count (tagged) 994 // esp[8] = address of receiver argument
987 // esp[16] = parameter count (tagged) 995 // esp[12] = mapped parameter count (tagged)
988 // esp[20] = address of receiver argument 996 // esp[16] = function
997 // esp[20] = parameter count (tagged)
989 __ jmp(&parameters_test, Label::kNear); 998 __ jmp(&parameters_test, Label::kNear);
990 999
991 __ bind(&parameters_loop); 1000 __ bind(&parameters_loop);
992 __ sub(eax, Immediate(Smi::FromInt(1))); 1001 __ sub(eax, Immediate(Smi::FromInt(1)));
993 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx); 1002 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
994 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx); 1003 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
995 __ add(ebx, Immediate(Smi::FromInt(1))); 1004 __ add(ebx, Immediate(Smi::FromInt(1)));
996 __ bind(&parameters_test); 1005 __ bind(&parameters_test);
997 __ test(eax, eax); 1006 __ test(eax, eax);
998 __ j(not_zero, &parameters_loop, Label::kNear); 1007 __ j(not_zero, &parameters_loop, Label::kNear);
999 __ pop(ecx); 1008 __ pop(ecx);
1000 1009
1001 __ bind(&skip_parameter_map); 1010 __ bind(&skip_parameter_map);
1002 1011
1003 // ecx = argument count (tagged) 1012 // ecx = argument count (tagged)
1004 // edi = address of backing store (tagged) 1013 // edi = address of backing store (tagged)
1005 // esp[0] = address of new object (tagged) 1014 // esp[0] = address of new object (tagged)
1006 // esp[4] = mapped parameter count (tagged) 1015 // esp[4] = address of receiver argument
1007 // esp[12] = parameter count (tagged) 1016 // esp[8] = mapped parameter count (tagged)
1008 // esp[16] = address of receiver argument 1017 // esp[12] = function
1018 // esp[16] = parameter count (tagged)
1009 // Copy arguments header and remaining slots (if there are any). 1019 // Copy arguments header and remaining slots (if there are any).
1010 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1020 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1011 Immediate(isolate()->factory()->fixed_array_map())); 1021 Immediate(isolate()->factory()->fixed_array_map()));
1012 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 1022 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1013 1023
1014 Label arguments_loop, arguments_test; 1024 Label arguments_loop, arguments_test;
1015 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 1025 __ mov(ebx, Operand(esp, 2 * kPointerSize));
1016 __ mov(edx, Operand(esp, 4 * kPointerSize)); 1026 __ mov(edx, Operand(esp, 1 * kPointerSize));
1017 __ sub(edx, ebx); // Is there a smarter way to do negative scaling? 1027 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
1018 __ sub(edx, ebx); 1028 __ sub(edx, ebx);
1019 __ jmp(&arguments_test, Label::kNear); 1029 __ jmp(&arguments_test, Label::kNear);
1020 1030
1021 __ bind(&arguments_loop); 1031 __ bind(&arguments_loop);
1022 __ sub(edx, Immediate(kPointerSize)); 1032 __ sub(edx, Immediate(kPointerSize));
1023 __ mov(eax, Operand(edx, 0)); 1033 __ mov(eax, Operand(edx, 0));
1024 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax); 1034 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
1025 __ add(ebx, Immediate(Smi::FromInt(1))); 1035 __ add(ebx, Immediate(Smi::FromInt(1)));
1026 1036
1027 __ bind(&arguments_test); 1037 __ bind(&arguments_test);
1028 __ cmp(ebx, ecx); 1038 __ cmp(ebx, ecx);
1029 __ j(less, &arguments_loop, Label::kNear); 1039 __ j(less, &arguments_loop, Label::kNear);
1030 1040
1031 // Restore. 1041 // Restore.
1032 __ pop(eax); // Address of arguments object. 1042 __ pop(eax); // Address of arguments object.
1033 __ pop(ebx); // Parameter count. 1043 __ Drop(4);
1034 1044
1035 // Return and remove the on-stack parameters. 1045 // Return.
1036 __ ret(3 * kPointerSize); 1046 __ ret(0);
1037 1047
1038 // Do the runtime call to allocate the arguments object. 1048 // Do the runtime call to allocate the arguments object.
1039 __ bind(&runtime); 1049 __ bind(&runtime);
1040 __ pop(eax); // Remove saved parameter count. 1050 __ pop(eax); // Remove saved mapped parameter count.
1041 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. 1051 __ pop(edi); // Pop saved function.
1052 __ pop(eax); // Remove saved parameter count.
1053 __ pop(eax); // Pop return address.
1054 __ push(edi); // Push function.
1055 __ push(edx); // Push parameters pointer.
1056 __ push(ecx); // Push parameter count.
1057 __ push(eax); // Push return address.
1042 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 1058 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1043 } 1059 }
1044 1060
1045 1061
1046 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 1062 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1063 // ecx : number of parameters (tagged)
1064 // edx : parameters pointer
1065 // edi : function
1047 // esp[0] : return address 1066 // esp[0] : return address
1048 // esp[4] : number of parameters 1067
1049 // esp[8] : receiver displacement 1068 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
1050 // esp[12] : function 1069 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
1070 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
1051 1071
1052 // Check if the calling frame is an arguments adaptor frame. 1072 // Check if the calling frame is an arguments adaptor frame.
1053 Label adaptor_frame, try_allocate, runtime; 1073 Label try_allocate, runtime;
1054 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 1074 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1055 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 1075 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
1056 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1076 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1057 __ j(equal, &adaptor_frame, Label::kNear); 1077 __ j(not_equal, &try_allocate, Label::kNear);
1058
1059 // Get the length from the frame.
1060 __ mov(ecx, Operand(esp, 1 * kPointerSize));
1061 __ jmp(&try_allocate, Label::kNear);
1062 1078
1063 // Patch the arguments.length and the parameters pointer. 1079 // Patch the arguments.length and the parameters pointer.
1064 __ bind(&adaptor_frame); 1080 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
1065 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1081 __ lea(edx,
1066 1082 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
1067 __ lea(edx, Operand(edx, ecx, times_2,
1068 StandardFrameConstants::kCallerSPOffset));
1069 __ mov(Operand(esp, 1 * kPointerSize), ecx);
1070 __ mov(Operand(esp, 2 * kPointerSize), edx);
1071 1083
1072 // Try the new space allocation. Start out with computing the size of 1084 // Try the new space allocation. Start out with computing the size of
1073 // the arguments object and the elements array. 1085 // the arguments object and the elements array.
1074 Label add_arguments_object; 1086 Label add_arguments_object;
1075 __ bind(&try_allocate); 1087 __ bind(&try_allocate);
1076 __ test(ecx, ecx); 1088 __ mov(eax, ecx);
1089 __ test(eax, eax);
1077 __ j(zero, &add_arguments_object, Label::kNear); 1090 __ j(zero, &add_arguments_object, Label::kNear);
1078 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); 1091 __ lea(eax, Operand(eax, times_2, FixedArray::kHeaderSize));
1079 __ bind(&add_arguments_object); 1092 __ bind(&add_arguments_object);
1080 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); 1093 __ add(eax, Immediate(Heap::kStrictArgumentsObjectSize));
1081 1094
1082 // Do the allocation of both objects in one go. 1095 // Do the allocation of both objects in one go.
1083 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); 1096 __ Allocate(eax, eax, ebx, no_reg, &runtime, TAG_OBJECT);
1084 1097
1085 // Get the arguments map from the current native context. 1098 // Get the arguments map from the current native context.
1086 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1099 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1087 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); 1100 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
1088 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); 1101 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
1089 __ mov(edi, Operand(edi, offset)); 1102 __ mov(edi, Operand(edi, offset));
1090 1103
1091 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 1104 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
1092 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 1105 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
1093 masm->isolate()->factory()->empty_fixed_array()); 1106 masm->isolate()->factory()->empty_fixed_array());
1094 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 1107 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
1095 masm->isolate()->factory()->empty_fixed_array()); 1108 masm->isolate()->factory()->empty_fixed_array());
1096 1109
1097 // Get the length (smi tagged) and set that as an in-object property too. 1110 // Get the length (smi tagged) and set that as an in-object property too.
1098 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1111 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1099 __ mov(ecx, Operand(esp, 1 * kPointerSize));
1100 __ AssertSmi(ecx); 1112 __ AssertSmi(ecx);
1101 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 1113 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
1102 Heap::kArgumentsLengthIndex * kPointerSize), 1114 Heap::kArgumentsLengthIndex * kPointerSize),
1103 ecx); 1115 ecx);
1104 1116
1105 // If there are no actual arguments, we're done. 1117 // If there are no actual arguments, we're done.
1106 Label done; 1118 Label done;
1107 __ test(ecx, ecx); 1119 __ test(ecx, ecx);
1108 __ j(zero, &done, Label::kNear); 1120 __ j(zero, &done, Label::kNear);
1109 1121
1110 // Get the parameters pointer from the stack.
1111 __ mov(edx, Operand(esp, 2 * kPointerSize));
1112
1113 // Set up the elements pointer in the allocated arguments object and 1122 // Set up the elements pointer in the allocated arguments object and
1114 // initialize the header in the elements fixed array. 1123 // initialize the header in the elements fixed array.
1115 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize)); 1124 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
1116 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 1125 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
1117 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1126 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1118 Immediate(isolate()->factory()->fixed_array_map())); 1127 Immediate(isolate()->factory()->fixed_array_map()));
1128 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1119 1129
1120 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1121 // Untag the length for the loop below. 1130 // Untag the length for the loop below.
1122 __ SmiUntag(ecx); 1131 __ SmiUntag(ecx);
1123 1132
1124 // Copy the fixed array slots. 1133 // Copy the fixed array slots.
1125 Label loop; 1134 Label loop;
1126 __ bind(&loop); 1135 __ bind(&loop);
1127 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. 1136 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
1128 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); 1137 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
1129 __ add(edi, Immediate(kPointerSize)); 1138 __ add(edi, Immediate(kPointerSize));
1130 __ sub(edx, Immediate(kPointerSize)); 1139 __ sub(edx, Immediate(kPointerSize));
1131 __ dec(ecx); 1140 __ dec(ecx);
1132 __ j(not_zero, &loop); 1141 __ j(not_zero, &loop);
1133 1142
1134 // Return and remove the on-stack parameters. 1143 // Return.
1135 __ bind(&done); 1144 __ bind(&done);
1136 __ ret(3 * kPointerSize); 1145 __ ret(0);
1137 1146
1138 // Do the runtime call to allocate the arguments object. 1147 // Do the runtime call to allocate the arguments object.
1139 __ bind(&runtime); 1148 __ bind(&runtime);
1149 __ pop(eax); // Pop return address.
1150 __ push(edi); // Push function.
1151 __ push(edx); // Push parameters pointer.
1152 __ push(ecx); // Push parameter count.
1153 __ push(eax); // Push return address.
1140 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1154 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1141 } 1155 }
1142 1156
1143 1157
1144 void RegExpExecStub::Generate(MacroAssembler* masm) { 1158 void RegExpExecStub::Generate(MacroAssembler* masm) {
1145 // Just jump directly to runtime if native RegExp is not selected at compile 1159 // Just jump directly to runtime if native RegExp is not selected at compile
1146 // time or if regexp entry in generated code is turned off runtime switch or 1160 // time or if regexp entry in generated code is turned off runtime switch or
1147 // at compilation. 1161 // at compilation.
1148 #ifdef V8_INTERPRETED_REGEXP 1162 #ifdef V8_INTERPRETED_REGEXP
1149 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1163 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
(...skipping 4659 matching lines...) Expand 10 before | Expand all | Expand 10 after
5809 Operand(ebp, 7 * kPointerSize), NULL); 5823 Operand(ebp, 7 * kPointerSize), NULL);
5810 } 5824 }
5811 5825
5812 5826
5813 #undef __ 5827 #undef __
5814 5828
5815 } // namespace internal 5829 } // namespace internal
5816 } // namespace v8 5830 } // namespace v8
5817 5831
5818 #endif // V8_TARGET_ARCH_IA32 5832 #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