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

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: 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
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(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
798 // esp[12] : function 801 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
802 DCHECK(edi.is(ArgumentsAccessNewDescriptor::callee()));
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) {
820 // esp[0] : return address 827 // esp[0] : return address
821 // esp[4] : number of parameters (tagged) 828 // esp[4] : number of parameters (tagged)
822 // esp[8] : receiver displacement 829 // esp[8] : receiver displacement
823 // esp[12] : function 830 // esp[12] : function
824 831
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 1044
1038 // Do the runtime call to allocate the arguments object. 1045 // Do the runtime call to allocate the arguments object.
1039 __ bind(&runtime); 1046 __ bind(&runtime);
1040 __ pop(eax); // Remove saved parameter count. 1047 __ pop(eax); // Remove saved parameter count.
1041 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. 1048 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count.
1042 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 1049 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
1043 } 1050 }
1044 1051
1045 1052
1046 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 1053 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
1054 // ecx : number of parameters (tagged)
1055 // edx : parameters pointer
1056 // edi : function
1047 // esp[0] : return address 1057 // esp[0] : return address
1048 // esp[4] : number of parameters 1058
1049 // esp[8] : receiver displacement 1059 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
1050 // esp[12] : function 1060 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
1061 DCHECK(edi.is(ArgumentsAccessNewDescriptor::callee()));
1051 1062
1052 // Check if the calling frame is an arguments adaptor frame. 1063 // Check if the calling frame is an arguments adaptor frame.
1053 Label adaptor_frame, try_allocate, runtime; 1064 Label try_allocate, runtime;
1054 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 1065 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
1055 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 1066 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
1056 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1067 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1057 __ j(equal, &adaptor_frame, Label::kNear); 1068 __ 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 1069
1063 // Patch the arguments.length and the parameters pointer. 1070 // Patch the arguments.length and the parameters pointer.
1064 __ bind(&adaptor_frame); 1071 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
1065 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 1072 __ lea(edx,
1066 1073 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 1074
1072 // Try the new space allocation. Start out with computing the size of 1075 // Try the new space allocation. Start out with computing the size of
1073 // the arguments object and the elements array. 1076 // the arguments object and the elements array.
1074 Label add_arguments_object; 1077 Label add_arguments_object;
1075 __ bind(&try_allocate); 1078 __ bind(&try_allocate);
1076 __ test(ecx, ecx); 1079 __ mov(eax, ecx);
1080 __ test(eax, eax);
1077 __ j(zero, &add_arguments_object, Label::kNear); 1081 __ j(zero, &add_arguments_object, Label::kNear);
1078 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); 1082 __ lea(eax, Operand(eax, times_2, FixedArray::kHeaderSize));
1079 __ bind(&add_arguments_object); 1083 __ bind(&add_arguments_object);
1080 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); 1084 __ add(eax, Immediate(Heap::kStrictArgumentsObjectSize));
1081 1085
1082 // Do the allocation of both objects in one go. 1086 // Do the allocation of both objects in one go.
1083 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); 1087 __ Allocate(eax, eax, ebx, no_reg, &runtime, TAG_OBJECT);
1084 1088
1085 // Get the arguments map from the current native context. 1089 // Get the arguments map from the current native context.
1086 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 1090 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
1087 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); 1091 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
1088 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); 1092 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
1089 __ mov(edi, Operand(edi, offset)); 1093 __ mov(edi, Operand(edi, offset));
1090 1094
1091 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 1095 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
1092 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 1096 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
1093 masm->isolate()->factory()->empty_fixed_array()); 1097 masm->isolate()->factory()->empty_fixed_array());
1094 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 1098 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
1095 masm->isolate()->factory()->empty_fixed_array()); 1099 masm->isolate()->factory()->empty_fixed_array());
1096 1100
1097 // Get the length (smi tagged) and set that as an in-object property too. 1101 // Get the length (smi tagged) and set that as an in-object property too.
1098 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 1102 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
1099 __ mov(ecx, Operand(esp, 1 * kPointerSize));
1100 __ AssertSmi(ecx); 1103 __ AssertSmi(ecx);
1101 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 1104 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
1102 Heap::kArgumentsLengthIndex * kPointerSize), 1105 Heap::kArgumentsLengthIndex * kPointerSize),
1103 ecx); 1106 ecx);
1104 1107
1105 // If there are no actual arguments, we're done. 1108 // If there are no actual arguments, we're done.
1106 Label done; 1109 Label done;
1107 __ test(ecx, ecx); 1110 __ test(ecx, ecx);
1108 __ j(zero, &done, Label::kNear); 1111 __ j(zero, &done, Label::kNear);
1109 1112
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 1113 // Set up the elements pointer in the allocated arguments object and
1114 // initialize the header in the elements fixed array. 1114 // initialize the header in the elements fixed array.
1115 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize)); 1115 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
1116 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 1116 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
1117 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 1117 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
1118 Immediate(isolate()->factory()->fixed_array_map())); 1118 Immediate(isolate()->factory()->fixed_array_map()));
1119 1119
1120 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 1120 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
1121 // Untag the length for the loop below. 1121 // Untag the length for the loop below.
1122 __ SmiUntag(ecx); 1122 __ SmiUntag(ecx);
1123 1123
1124 // Copy the fixed array slots. 1124 // Copy the fixed array slots.
1125 Label loop; 1125 Label loop;
1126 __ bind(&loop); 1126 __ bind(&loop);
1127 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. 1127 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
1128 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); 1128 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
1129 __ add(edi, Immediate(kPointerSize)); 1129 __ add(edi, Immediate(kPointerSize));
1130 __ sub(edx, Immediate(kPointerSize)); 1130 __ sub(edx, Immediate(kPointerSize));
1131 __ dec(ecx); 1131 __ dec(ecx);
1132 __ j(not_zero, &loop); 1132 __ j(not_zero, &loop);
1133 1133
1134 // Return and remove the on-stack parameters. 1134 // Return and remove the on-stack parameters.
1135 __ bind(&done); 1135 __ bind(&done);
1136 __ ret(3 * kPointerSize); 1136 __ ret(0);
1137 1137
1138 // Do the runtime call to allocate the arguments object. 1138 // Do the runtime call to allocate the arguments object.
1139 __ bind(&runtime); 1139 __ bind(&runtime);
1140 __ pop(eax); // Pop return address.
1141 __ push(edi); // Push function.
1142 __ push(edx); // Push parameters pointer.
1143 __ push(ecx); // Push parameter count.
1144 __ push(eax); // Push return address.
1140 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1145 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1141 } 1146 }
1142 1147
1143 1148
1144 void RegExpExecStub::Generate(MacroAssembler* masm) { 1149 void RegExpExecStub::Generate(MacroAssembler* masm) {
1145 // Just jump directly to runtime if native RegExp is not selected at compile 1150 // 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 1151 // time or if regexp entry in generated code is turned off runtime switch or
1147 // at compilation. 1152 // at compilation.
1148 #ifdef V8_INTERPRETED_REGEXP 1153 #ifdef V8_INTERPRETED_REGEXP
1149 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1154 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
(...skipping 4662 matching lines...) Expand 10 before | Expand all | Expand 10 after
5812 Operand(ebp, 7 * kPointerSize), NULL); 5817 Operand(ebp, 7 * kPointerSize), NULL);
5813 } 5818 }
5814 5819
5815 5820
5816 #undef __ 5821 #undef __
5817 5822
5818 } // namespace internal 5823 } // namespace internal
5819 } // namespace v8 5824 } // namespace v8
5820 5825
5821 #endif // V8_TARGET_ARCH_IA32 5826 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698