OLD | NEW |
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_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 __ cmp(eax, ebx); | 1102 __ cmp(eax, ebx); |
1103 __ j(not_equal, | 1103 __ j(not_equal, |
1104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); | 1104 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline()); |
1105 | 1105 |
1106 ParameterCount expected(0); | 1106 ParameterCount expected(0); |
1107 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1107 __ InvokeCode(edx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1108 } | 1108 } |
1109 | 1109 |
1110 | 1110 |
1111 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1111 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
| 1112 const int vectorOffset, |
1112 const int argumentsOffset, | 1113 const int argumentsOffset, |
1113 const int indexOffset, | 1114 const int indexOffset, |
1114 const int limitOffset) { | 1115 const int limitOffset) { |
1115 // Copy all arguments from the array to the stack. | 1116 // Copy all arguments from the array to the stack. |
1116 Label entry, loop; | 1117 Label entry, loop; |
1117 Register receiver = LoadDescriptor::ReceiverRegister(); | 1118 Register receiver = LoadDescriptor::ReceiverRegister(); |
1118 Register key = LoadDescriptor::NameRegister(); | 1119 Register key = LoadDescriptor::NameRegister(); |
1119 Register slot = LoadDescriptor::SlotRegister(); | 1120 Register slot = LoadDescriptor::SlotRegister(); |
1120 Register vector = LoadWithVectorDescriptor::VectorRegister(); | 1121 Register vector = LoadWithVectorDescriptor::VectorRegister(); |
1121 __ mov(key, Operand(ebp, indexOffset)); | 1122 __ mov(key, Operand(ebp, indexOffset)); |
1122 __ jmp(&entry); | 1123 __ jmp(&entry); |
1123 __ bind(&loop); | 1124 __ bind(&loop); |
1124 __ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments | 1125 __ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments |
1125 | 1126 |
1126 // Use inline caching to speed up access to arguments. | 1127 // Use inline caching to speed up access to arguments. |
1127 Code::Kind kinds[] = {Code::KEYED_LOAD_IC}; | 1128 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex(); |
1128 FeedbackVectorSpec spec(0, 1, kinds); | 1129 __ mov(slot, Immediate(Smi::FromInt(slot_index))); |
1129 Handle<TypeFeedbackVector> feedback_vector = | 1130 __ mov(vector, Operand(ebp, vectorOffset)); |
1130 masm->isolate()->factory()->NewTypeFeedbackVector(&spec); | |
1131 int index = feedback_vector->GetIndex(FeedbackVectorICSlot(0)); | |
1132 __ mov(slot, Immediate(Smi::FromInt(index))); | |
1133 __ mov(vector, Immediate(feedback_vector)); | |
1134 Handle<Code> ic = | 1131 Handle<Code> ic = |
1135 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); | 1132 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode(); |
1136 __ call(ic, RelocInfo::CODE_TARGET); | 1133 __ call(ic, RelocInfo::CODE_TARGET); |
1137 // It is important that we do not have a test instruction after the | 1134 // It is important that we do not have a test instruction after the |
1138 // call. A test instruction after the call is used to indicate that | 1135 // call. A test instruction after the call is used to indicate that |
1139 // we have generated an inline version of the keyed load. In this | 1136 // we have generated an inline version of the keyed load. In this |
1140 // case, we know that we are not generating a test instruction next. | 1137 // case, we know that we are not generating a test instruction next. |
1141 | 1138 |
1142 // Push the nth argument. | 1139 // Push the nth argument. |
1143 __ push(eax); | 1140 __ push(eax); |
(...skipping 27 matching lines...) Expand all Loading... |
1171 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1168 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1172 // Stack frame: | 1169 // Stack frame: |
1173 // ebp : Old base pointer | 1170 // ebp : Old base pointer |
1174 // ebp[4] : return address | 1171 // ebp[4] : return address |
1175 // ebp[8] : function arguments | 1172 // ebp[8] : function arguments |
1176 // ebp[12] : receiver | 1173 // ebp[12] : receiver |
1177 // ebp[16] : function | 1174 // ebp[16] : function |
1178 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1175 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1179 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1176 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1180 static const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1177 static const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1178 static const int kVectorOffset = |
| 1179 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1180 |
| 1181 // Push the vector. |
| 1182 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1183 __ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1184 __ push(edi); |
1181 | 1185 |
1182 __ push(Operand(ebp, kFunctionOffset)); // push this | 1186 __ push(Operand(ebp, kFunctionOffset)); // push this |
1183 __ push(Operand(ebp, kArgumentsOffset)); // push arguments | 1187 __ push(Operand(ebp, kArgumentsOffset)); // push arguments |
1184 if (targetIsArgument) { | 1188 if (targetIsArgument) { |
1185 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1189 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1186 } else { | 1190 } else { |
1187 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1191 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1188 } | 1192 } |
1189 | 1193 |
1190 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1194 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); |
1191 | 1195 |
1192 // Push current index and limit. | 1196 // Push current index and limit. |
1193 const int kLimitOffset = | 1197 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1194 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | |
1195 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1198 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1196 __ push(eax); // limit | 1199 __ push(eax); // limit |
1197 __ push(Immediate(0)); // index | 1200 __ push(Immediate(0)); // index |
1198 | 1201 |
1199 // Get the receiver. | 1202 // Get the receiver. |
1200 __ mov(ebx, Operand(ebp, kReceiverOffset)); | 1203 __ mov(ebx, Operand(ebp, kReceiverOffset)); |
1201 | 1204 |
1202 // Check that the function is a JS function (otherwise it must be a proxy). | 1205 // Check that the function is a JS function (otherwise it must be a proxy). |
1203 Label push_receiver, use_global_proxy; | 1206 Label push_receiver, use_global_proxy; |
1204 __ mov(edi, Operand(ebp, kFunctionOffset)); | 1207 __ mov(edi, Operand(ebp, kFunctionOffset)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 __ bind(&use_global_proxy); | 1248 __ bind(&use_global_proxy); |
1246 __ mov(ebx, | 1249 __ mov(ebx, |
1247 Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); | 1250 Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); |
1248 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalProxyOffset)); | 1251 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalProxyOffset)); |
1249 | 1252 |
1250 // Push the receiver. | 1253 // Push the receiver. |
1251 __ bind(&push_receiver); | 1254 __ bind(&push_receiver); |
1252 __ push(ebx); | 1255 __ push(ebx); |
1253 | 1256 |
1254 // Loop over the arguments array, pushing each value to the stack | 1257 // Loop over the arguments array, pushing each value to the stack |
1255 Generate_PushAppliedArguments( | 1258 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1256 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1259 kIndexOffset, kLimitOffset); |
1257 | 1260 |
1258 // Call the function. | 1261 // Call the function. |
1259 Label call_proxy; | 1262 Label call_proxy; |
1260 ParameterCount actual(eax); | 1263 ParameterCount actual(eax); |
1261 __ mov(edi, Operand(ebp, kFunctionOffset)); | 1264 __ mov(edi, Operand(ebp, kFunctionOffset)); |
1262 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 1265 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
1263 __ j(not_equal, &call_proxy); | 1266 __ j(not_equal, &call_proxy); |
1264 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); | 1267 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); |
1265 | 1268 |
1266 frame_scope.GenerateLeaveFrame(); | 1269 frame_scope.GenerateLeaveFrame(); |
(...skipping 28 matching lines...) Expand all Loading... |
1295 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1298 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
1296 // Stack frame: | 1299 // Stack frame: |
1297 // ebp : Old base pointer | 1300 // ebp : Old base pointer |
1298 // ebp[4] : return address | 1301 // ebp[4] : return address |
1299 // ebp[8] : original constructor (new.target) | 1302 // ebp[8] : original constructor (new.target) |
1300 // ebp[12] : arguments | 1303 // ebp[12] : arguments |
1301 // ebp[16] : constructor | 1304 // ebp[16] : constructor |
1302 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; | 1305 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; |
1303 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; | 1306 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize; |
1304 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; | 1307 static const int kFunctionOffset = kArgumentsOffset + kPointerSize; |
| 1308 static const int kVectorOffset = |
| 1309 InternalFrameConstants::kCodeOffset - 1 * kPointerSize; |
| 1310 |
| 1311 // Push the vector. |
| 1312 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1313 __ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset)); |
| 1314 __ push(edi); |
1305 | 1315 |
1306 // If newTarget is not supplied, set it to constructor | 1316 // If newTarget is not supplied, set it to constructor |
1307 Label validate_arguments; | 1317 Label validate_arguments; |
1308 __ mov(eax, Operand(ebp, kNewTargetOffset)); | 1318 __ mov(eax, Operand(ebp, kNewTargetOffset)); |
1309 __ CompareRoot(eax, Heap::kUndefinedValueRootIndex); | 1319 __ CompareRoot(eax, Heap::kUndefinedValueRootIndex); |
1310 __ j(not_equal, &validate_arguments, Label::kNear); | 1320 __ j(not_equal, &validate_arguments, Label::kNear); |
1311 __ mov(eax, Operand(ebp, kFunctionOffset)); | 1321 __ mov(eax, Operand(ebp, kFunctionOffset)); |
1312 __ mov(Operand(ebp, kNewTargetOffset), eax); | 1322 __ mov(Operand(ebp, kNewTargetOffset), eax); |
1313 | 1323 |
1314 // Validate arguments | 1324 // Validate arguments |
1315 __ bind(&validate_arguments); | 1325 __ bind(&validate_arguments); |
1316 __ push(Operand(ebp, kFunctionOffset)); | 1326 __ push(Operand(ebp, kFunctionOffset)); |
1317 __ push(Operand(ebp, kArgumentsOffset)); | 1327 __ push(Operand(ebp, kArgumentsOffset)); |
1318 __ push(Operand(ebp, kNewTargetOffset)); | 1328 __ push(Operand(ebp, kNewTargetOffset)); |
1319 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1329 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1320 | 1330 |
1321 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1331 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); |
1322 | 1332 |
1323 // Push current index and limit. | 1333 // Push current index and limit. |
1324 const int kLimitOffset = | 1334 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1325 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | |
1326 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1335 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1327 __ Push(eax); // limit | 1336 __ Push(eax); // limit |
1328 __ push(Immediate(0)); // index | 1337 __ push(Immediate(0)); // index |
1329 // Push the constructor function as callee. | 1338 // Push the constructor function as callee. |
1330 __ push(Operand(ebp, kFunctionOffset)); | 1339 __ push(Operand(ebp, kFunctionOffset)); |
1331 | 1340 |
1332 // Loop over the arguments array, pushing each value to the stack | 1341 // Loop over the arguments array, pushing each value to the stack |
1333 Generate_PushAppliedArguments( | 1342 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1334 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); | 1343 kIndexOffset, kLimitOffset); |
1335 | 1344 |
1336 // Use undefined feedback vector | 1345 // Use undefined feedback vector |
1337 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); | 1346 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); |
1338 __ mov(edi, Operand(ebp, kFunctionOffset)); | 1347 __ mov(edi, Operand(ebp, kFunctionOffset)); |
1339 __ mov(ecx, Operand(ebp, kNewTargetOffset)); | 1348 __ mov(ecx, Operand(ebp, kNewTargetOffset)); |
1340 | 1349 |
1341 // Call the function. | 1350 // Call the function. |
1342 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); | 1351 CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); |
1343 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 1352 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
1344 | 1353 |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1781 | 1790 |
1782 __ bind(&ok); | 1791 __ bind(&ok); |
1783 __ ret(0); | 1792 __ ret(0); |
1784 } | 1793 } |
1785 | 1794 |
1786 #undef __ | 1795 #undef __ |
1787 } // namespace internal | 1796 } // namespace internal |
1788 } // namespace v8 | 1797 } // namespace v8 |
1789 | 1798 |
1790 #endif // V8_TARGET_ARCH_X87 | 1799 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |