OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #if defined(V8_TARGET_ARCH_X64) | 30 #if V8_TARGET_ARCH_X64 |
31 | 31 |
32 #include "codegen.h" | 32 #include "codegen.h" |
33 #include "deoptimizer.h" | 33 #include "deoptimizer.h" |
34 #include "full-codegen.h" | 34 #include "full-codegen.h" |
35 | 35 |
36 namespace v8 { | 36 namespace v8 { |
37 namespace internal { | 37 namespace internal { |
38 | 38 |
39 | 39 |
40 #define __ ACCESS_MASM(masm) | 40 #define __ ACCESS_MASM(masm) |
41 | 41 |
42 | 42 |
43 void Builtins::Generate_Adaptor(MacroAssembler* masm, | 43 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
44 CFunctionId id, | 44 CFunctionId id, |
45 BuiltinExtraArguments extra_args) { | 45 BuiltinExtraArguments extra_args) { |
46 // ----------- S t a t e ------------- | 46 // ----------- S t a t e ------------- |
47 // -- rax : number of arguments excluding receiver | 47 // -- rax : number of arguments excluding receiver |
48 // -- rdi : called function (only guaranteed when | 48 // -- rdi : called function (only guaranteed when |
49 // extra_args requires it) | 49 // extra_args requires it) |
50 // -- rsi : context | 50 // -- rsi : context |
51 // -- rsp[0] : return address | 51 // -- rsp[0] : return address |
52 // -- rsp[8] : last argument | 52 // -- rsp[8] : last argument |
53 // -- ... | 53 // -- ... |
54 // -- rsp[8 * argc] : first argument (argc == rax) | 54 // -- rsp[8 * argc] : first argument (argc == rax) |
55 // -- rsp[8 * (argc +1)] : receiver | 55 // -- rsp[8 * (argc + 1)] : receiver |
56 // ----------------------------------- | 56 // ----------------------------------- |
57 | 57 |
58 // Insert extra arguments. | 58 // Insert extra arguments. |
59 int num_extra_args = 0; | 59 int num_extra_args = 0; |
60 if (extra_args == NEEDS_CALLED_FUNCTION) { | 60 if (extra_args == NEEDS_CALLED_FUNCTION) { |
61 num_extra_args = 1; | 61 num_extra_args = 1; |
62 __ pop(kScratchRegister); // Save return address. | 62 __ pop(kScratchRegister); // Save return address. |
63 __ push(rdi); | 63 __ push(rdi); |
64 __ push(kScratchRegister); // Restore return address. | 64 __ push(kScratchRegister); // Restore return address. |
65 } else { | 65 } else { |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 } | 449 } |
450 | 450 |
451 | 451 |
452 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 452 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
453 Generate_JSConstructStubHelper(masm, true, false); | 453 Generate_JSConstructStubHelper(masm, true, false); |
454 } | 454 } |
455 | 455 |
456 | 456 |
457 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 457 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
458 bool is_construct) { | 458 bool is_construct) { |
| 459 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 460 |
459 // Expects five C++ function parameters. | 461 // Expects five C++ function parameters. |
460 // - Address entry (ignored) | 462 // - Address entry (ignored) |
461 // - JSFunction* function ( | 463 // - JSFunction* function ( |
462 // - Object* receiver | 464 // - Object* receiver |
463 // - int argc | 465 // - int argc |
464 // - Object*** argv | 466 // - Object*** argv |
465 // (see Handle::Invoke in execution.cc). | 467 // (see Handle::Invoke in execution.cc). |
466 | 468 |
467 // Open a C++ scope for the FrameScope. | 469 // Open a C++ scope for the FrameScope. |
468 { | 470 { |
469 // Platform specific argument handling. After this, the stack contains | 471 // Platform specific argument handling. After this, the stack contains |
470 // an internal frame and the pushed function and receiver, and | 472 // an internal frame and the pushed function and receiver, and |
471 // register rax and rbx holds the argument count and argument array, | 473 // register rax and rbx holds the argument count and argument array, |
472 // while rdi holds the function pointer and rsi the context. | 474 // while rdi holds the function pointer and rsi the context. |
473 | 475 |
474 #ifdef _WIN64 | 476 #ifdef _WIN64 |
475 // MSVC parameters in: | 477 // MSVC parameters in: |
476 // rcx : entry (ignored) | 478 // rcx : entry (ignored) |
477 // rdx : function | 479 // rdx : function |
478 // r8 : receiver | 480 // r8 : receiver |
479 // r9 : argc | 481 // r9 : argc |
480 // [rsp+0x20] : argv | 482 // [rsp+0x20] : argv |
481 | 483 |
482 // Clear the context before we push it when entering the internal frame. | 484 // Clear the context before we push it when entering the internal frame. |
483 __ Set(rsi, 0); | 485 __ Set(rsi, 0); |
484 // Enter an internal frame. | 486 // Enter an internal frame. |
485 FrameScope scope(masm, StackFrame::INTERNAL); | 487 FrameScope scope(masm, StackFrame::INTERNAL); |
486 | 488 |
487 // Load the function context into rsi. | 489 // Load the function context into rsi. |
488 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); | 490 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); |
489 | 491 |
(...skipping 28 matching lines...) Expand all Loading... |
518 __ push(rdi); | 520 __ push(rdi); |
519 __ push(rdx); | 521 __ push(rdx); |
520 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 522 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
521 | 523 |
522 // Load the number of arguments and setup pointer to the arguments. | 524 // Load the number of arguments and setup pointer to the arguments. |
523 __ movq(rax, rcx); | 525 __ movq(rax, rcx); |
524 __ movq(rbx, r8); | 526 __ movq(rbx, r8); |
525 #endif // _WIN64 | 527 #endif // _WIN64 |
526 | 528 |
527 // Current stack contents: | 529 // Current stack contents: |
528 // [rsp + 2 * kPointerSize ... ]: Internal frame | 530 // [rsp + 2 * kPointerSize ... ] : Internal frame |
529 // [rsp + kPointerSize] : function | 531 // [rsp + kPointerSize] : function |
530 // [rsp] : receiver | 532 // [rsp] : receiver |
531 // Current register contents: | 533 // Current register contents: |
532 // rax : argc | 534 // rax : argc |
533 // rbx : argv | 535 // rbx : argv |
534 // rsi : context | 536 // rsi : context |
535 // rdi : function | 537 // rdi : function |
536 | 538 |
537 // Copy arguments to the stack in a loop. | 539 // Copy arguments to the stack in a loop. |
538 // Register rbx points to array of pointers to handle locations. | 540 // Register rbx points to array of pointers to handle locations. |
539 // Push the values of these handles. | 541 // Push the values of these handles. |
540 Label loop, entry; | 542 Label loop, entry; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 __ bind(¬_no_registers); | 719 __ bind(¬_no_registers); |
718 __ movq(rax, Operand(rsp, 2 * kPointerSize)); | 720 __ movq(rax, Operand(rsp, 2 * kPointerSize)); |
719 __ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG)); | 721 __ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG)); |
720 __ j(not_equal, ¬_tos_rax, Label::kNear); | 722 __ j(not_equal, ¬_tos_rax, Label::kNear); |
721 __ ret(2 * kPointerSize); // Remove state, rax. | 723 __ ret(2 * kPointerSize); // Remove state, rax. |
722 | 724 |
723 __ bind(¬_tos_rax); | 725 __ bind(¬_tos_rax); |
724 __ Abort("no cases left"); | 726 __ Abort("no cases left"); |
725 } | 727 } |
726 | 728 |
| 729 |
727 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 730 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { |
728 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 731 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); |
729 } | 732 } |
730 | 733 |
731 | 734 |
732 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 735 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { |
733 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 736 Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); |
734 } | 737 } |
735 | 738 |
736 | 739 |
(...skipping 12 matching lines...) Expand all Loading... |
749 FrameScope scope(masm, StackFrame::INTERNAL); | 752 FrameScope scope(masm, StackFrame::INTERNAL); |
750 __ CallRuntime(Runtime::kNotifyOSR, 0); | 753 __ CallRuntime(Runtime::kNotifyOSR, 0); |
751 } | 754 } |
752 __ Popad(); | 755 __ Popad(); |
753 __ ret(0); | 756 __ ret(0); |
754 } | 757 } |
755 | 758 |
756 | 759 |
757 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 760 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
758 // Stack Layout: | 761 // Stack Layout: |
759 // rsp[0]: Return address | 762 // rsp[0] : Return address |
760 // rsp[1]: Argument n | 763 // rsp[8] : Argument n |
761 // rsp[2]: Argument n-1 | 764 // rsp[16] : Argument n-1 |
762 // ... | 765 // ... |
763 // rsp[n]: Argument 1 | 766 // rsp[8 * n] : Argument 1 |
764 // rsp[n+1]: Receiver (function to call) | 767 // rsp[8 * (n + 1)] : Receiver (function to call) |
765 // | 768 // |
766 // rax contains the number of arguments, n, not counting the receiver. | 769 // rax contains the number of arguments, n, not counting the receiver. |
767 // | 770 // |
768 // 1. Make sure we have at least one argument. | 771 // 1. Make sure we have at least one argument. |
769 { Label done; | 772 { Label done; |
770 __ testq(rax, rax); | 773 __ testq(rax, rax); |
771 __ j(not_zero, &done); | 774 __ j(not_zero, &done); |
772 __ pop(rbx); | 775 __ pop(rbx); |
773 __ Push(masm->isolate()->factory()->undefined_value()); | 776 __ Push(masm->isolate()->factory()->undefined_value()); |
774 __ push(rbx); | 777 __ push(rbx); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 RelocInfo::CODE_TARGET); | 925 RelocInfo::CODE_TARGET); |
923 | 926 |
924 ParameterCount expected(0); | 927 ParameterCount expected(0); |
925 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, | 928 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, |
926 NullCallWrapper(), CALL_AS_METHOD); | 929 NullCallWrapper(), CALL_AS_METHOD); |
927 } | 930 } |
928 | 931 |
929 | 932 |
930 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 933 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
931 // Stack at entry: | 934 // Stack at entry: |
932 // rsp: return address | 935 // rsp : return address |
933 // rsp+8: arguments | 936 // rsp[8] : arguments |
934 // rsp+16: receiver ("this") | 937 // rsp[16] : receiver ("this") |
935 // rsp+24: function | 938 // rsp[24] : function |
936 { | 939 { |
937 FrameScope frame_scope(masm, StackFrame::INTERNAL); | 940 FrameScope frame_scope(masm, StackFrame::INTERNAL); |
938 // Stack frame: | 941 // Stack frame: |
939 // rbp: Old base pointer | 942 // rbp : Old base pointer |
940 // rbp[1]: return address | 943 // rbp[8] : return address |
941 // rbp[2]: function arguments | 944 // rbp[16] : function arguments |
942 // rbp[3]: receiver | 945 // rbp[24] : receiver |
943 // rbp[4]: function | 946 // rbp[32] : function |
944 static const int kArgumentsOffset = 2 * kPointerSize; | 947 static const int kArgumentsOffset = 2 * kPointerSize; |
945 static const int kReceiverOffset = 3 * kPointerSize; | 948 static const int kReceiverOffset = 3 * kPointerSize; |
946 static const int kFunctionOffset = 4 * kPointerSize; | 949 static const int kFunctionOffset = 4 * kPointerSize; |
947 | 950 |
948 __ push(Operand(rbp, kFunctionOffset)); | 951 __ push(Operand(rbp, kFunctionOffset)); |
949 __ push(Operand(rbp, kArgumentsOffset)); | 952 __ push(Operand(rbp, kArgumentsOffset)); |
950 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 953 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
951 | 954 |
952 // Check the stack for overflow. We are not trying to catch | 955 // Check the stack for overflow. We are not trying to catch |
953 // interruptions (e.g. debug break and preemption) here, so the "real stack | 956 // interruptions (e.g. debug break and preemption) here, so the "real stack |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 RelocInfo::CODE_TARGET); | 1091 RelocInfo::CODE_TARGET); |
1089 | 1092 |
1090 // Leave internal frame. | 1093 // Leave internal frame. |
1091 } | 1094 } |
1092 __ ret(3 * kPointerSize); // remove this, receiver, and arguments | 1095 __ ret(3 * kPointerSize); // remove this, receiver, and arguments |
1093 } | 1096 } |
1094 | 1097 |
1095 | 1098 |
1096 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1099 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1097 // ----------- S t a t e ------------- | 1100 // ----------- S t a t e ------------- |
1098 // -- rax : argc | 1101 // -- rax : argc |
1099 // -- rsp[0] : return address | 1102 // -- rsp[0] : return address |
1100 // -- rsp[8] : last argument | 1103 // -- rsp[8] : last argument |
1101 // ----------------------------------- | 1104 // ----------------------------------- |
1102 Label generic_array_code; | 1105 Label generic_array_code; |
1103 | 1106 |
1104 // Get the InternalArray function. | 1107 // Get the InternalArray function. |
1105 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, rdi); | 1108 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, rdi); |
1106 | 1109 |
1107 if (FLAG_debug_code) { | 1110 if (FLAG_debug_code) { |
1108 // Initial map for the builtin InternalArray functions should be maps. | 1111 // Initial map for the builtin InternalArray functions should be maps. |
1109 __ movq(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 1112 __ movq(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
1110 // Will both indicate a NULL and a Smi. | 1113 // Will both indicate a NULL and a Smi. |
1111 STATIC_ASSERT(kSmiTag == 0); | 1114 STATIC_ASSERT(kSmiTag == 0); |
1112 Condition not_smi = NegateCondition(masm->CheckSmi(rbx)); | 1115 Condition not_smi = NegateCondition(masm->CheckSmi(rbx)); |
1113 __ Check(not_smi, "Unexpected initial map for InternalArray function"); | 1116 __ Check(not_smi, "Unexpected initial map for InternalArray function"); |
1114 __ CmpObjectType(rbx, MAP_TYPE, rcx); | 1117 __ CmpObjectType(rbx, MAP_TYPE, rcx); |
1115 __ Check(equal, "Unexpected initial map for InternalArray function"); | 1118 __ Check(equal, "Unexpected initial map for InternalArray function"); |
1116 } | 1119 } |
1117 | 1120 |
1118 // Run the native code for the InternalArray function called as a normal | 1121 // Run the native code for the InternalArray function called as a normal |
1119 // function. | 1122 // function. |
1120 // tail call a stub | 1123 // tail call a stub |
1121 InternalArrayConstructorStub stub(masm->isolate()); | 1124 InternalArrayConstructorStub stub(masm->isolate()); |
1122 __ TailCallStub(&stub); | 1125 __ TailCallStub(&stub); |
1123 } | 1126 } |
1124 | 1127 |
1125 | 1128 |
1126 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 1129 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { |
1127 // ----------- S t a t e ------------- | 1130 // ----------- S t a t e ------------- |
1128 // -- rax : argc | 1131 // -- rax : argc |
1129 // -- rsp[0] : return address | 1132 // -- rsp[0] : return address |
1130 // -- rsp[8] : last argument | 1133 // -- rsp[8] : last argument |
1131 // ----------------------------------- | 1134 // ----------------------------------- |
1132 Label generic_array_code; | 1135 Label generic_array_code; |
1133 | 1136 |
1134 // Get the Array function. | 1137 // Get the Array function. |
1135 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rdi); | 1138 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rdi); |
1136 | 1139 |
1137 if (FLAG_debug_code) { | 1140 if (FLAG_debug_code) { |
1138 // Initial map for the builtin Array functions should be maps. | 1141 // Initial map for the builtin Array functions should be maps. |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1435 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1433 generator.Generate(); | 1436 generator.Generate(); |
1434 } | 1437 } |
1435 | 1438 |
1436 | 1439 |
1437 #undef __ | 1440 #undef __ |
1438 | 1441 |
1439 } } // namespace v8::internal | 1442 } } // namespace v8::internal |
1440 | 1443 |
1441 #endif // V8_TARGET_ARCH_X64 | 1444 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |