OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 void Builtins::Generate_Adaptor(MacroAssembler* masm, | 47 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
48 CFunctionId id, | 48 CFunctionId id, |
49 BuiltinExtraArguments extra_args) { | 49 BuiltinExtraArguments extra_args) { |
50 // ----------- S t a t e ------------- | 50 // ----------- S t a t e ------------- |
51 // -- x0 : number of arguments excluding receiver | 51 // -- x0 : number of arguments excluding receiver |
52 // -- x1 : called function (only guaranteed when | 52 // -- x1 : called function (only guaranteed when |
53 // extra_args requires it) | 53 // extra_args requires it) |
54 // -- cp : context | |
55 // -- sp[0] : last argument | 54 // -- sp[0] : last argument |
56 // -- ... | 55 // -- ... |
57 // -- sp[4 * (argc - 1)] : first argument (argc == x0) | 56 // -- sp[4 * (argc - 1)] : first argument (argc == x0) |
58 // -- sp[4 * argc] : receiver | 57 // -- sp[4 * argc] : receiver |
59 // ----------------------------------- | 58 // ----------------------------------- |
| 59 __ AssertFunction(x1); |
| 60 |
| 61 // Make sure we operate in the context of the called function (for example |
| 62 // ConstructStubs implemented in C++ will be run in the context of the caller |
| 63 // instead of the callee, due to the way that [[Construct]] is defined for |
| 64 // ordinary functions). |
| 65 // TODO(bmeurer): Can we make this more robust? |
| 66 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); |
60 | 67 |
61 // Insert extra arguments. | 68 // Insert extra arguments. |
62 int num_extra_args = 0; | 69 int num_extra_args = 0; |
63 if (extra_args == NEEDS_CALLED_FUNCTION) { | 70 if (extra_args == NEEDS_CALLED_FUNCTION) { |
64 num_extra_args = 1; | 71 num_extra_args = 1; |
65 __ Push(x1); | 72 __ Push(x1); |
66 } else { | 73 } else { |
67 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); | 74 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); |
68 } | 75 } |
69 | 76 |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 // We should never return from the APPLY_OVERFLOW builtin. | 754 // We should never return from the APPLY_OVERFLOW builtin. |
748 if (__ emit_debug_code()) { | 755 if (__ emit_debug_code()) { |
749 __ Unreachable(); | 756 __ Unreachable(); |
750 } | 757 } |
751 | 758 |
752 __ Bind(&enough_stack_space); | 759 __ Bind(&enough_stack_space); |
753 } | 760 } |
754 | 761 |
755 | 762 |
756 // Input: | 763 // Input: |
757 // x0: code entry. | 764 // x0: new.target. |
758 // x1: function. | 765 // x1: function. |
759 // x2: receiver. | 766 // x2: receiver. |
760 // x3: argc. | 767 // x3: argc. |
761 // x4: argv. | 768 // x4: argv. |
762 // Output: | 769 // Output: |
763 // x0: result. | 770 // x0: result. |
764 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 771 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
765 bool is_construct) { | 772 bool is_construct) { |
766 // Called from JSEntryStub::GenerateBody(). | 773 // Called from JSEntryStub::GenerateBody(). |
| 774 Register new_target = x0; |
767 Register function = x1; | 775 Register function = x1; |
768 Register receiver = x2; | 776 Register receiver = x2; |
769 Register argc = x3; | 777 Register argc = x3; |
770 Register argv = x4; | 778 Register argv = x4; |
| 779 Register scratch = x10; |
771 | 780 |
772 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 781 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
773 | 782 |
774 // Clear the context before we push it when entering the internal frame. | 783 // Clear the context before we push it when entering the internal frame. |
775 __ Mov(cp, 0); | 784 __ Mov(cp, 0); |
776 | 785 |
777 { | 786 { |
778 // Enter an internal frame. | 787 // Enter an internal frame. |
779 FrameScope scope(masm, StackFrame::INTERNAL); | 788 FrameScope scope(masm, StackFrame::INTERNAL); |
780 | 789 |
781 // Set up the context from the function argument. | 790 // Setup the context (we need to use the caller context from the isolate). |
782 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 791 __ Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
| 792 masm->isolate()))); |
| 793 __ Ldr(cp, MemOperand(scratch)); |
783 | 794 |
784 __ InitializeRootRegister(); | 795 __ InitializeRootRegister(); |
785 | 796 |
786 // Push the function and the receiver onto the stack. | 797 // Push the function and the receiver onto the stack. |
787 __ Push(function, receiver); | 798 __ Push(function, receiver); |
788 | 799 |
789 // Check if we have enough stack space to push all arguments. | 800 // Check if we have enough stack space to push all arguments. |
790 // The function is the first thing that was pushed above after entering | 801 // The function is the first thing that was pushed above after entering |
791 // the internal frame. | 802 // the internal frame. |
792 const int kFunctionOffset = | 803 const int kFunctionOffset = |
793 InternalFrameConstants::kCodeOffset - kPointerSize; | 804 InternalFrameConstants::kCodeOffset - kPointerSize; |
794 // Expects argument count in eax. Clobbers ecx, edx, edi. | 805 // Expects argument count in eax. Clobbers ecx, edx, edi. |
795 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, | 806 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, |
796 kArgcIsUntaggedInt); | 807 kArgcIsUntaggedInt); |
797 | 808 |
798 // Copy arguments to the stack in a loop, in reverse order. | 809 // Copy arguments to the stack in a loop, in reverse order. |
799 // x3: argc. | 810 // x3: argc. |
800 // x4: argv. | 811 // x4: argv. |
801 Label loop, entry; | 812 Label loop, entry; |
802 // Compute the copy end address. | 813 // Compute the copy end address. |
803 __ Add(x10, argv, Operand(argc, LSL, kPointerSizeLog2)); | 814 __ Add(scratch, argv, Operand(argc, LSL, kPointerSizeLog2)); |
804 | 815 |
805 __ B(&entry); | 816 __ B(&entry); |
806 __ Bind(&loop); | 817 __ Bind(&loop); |
807 __ Ldr(x11, MemOperand(argv, kPointerSize, PostIndex)); | 818 __ Ldr(x11, MemOperand(argv, kPointerSize, PostIndex)); |
808 __ Ldr(x12, MemOperand(x11)); // Dereference the handle. | 819 __ Ldr(x12, MemOperand(x11)); // Dereference the handle. |
809 __ Push(x12); // Push the argument. | 820 __ Push(x12); // Push the argument. |
810 __ Bind(&entry); | 821 __ Bind(&entry); |
811 __ Cmp(x10, argv); | 822 __ Cmp(scratch, argv); |
812 __ B(ne, &loop); | 823 __ B(ne, &loop); |
813 | 824 |
| 825 __ Mov(scratch, argc); |
| 826 __ Mov(argc, new_target); |
| 827 __ Mov(new_target, scratch); |
| 828 // x0: argc. |
| 829 // x3: new.target. |
| 830 |
814 // Initialize all JavaScript callee-saved registers, since they will be seen | 831 // Initialize all JavaScript callee-saved registers, since they will be seen |
815 // by the garbage collector as part of handlers. | 832 // by the garbage collector as part of handlers. |
816 // The original values have been saved in JSEntryStub::GenerateBody(). | 833 // The original values have been saved in JSEntryStub::GenerateBody(). |
817 __ LoadRoot(x19, Heap::kUndefinedValueRootIndex); | 834 __ LoadRoot(x19, Heap::kUndefinedValueRootIndex); |
818 __ Mov(x20, x19); | 835 __ Mov(x20, x19); |
819 __ Mov(x21, x19); | 836 __ Mov(x21, x19); |
820 __ Mov(x22, x19); | 837 __ Mov(x22, x19); |
821 __ Mov(x23, x19); | 838 __ Mov(x23, x19); |
822 __ Mov(x24, x19); | 839 __ Mov(x24, x19); |
823 __ Mov(x25, x19); | 840 __ Mov(x25, x19); |
824 // Don't initialize the reserved registers. | 841 // Don't initialize the reserved registers. |
825 // x26 : root register (root). | 842 // x26 : root register (root). |
826 // x27 : context pointer (cp). | 843 // x27 : context pointer (cp). |
827 // x28 : JS stack pointer (jssp). | 844 // x28 : JS stack pointer (jssp). |
828 // x29 : frame pointer (fp). | 845 // x29 : frame pointer (fp). |
829 | 846 |
830 __ Mov(x0, argc); | 847 Handle<Code> builtin = is_construct |
831 if (is_construct) { | 848 ? masm->isolate()->builtins()->Construct() |
832 // No type feedback cell is available. | 849 : masm->isolate()->builtins()->Call(); |
833 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 850 __ Call(builtin, RelocInfo::CODE_TARGET); |
834 | 851 |
835 CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS); | |
836 __ CallStub(&stub); | |
837 } else { | |
838 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
839 } | |
840 // Exit the JS internal frame and remove the parameters (except function), | 852 // Exit the JS internal frame and remove the parameters (except function), |
841 // and return. | 853 // and return. |
842 } | 854 } |
843 | 855 |
844 // Result is in x0. Return. | 856 // Result is in x0. Return. |
845 __ Ret(); | 857 __ Ret(); |
846 } | 858 } |
847 | 859 |
848 | 860 |
849 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 861 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1672 __ Pop(x0); | 1684 __ Pop(x0); |
1673 __ SmiUntag(x0); | 1685 __ SmiUntag(x0); |
1674 } | 1686 } |
1675 // The delegate is always a regular function. | 1687 // The delegate is always a regular function. |
1676 __ AssertFunction(x1); | 1688 __ AssertFunction(x1); |
1677 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1689 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
1678 } | 1690 } |
1679 | 1691 |
1680 | 1692 |
1681 // static | 1693 // static |
| 1694 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 1695 // ----------- S t a t e ------------- |
| 1696 // -- x0 : the number of arguments (not including the receiver) |
| 1697 // -- x1 : the constructor to call (checked to be a JSFunction) |
| 1698 // -- x3 : the original constructor (checked to be a JSFunction) |
| 1699 // ----------------------------------- |
| 1700 __ AssertFunction(x1); |
| 1701 __ AssertFunction(x3); |
| 1702 |
| 1703 // Calling convention for function specific ConstructStubs require |
| 1704 // x2 to contain either an AllocationSite or undefined. |
| 1705 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
| 1706 |
| 1707 // Tail call to the function-specific construct stub (still in the caller |
| 1708 // context at this point). |
| 1709 __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 1710 __ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset)); |
| 1711 __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag); |
| 1712 __ Br(x4); |
| 1713 } |
| 1714 |
| 1715 |
| 1716 // static |
| 1717 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 1718 // ----------- S t a t e ------------- |
| 1719 // -- x0 : the number of arguments (not including the receiver) |
| 1720 // -- x1 : the constructor to call (can be any Object) |
| 1721 // -- x3 : the original constructor (either the same as the constructor or |
| 1722 // the JSFunction on which new was invoked initially) |
| 1723 // ----------------------------------- |
| 1724 |
| 1725 Label slow; |
| 1726 __ JumpIfSmi(x1, &slow); |
| 1727 __ CompareObjectType(x1, x5, x5, JS_FUNCTION_TYPE); |
| 1728 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
| 1729 RelocInfo::CODE_TARGET, eq); |
| 1730 __ Cmp(x5, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 1731 __ B(ne, &slow); |
| 1732 |
| 1733 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
| 1734 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kConstructTrapOffset)); |
| 1735 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1736 |
| 1737 __ Bind(&slow); |
| 1738 { |
| 1739 // Determine the delegate for the target (if any). |
| 1740 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1741 __ SmiTag(x0); |
| 1742 __ Push(x0, x1); |
| 1743 __ CallRuntime(Runtime::kGetConstructorDelegate, 1); |
| 1744 __ Mov(x1, x0); |
| 1745 __ Pop(x0); |
| 1746 __ SmiUntag(x0); |
| 1747 } |
| 1748 // The delegate is always a regular function. |
| 1749 __ AssertFunction(x1); |
| 1750 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
| 1751 } |
| 1752 |
| 1753 |
| 1754 // static |
1682 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { | 1755 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { |
1683 // ----------- S t a t e ------------- | 1756 // ----------- S t a t e ------------- |
1684 // -- x0 : the number of arguments (not including the receiver) | 1757 // -- x0 : the number of arguments (not including the receiver) |
1685 // -- x2 : the address of the first argument to be pushed. Subsequent | 1758 // -- x2 : the address of the first argument to be pushed. Subsequent |
1686 // arguments should be consecutive above this, in the same order as | 1759 // arguments should be consecutive above this, in the same order as |
1687 // they are to be pushed onto the stack. | 1760 // they are to be pushed onto the stack. |
1688 // -- x1 : the target to call (can be any Object). | 1761 // -- x1 : the target to call (can be any Object). |
1689 | 1762 |
1690 // Find the address of the last argument. | 1763 // Find the address of the last argument. |
1691 __ add(x3, x0, Operand(1)); // Add one for receiver. | 1764 __ add(x3, x0, Operand(1)); // Add one for receiver. |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1878 } | 1951 } |
1879 } | 1952 } |
1880 | 1953 |
1881 | 1954 |
1882 #undef __ | 1955 #undef __ |
1883 | 1956 |
1884 } // namespace internal | 1957 } // namespace internal |
1885 } // namespace v8 | 1958 } // namespace v8 |
1886 | 1959 |
1887 #endif // V8_TARGET_ARCH_ARM | 1960 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |