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 |