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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 // Check if the arguments will overflow the stack. | 518 // Check if the arguments will overflow the stack. |
519 __ cmpp(rcx, rdx); | 519 __ cmpp(rcx, rdx); |
520 __ j(greater, &okay); // Signed comparison. | 520 __ j(greater, &okay); // Signed comparison. |
521 | 521 |
522 // Out of stack space. | 522 // Out of stack space. |
523 __ Push(Operand(rbp, calleeOffset)); | 523 __ Push(Operand(rbp, calleeOffset)); |
524 if (rax_is_tagged == kRaxIsUntaggedInt) { | 524 if (rax_is_tagged == kRaxIsUntaggedInt) { |
525 __ Integer32ToSmi(rax, rax); | 525 __ Integer32ToSmi(rax, rax); |
526 } | 526 } |
527 __ Push(rax); | 527 __ Push(rax); |
528 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 528 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
529 | 529 |
530 __ bind(&okay); | 530 __ bind(&okay); |
531 } | 531 } |
532 | 532 |
533 | 533 |
534 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 534 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
535 bool is_construct) { | 535 bool is_construct) { |
536 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 536 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
537 | 537 |
538 // Expects five C++ function parameters. | 538 // Expects five C++ function parameters. |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 // Load frame size from the BytecodeArray object. | 711 // Load frame size from the BytecodeArray object. |
712 __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, | 712 __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, |
713 BytecodeArray::kFrameSizeOffset)); | 713 BytecodeArray::kFrameSizeOffset)); |
714 | 714 |
715 // Do a stack check to ensure we don't go over the limit. | 715 // Do a stack check to ensure we don't go over the limit. |
716 Label ok; | 716 Label ok; |
717 __ movp(rdx, rsp); | 717 __ movp(rdx, rsp); |
718 __ subp(rdx, rcx); | 718 __ subp(rdx, rcx); |
719 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); | 719 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); |
720 __ j(above_equal, &ok, Label::kNear); | 720 __ j(above_equal, &ok, Label::kNear); |
721 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 721 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
722 __ bind(&ok); | 722 __ bind(&ok); |
723 | 723 |
724 // If ok, push undefined as the initial value for all register file entries. | 724 // If ok, push undefined as the initial value for all register file entries. |
725 Label loop_header; | 725 Label loop_header; |
726 Label loop_check; | 726 Label loop_check; |
727 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 727 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
728 __ j(always, &loop_check); | 728 __ j(always, &loop_check); |
729 __ bind(&loop_header); | 729 __ bind(&loop_header); |
730 // TODO(rmcilroy): Consider doing more than one push per loop iteration. | 730 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
731 __ Push(rdx); | 731 __ Push(rdx); |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 __ testp(rdx, rdx); | 1129 __ testp(rdx, rdx); |
1130 __ j(zero, &function); | 1130 __ j(zero, &function); |
1131 __ Set(rbx, 0); | 1131 __ Set(rbx, 0); |
1132 __ cmpp(rdx, Immediate(1)); | 1132 __ cmpp(rdx, Immediate(1)); |
1133 __ j(not_equal, &non_proxy); | 1133 __ j(not_equal, &non_proxy); |
1134 | 1134 |
1135 __ PopReturnAddressTo(rdx); | 1135 __ PopReturnAddressTo(rdx); |
1136 __ Push(rdi); // re-add proxy object as additional argument | 1136 __ Push(rdi); // re-add proxy object as additional argument |
1137 __ PushReturnAddressFrom(rdx); | 1137 __ PushReturnAddressFrom(rdx); |
1138 __ incp(rax); | 1138 __ incp(rax); |
1139 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); | 1139 __ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); |
1140 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1140 __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1141 RelocInfo::CODE_TARGET); | 1141 RelocInfo::CODE_TARGET); |
1142 | 1142 |
1143 __ bind(&non_proxy); | 1143 __ bind(&non_proxy); |
1144 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | 1144 __ GetBuiltinEntry(rdx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX); |
1145 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1145 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1146 RelocInfo::CODE_TARGET); | 1146 RelocInfo::CODE_TARGET); |
1147 __ bind(&function); | 1147 __ bind(&function); |
1148 } | 1148 } |
1149 | 1149 |
1150 // 5b. Get the code to call from the function and check that the number of | 1150 // 5b. Get the code to call from the function and check that the number of |
1151 // expected arguments matches what we're providing. If so, jump | 1151 // expected arguments matches what we're providing. If so, jump |
1152 // (tail-call) to the code in register edx without checking arguments. | 1152 // (tail-call) to the code in register edx without checking arguments. |
1153 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 1153 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
1154 __ LoadSharedFunctionInfoSpecialField(rbx, rdx, | 1154 __ LoadSharedFunctionInfoSpecialField(rbx, rdx, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 // rbp[16] : function arguments | 1231 // rbp[16] : function arguments |
1232 // rbp[24] : receiver | 1232 // rbp[24] : receiver |
1233 // rbp[32] : function | 1233 // rbp[32] : function |
1234 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; | 1234 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; |
1235 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; | 1235 static const int kReceiverOffset = kArgumentsOffset + kPointerSize; |
1236 static const int kFunctionOffset = kReceiverOffset + kPointerSize; | 1236 static const int kFunctionOffset = kReceiverOffset + kPointerSize; |
1237 | 1237 |
1238 __ Push(Operand(rbp, kFunctionOffset)); | 1238 __ Push(Operand(rbp, kFunctionOffset)); |
1239 __ Push(Operand(rbp, kArgumentsOffset)); | 1239 __ Push(Operand(rbp, kArgumentsOffset)); |
1240 if (targetIsArgument) { | 1240 if (targetIsArgument) { |
1241 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1241 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
| 1242 CALL_FUNCTION); |
1242 } else { | 1243 } else { |
1243 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1244 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
1244 } | 1245 } |
1245 | 1246 |
1246 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1247 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); |
1247 | 1248 |
1248 // Push current index and limit. | 1249 // Push current index and limit. |
1249 const int kLimitOffset = | 1250 const int kLimitOffset = |
1250 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | 1251 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; |
1251 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1252 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1252 __ Push(rax); // limit | 1253 __ Push(rax); // limit |
1253 __ Push(Immediate(0)); // index | 1254 __ Push(Immediate(0)); // index |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1319 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); | 1320 __ InvokeFunction(rdi, actual, CALL_FUNCTION, NullCallWrapper()); |
1320 | 1321 |
1321 frame_scope.GenerateLeaveFrame(); | 1322 frame_scope.GenerateLeaveFrame(); |
1322 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments | 1323 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments |
1323 | 1324 |
1324 // Call the function proxy. | 1325 // Call the function proxy. |
1325 __ bind(&call_proxy); | 1326 __ bind(&call_proxy); |
1326 __ Push(rdi); // add function proxy as last argument | 1327 __ Push(rdi); // add function proxy as last argument |
1327 __ incp(rax); | 1328 __ incp(rax); |
1328 __ Set(rbx, 0); | 1329 __ Set(rbx, 0); |
1329 __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY); | 1330 __ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); |
1330 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1331 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1331 RelocInfo::CODE_TARGET); | 1332 RelocInfo::CODE_TARGET); |
1332 | 1333 |
1333 // Leave internal frame. | 1334 // Leave internal frame. |
1334 } | 1335 } |
1335 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments | 1336 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments |
1336 } | 1337 } |
1337 | 1338 |
1338 | 1339 |
1339 // Used by ReflectConstruct | 1340 // Used by ReflectConstruct |
(...skipping 24 matching lines...) Expand all Loading... |
1364 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 1365 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
1365 __ j(not_equal, &validate_arguments, Label::kNear); | 1366 __ j(not_equal, &validate_arguments, Label::kNear); |
1366 __ movp(rax, Operand(rbp, kFunctionOffset)); | 1367 __ movp(rax, Operand(rbp, kFunctionOffset)); |
1367 __ movp(Operand(rbp, kNewTargetOffset), rax); | 1368 __ movp(Operand(rbp, kNewTargetOffset), rax); |
1368 | 1369 |
1369 // Validate arguments | 1370 // Validate arguments |
1370 __ bind(&validate_arguments); | 1371 __ bind(&validate_arguments); |
1371 __ Push(Operand(rbp, kFunctionOffset)); | 1372 __ Push(Operand(rbp, kFunctionOffset)); |
1372 __ Push(Operand(rbp, kArgumentsOffset)); | 1373 __ Push(Operand(rbp, kArgumentsOffset)); |
1373 __ Push(Operand(rbp, kNewTargetOffset)); | 1374 __ Push(Operand(rbp, kNewTargetOffset)); |
1374 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1375 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
| 1376 CALL_FUNCTION); |
1375 | 1377 |
1376 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1378 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); |
1377 | 1379 |
1378 // Push current index and limit. | 1380 // Push current index and limit. |
1379 const int kLimitOffset = | 1381 const int kLimitOffset = |
1380 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; | 1382 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; |
1381 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1383 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1382 __ Push(rax); // limit | 1384 __ Push(rax); // limit |
1383 __ Push(Immediate(0)); // index | 1385 __ Push(Immediate(0)); // index |
1384 // Push the constructor function as callee. | 1386 // Push the constructor function as callee. |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 __ IncrementCounter(counters->string_ctor_string_value(), 1); | 1573 __ IncrementCounter(counters->string_ctor_string_value(), 1); |
1572 __ jmp(&argument_is_string); | 1574 __ jmp(&argument_is_string); |
1573 | 1575 |
1574 // Invoke the conversion builtin and put the result into rbx. | 1576 // Invoke the conversion builtin and put the result into rbx. |
1575 __ bind(&convert_argument); | 1577 __ bind(&convert_argument); |
1576 __ IncrementCounter(counters->string_ctor_conversions(), 1); | 1578 __ IncrementCounter(counters->string_ctor_conversions(), 1); |
1577 { | 1579 { |
1578 FrameScope scope(masm, StackFrame::INTERNAL); | 1580 FrameScope scope(masm, StackFrame::INTERNAL); |
1579 __ Push(rdi); // Preserve the function. | 1581 __ Push(rdi); // Preserve the function. |
1580 __ Push(rax); | 1582 __ Push(rax); |
1581 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 1583 __ InvokeBuiltin(Context::TO_STRING_BUILTIN_INDEX, CALL_FUNCTION); |
1582 __ Pop(rdi); | 1584 __ Pop(rdi); |
1583 } | 1585 } |
1584 __ movp(rbx, rax); | 1586 __ movp(rbx, rax); |
1585 __ jmp(&argument_is_string); | 1587 __ jmp(&argument_is_string); |
1586 | 1588 |
1587 // Load the empty string into rbx, remove the receiver from the | 1589 // Load the empty string into rbx, remove the receiver from the |
1588 // stack, and jump back to the case where the argument is a string. | 1590 // stack, and jump back to the case where the argument is a string. |
1589 __ bind(&no_arguments); | 1591 __ bind(&no_arguments); |
1590 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); | 1592 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
1591 __ PopReturnAddressTo(rcx); | 1593 __ PopReturnAddressTo(rcx); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1785 // ------------------------------------------- | 1787 // ------------------------------------------- |
1786 // Dont adapt arguments. | 1788 // Dont adapt arguments. |
1787 // ------------------------------------------- | 1789 // ------------------------------------------- |
1788 __ bind(&dont_adapt_arguments); | 1790 __ bind(&dont_adapt_arguments); |
1789 __ jmp(rdx); | 1791 __ jmp(rdx); |
1790 | 1792 |
1791 __ bind(&stack_overflow); | 1793 __ bind(&stack_overflow); |
1792 { | 1794 { |
1793 FrameScope frame(masm, StackFrame::MANUAL); | 1795 FrameScope frame(masm, StackFrame::MANUAL); |
1794 EnterArgumentsAdaptorFrame(masm); | 1796 EnterArgumentsAdaptorFrame(masm); |
1795 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 1797 __ InvokeBuiltin(Context::STACK_OVERFLOW_BUILTIN_INDEX, CALL_FUNCTION); |
1796 __ int3(); | 1798 __ int3(); |
1797 } | 1799 } |
1798 } | 1800 } |
1799 | 1801 |
1800 | 1802 |
1801 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1803 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1802 // Lookup the function in the JavaScript frame. | 1804 // Lookup the function in the JavaScript frame. |
1803 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1805 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
1804 { | 1806 { |
1805 FrameScope scope(masm, StackFrame::INTERNAL); | 1807 FrameScope scope(masm, StackFrame::INTERNAL); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 __ ret(0); | 1852 __ ret(0); |
1851 } | 1853 } |
1852 | 1854 |
1853 | 1855 |
1854 #undef __ | 1856 #undef __ |
1855 | 1857 |
1856 } // namespace internal | 1858 } // namespace internal |
1857 } // namespace v8 | 1859 } // namespace v8 |
1858 | 1860 |
1859 #endif // V8_TARGET_ARCH_X64 | 1861 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |