| 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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 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 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 // Check if the arguments will overflow the stack. | 515 // Check if the arguments will overflow the stack. |
| 516 __ cmp(ecx, edx); | 516 __ cmp(ecx, edx); |
| 517 __ j(greater, &okay); // Signed comparison. | 517 __ j(greater, &okay); // Signed comparison. |
| 518 | 518 |
| 519 // Out of stack space. | 519 // Out of stack space. |
| 520 __ push(Operand(ebp, calleeOffset)); // push this | 520 __ push(Operand(ebp, calleeOffset)); // push this |
| 521 if (eax_is_tagged == kEaxIsUntaggedInt) { | 521 if (eax_is_tagged == kEaxIsUntaggedInt) { |
| 522 __ SmiTag(eax); | 522 __ SmiTag(eax); |
| 523 } | 523 } |
| 524 __ push(eax); | 524 __ push(eax); |
| 525 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 525 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
| 526 | 526 |
| 527 __ bind(&okay); | 527 __ bind(&okay); |
| 528 } | 528 } |
| 529 | 529 |
| 530 | 530 |
| 531 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 531 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 532 bool is_construct) { | 532 bool is_construct) { |
| 533 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 533 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 534 | 534 |
| 535 // Clear the context before we push it when entering the internal frame. | 535 // Clear the context before we push it when entering the internal frame. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 BytecodeArray::kFrameSizeOffset)); | 653 BytecodeArray::kFrameSizeOffset)); |
| 654 | 654 |
| 655 // Do a stack check to ensure we don't go over the limit. | 655 // Do a stack check to ensure we don't go over the limit. |
| 656 Label ok; | 656 Label ok; |
| 657 __ mov(ecx, esp); | 657 __ mov(ecx, esp); |
| 658 __ sub(ecx, ebx); | 658 __ sub(ecx, ebx); |
| 659 ExternalReference stack_limit = | 659 ExternalReference stack_limit = |
| 660 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 660 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
| 661 __ cmp(ecx, Operand::StaticVariable(stack_limit)); | 661 __ cmp(ecx, Operand::StaticVariable(stack_limit)); |
| 662 __ j(above_equal, &ok); | 662 __ j(above_equal, &ok); |
| 663 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 663 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
| 664 __ bind(&ok); | 664 __ bind(&ok); |
| 665 | 665 |
| 666 // If ok, push undefined as the initial value for all register file entries. | 666 // If ok, push undefined as the initial value for all register file entries. |
| 667 Label loop_header; | 667 Label loop_header; |
| 668 Label loop_check; | 668 Label loop_check; |
| 669 __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value())); | 669 __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value())); |
| 670 __ jmp(&loop_check); | 670 __ jmp(&loop_check); |
| 671 __ bind(&loop_header); | 671 __ bind(&loop_header); |
| 672 // TODO(rmcilroy): Consider doing more than one push per loop iteration. | 672 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
| 673 __ push(eax); | 673 __ push(eax); |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 __ test(edx, edx); | 1074 __ test(edx, edx); |
| 1075 __ j(zero, &function); | 1075 __ j(zero, &function); |
| 1076 __ Move(ebx, Immediate(0)); | 1076 __ Move(ebx, Immediate(0)); |
| 1077 __ cmp(edx, Immediate(1)); | 1077 __ cmp(edx, Immediate(1)); |
| 1078 __ j(not_equal, &non_proxy); | 1078 __ j(not_equal, &non_proxy); |
| 1079 | 1079 |
| 1080 __ pop(edx); // return address | 1080 __ pop(edx); // return address |
| 1081 __ push(edi); // re-add proxy object as additional argument | 1081 __ push(edi); // re-add proxy object as additional argument |
| 1082 __ push(edx); | 1082 __ push(edx); |
| 1083 __ inc(eax); | 1083 __ inc(eax); |
| 1084 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 1084 __ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); |
| 1085 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1085 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 1086 RelocInfo::CODE_TARGET); | 1086 RelocInfo::CODE_TARGET); |
| 1087 | 1087 |
| 1088 __ bind(&non_proxy); | 1088 __ bind(&non_proxy); |
| 1089 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 1089 __ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX); |
| 1090 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1090 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 1091 RelocInfo::CODE_TARGET); | 1091 RelocInfo::CODE_TARGET); |
| 1092 __ bind(&function); | 1092 __ bind(&function); |
| 1093 } | 1093 } |
| 1094 | 1094 |
| 1095 // 5b. Get the code to call from the function and check that the number of | 1095 // 5b. Get the code to call from the function and check that the number of |
| 1096 // expected arguments matches what we're providing. If so, jump | 1096 // expected arguments matches what we're providing. If so, jump |
| 1097 // (tail-call) to the code in register edx without checking arguments. | 1097 // (tail-call) to the code in register edx without checking arguments. |
| 1098 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1098 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1099 __ mov(ebx, | 1099 __ mov(ebx, |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 // ebp[8] : function arguments | 1176 // ebp[8] : function arguments |
| 1177 // ebp[12] : receiver | 1177 // ebp[12] : receiver |
| 1178 // ebp[16] : function | 1178 // ebp[16] : function |
| 1179 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1179 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
| 1180 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1180 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
| 1181 static const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1181 static const int kFunctionOffset = kReceiverOffset + kPointerSize; |
| 1182 | 1182 |
| 1183 __ push(Operand(ebp, kFunctionOffset)); // push this | 1183 __ push(Operand(ebp, kFunctionOffset)); // push this |
| 1184 __ push(Operand(ebp, kArgumentsOffset)); // push arguments | 1184 __ push(Operand(ebp, kArgumentsOffset)); // push arguments |
| 1185 if (targetIsArgument) { | 1185 if (targetIsArgument) { |
| 1186 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1186 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
| 1187 CALL_FUNCTION); |
| 1187 } else { | 1188 } else { |
| 1188 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1189 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
| 1189 } | 1190 } |
| 1190 | 1191 |
| 1191 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1192 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); |
| 1192 | 1193 |
| 1193 // Push current index and limit. | 1194 // Push current index and limit. |
| 1194 const int kLimitOffset = | 1195 const int kLimitOffset = |
| 1195 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | 1196 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; |
| 1196 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1197 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
| 1197 __ push(eax); // limit | 1198 __ push(eax); // limit |
| 1198 __ push(Immediate(0)); // index | 1199 __ push(Immediate(0)); // index |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1265 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); | 1266 __ InvokeFunction(edi, actual, CALL_FUNCTION, NullCallWrapper()); |
| 1266 | 1267 |
| 1267 frame_scope.GenerateLeaveFrame(); | 1268 frame_scope.GenerateLeaveFrame(); |
| 1268 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments | 1269 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments |
| 1269 | 1270 |
| 1270 // Call the function proxy. | 1271 // Call the function proxy. |
| 1271 __ bind(&call_proxy); | 1272 __ bind(&call_proxy); |
| 1272 __ push(edi); // add function proxy as last argument | 1273 __ push(edi); // add function proxy as last argument |
| 1273 __ inc(eax); | 1274 __ inc(eax); |
| 1274 __ Move(ebx, Immediate(0)); | 1275 __ Move(ebx, Immediate(0)); |
| 1275 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); | 1276 __ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); |
| 1276 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1277 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 1277 RelocInfo::CODE_TARGET); | 1278 RelocInfo::CODE_TARGET); |
| 1278 | 1279 |
| 1279 // Leave internal frame. | 1280 // Leave internal frame. |
| 1280 } | 1281 } |
| 1281 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments | 1282 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments |
| 1282 } | 1283 } |
| 1283 | 1284 |
| 1284 | 1285 |
| 1285 // Used by ReflectConstruct | 1286 // Used by ReflectConstruct |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1310 __ CompareRoot(eax, Heap::kUndefinedValueRootIndex); | 1311 __ CompareRoot(eax, Heap::kUndefinedValueRootIndex); |
| 1311 __ j(not_equal, &validate_arguments, Label::kNear); | 1312 __ j(not_equal, &validate_arguments, Label::kNear); |
| 1312 __ mov(eax, Operand(ebp, kFunctionOffset)); | 1313 __ mov(eax, Operand(ebp, kFunctionOffset)); |
| 1313 __ mov(Operand(ebp, kNewTargetOffset), eax); | 1314 __ mov(Operand(ebp, kNewTargetOffset), eax); |
| 1314 | 1315 |
| 1315 // Validate arguments | 1316 // Validate arguments |
| 1316 __ bind(&validate_arguments); | 1317 __ bind(&validate_arguments); |
| 1317 __ push(Operand(ebp, kFunctionOffset)); | 1318 __ push(Operand(ebp, kFunctionOffset)); |
| 1318 __ push(Operand(ebp, kArgumentsOffset)); | 1319 __ push(Operand(ebp, kArgumentsOffset)); |
| 1319 __ push(Operand(ebp, kNewTargetOffset)); | 1320 __ push(Operand(ebp, kNewTargetOffset)); |
| 1320 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1321 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
| 1322 CALL_FUNCTION); |
| 1321 | 1323 |
| 1322 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); | 1324 Generate_CheckStackOverflow(masm, kFunctionOffset, kEaxIsSmiTagged); |
| 1323 | 1325 |
| 1324 // Push current index and limit. | 1326 // Push current index and limit. |
| 1325 const int kLimitOffset = | 1327 const int kLimitOffset = |
| 1326 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | 1328 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; |
| 1327 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1329 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
| 1328 __ Push(eax); // limit | 1330 __ Push(eax); // limit |
| 1329 __ push(Immediate(0)); // index | 1331 __ push(Immediate(0)); // index |
| 1330 // Push the constructor function as callee. | 1332 // Push the constructor function as callee. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 __ IncrementCounter(counters->string_ctor_string_value(), 1); | 1516 __ IncrementCounter(counters->string_ctor_string_value(), 1); |
| 1515 __ jmp(&argument_is_string); | 1517 __ jmp(&argument_is_string); |
| 1516 | 1518 |
| 1517 // Invoke the conversion builtin and put the result into ebx. | 1519 // Invoke the conversion builtin and put the result into ebx. |
| 1518 __ bind(&convert_argument); | 1520 __ bind(&convert_argument); |
| 1519 __ IncrementCounter(counters->string_ctor_conversions(), 1); | 1521 __ IncrementCounter(counters->string_ctor_conversions(), 1); |
| 1520 { | 1522 { |
| 1521 FrameScope scope(masm, StackFrame::INTERNAL); | 1523 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1522 __ push(edi); // Preserve the function. | 1524 __ push(edi); // Preserve the function. |
| 1523 __ push(eax); | 1525 __ push(eax); |
| 1524 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 1526 __ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION); |
| 1525 __ pop(edi); | 1527 __ pop(edi); |
| 1526 } | 1528 } |
| 1527 __ mov(ebx, eax); | 1529 __ mov(ebx, eax); |
| 1528 __ jmp(&argument_is_string); | 1530 __ jmp(&argument_is_string); |
| 1529 | 1531 |
| 1530 // Load the empty string into ebx, remove the receiver from the | 1532 // Load the empty string into ebx, remove the receiver from the |
| 1531 // stack, and jump back to the case where the argument is a string. | 1533 // stack, and jump back to the case where the argument is a string. |
| 1532 __ bind(&no_arguments); | 1534 __ bind(&no_arguments); |
| 1533 __ Move(ebx, Immediate(factory->empty_string())); | 1535 __ Move(ebx, Immediate(factory->empty_string())); |
| 1534 __ pop(ecx); | 1536 __ pop(ecx); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 // ------------------------------------------- | 1718 // ------------------------------------------- |
| 1717 // Dont adapt arguments. | 1719 // Dont adapt arguments. |
| 1718 // ------------------------------------------- | 1720 // ------------------------------------------- |
| 1719 __ bind(&dont_adapt_arguments); | 1721 __ bind(&dont_adapt_arguments); |
| 1720 __ jmp(edx); | 1722 __ jmp(edx); |
| 1721 | 1723 |
| 1722 __ bind(&stack_overflow); | 1724 __ bind(&stack_overflow); |
| 1723 { | 1725 { |
| 1724 FrameScope frame(masm, StackFrame::MANUAL); | 1726 FrameScope frame(masm, StackFrame::MANUAL); |
| 1725 EnterArgumentsAdaptorFrame(masm); | 1727 EnterArgumentsAdaptorFrame(masm); |
| 1726 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 1728 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
| 1727 __ int3(); | 1729 __ int3(); |
| 1728 } | 1730 } |
| 1729 } | 1731 } |
| 1730 | 1732 |
| 1731 | 1733 |
| 1732 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1734 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 1733 // Lookup the function in the JavaScript frame. | 1735 // Lookup the function in the JavaScript frame. |
| 1734 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1736 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1735 { | 1737 { |
| 1736 FrameScope scope(masm, StackFrame::INTERNAL); | 1738 FrameScope scope(masm, StackFrame::INTERNAL); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 | 1784 |
| 1783 __ bind(&ok); | 1785 __ bind(&ok); |
| 1784 __ ret(0); | 1786 __ ret(0); |
| 1785 } | 1787 } |
| 1786 | 1788 |
| 1787 #undef __ | 1789 #undef __ |
| 1788 } // namespace internal | 1790 } // namespace internal |
| 1789 } // namespace v8 | 1791 } // namespace v8 |
| 1790 | 1792 |
| 1791 #endif // V8_TARGET_ARCH_IA32 | 1793 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |