OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.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" |
11 #include "src/runtime/runtime.h" | 11 #include "src/runtime/runtime.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | 16 |
17 #define __ ACCESS_MASM(masm) | 17 #define __ ACCESS_MASM(masm) |
18 | 18 |
19 | 19 |
20 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, | 20 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id, |
21 BuiltinExtraArguments extra_args) { | 21 BuiltinExtraArguments extra_args) { |
22 // ----------- S t a t e ------------- | 22 // ----------- S t a t e ------------- |
23 // -- r3 : number of arguments excluding receiver | 23 // -- r3 : number of arguments excluding receiver |
24 // -- r4 : called function (only guaranteed when | 24 // -- r4 : called function (only guaranteed when |
25 // extra_args requires it) | 25 // extra_args requires it) |
26 // -- cp : context | |
27 // -- sp[0] : last argument | 26 // -- sp[0] : last argument |
28 // -- ... | 27 // -- ... |
29 // -- sp[4 * (argc - 1)] : first argument (argc == r0) | 28 // -- sp[4 * (argc - 1)] : first argument (argc == r0) |
30 // -- sp[4 * argc] : receiver | 29 // -- sp[4 * argc] : receiver |
31 // ----------------------------------- | 30 // ----------------------------------- |
| 31 __ AssertFunction(r4); |
| 32 |
| 33 // Make sure we operate in the context of the called function (for example |
| 34 // ConstructStubs implemented in C++ will be run in the context of the caller |
| 35 // instead of the callee, due to the way that [[Construct]] is defined for |
| 36 // ordinary functions). |
| 37 // TODO(bmeurer): Can we make this more robust? |
| 38 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
32 | 39 |
33 // Insert extra arguments. | 40 // Insert extra arguments. |
34 int num_extra_args = 0; | 41 int num_extra_args = 0; |
35 if (extra_args == NEEDS_CALLED_FUNCTION) { | 42 if (extra_args == NEEDS_CALLED_FUNCTION) { |
36 num_extra_args = 1; | 43 num_extra_args = 1; |
37 __ push(r4); | 44 __ push(r4); |
38 } else { | 45 } else { |
39 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); | 46 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); |
40 } | 47 } |
41 | 48 |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 __ Push(r4, argc); | 725 __ Push(r4, argc); |
719 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 726 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
720 | 727 |
721 __ bind(&okay); | 728 __ bind(&okay); |
722 } | 729 } |
723 | 730 |
724 | 731 |
725 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 732 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
726 bool is_construct) { | 733 bool is_construct) { |
727 // Called from Generate_JS_Entry | 734 // Called from Generate_JS_Entry |
728 // r3: code entry | 735 // r3: new.target |
729 // r4: function | 736 // r4: function |
730 // r5: receiver | 737 // r5: receiver |
731 // r6: argc | 738 // r6: argc |
732 // r7: argv | 739 // r7: argv |
733 // r0,r8-r9, cp may be clobbered | 740 // r0,r8-r9, cp may be clobbered |
734 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 741 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
735 | 742 |
736 // Clear the context before we push it when entering the internal frame. | 743 // Clear the context before we push it when entering the internal frame. |
737 __ li(cp, Operand::Zero()); | 744 __ li(cp, Operand::Zero()); |
738 | 745 |
739 // Enter an internal frame. | 746 // Enter an internal frame. |
740 { | 747 { |
741 FrameScope scope(masm, StackFrame::INTERNAL); | 748 FrameScope scope(masm, StackFrame::INTERNAL); |
742 | 749 |
743 // Set up the context from the function argument. | 750 // Setup the context (we need to use the caller context from the isolate). |
744 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); | 751 ExternalReference context_address(Isolate::kContextAddress, |
| 752 masm->isolate()); |
| 753 __ mov(cp, Operand(context_address)); |
| 754 __ LoadP(cp, MemOperand(cp)); |
745 | 755 |
746 __ InitializeRootRegister(); | 756 __ InitializeRootRegister(); |
747 | 757 |
748 // Push the function and the receiver onto the stack. | 758 // Push the function and the receiver onto the stack. |
749 __ push(r4); | 759 __ Push(r4, r5); |
750 __ push(r5); | |
751 | 760 |
752 // Check if we have enough stack space to push all arguments. | 761 // Check if we have enough stack space to push all arguments. |
753 // The function is the first thing that was pushed above after entering | 762 // The function is the first thing that was pushed above after entering |
754 // the internal frame. | 763 // the internal frame. |
755 const int kFunctionOffset = | 764 const int kFunctionOffset = |
756 InternalFrameConstants::kCodeOffset - kPointerSize; | 765 InternalFrameConstants::kCodeOffset - kPointerSize; |
757 // Clobbers r5. | 766 // Clobbers r5. |
758 Generate_CheckStackOverflow(masm, kFunctionOffset, r6, kArgcIsUntaggedInt); | 767 Generate_CheckStackOverflow(masm, kFunctionOffset, r6, kArgcIsUntaggedInt); |
759 | 768 |
760 // Copy arguments to the stack in a loop. | 769 // Copy arguments to the stack in a loop. |
761 // r4: function | 770 // r4: function |
762 // r6: argc | 771 // r6: argc |
763 // r7: argv, i.e. points to first arg | 772 // r7: argv, i.e. points to first arg |
764 Label loop, entry; | 773 Label loop, entry; |
765 __ ShiftLeftImm(r0, r6, Operand(kPointerSizeLog2)); | 774 __ ShiftLeftImm(r0, r6, Operand(kPointerSizeLog2)); |
766 __ add(r5, r7, r0); | 775 __ add(r5, r7, r0); |
767 // r5 points past last arg. | 776 // r5 points past last arg. |
768 __ b(&entry); | 777 __ b(&entry); |
769 __ bind(&loop); | 778 __ bind(&loop); |
770 __ LoadP(r8, MemOperand(r7)); // read next parameter | 779 __ LoadP(r8, MemOperand(r7)); // read next parameter |
771 __ addi(r7, r7, Operand(kPointerSize)); | 780 __ addi(r7, r7, Operand(kPointerSize)); |
772 __ LoadP(r0, MemOperand(r8)); // dereference handle | 781 __ LoadP(r0, MemOperand(r8)); // dereference handle |
773 __ push(r0); // push parameter | 782 __ push(r0); // push parameter |
774 __ bind(&entry); | 783 __ bind(&entry); |
775 __ cmp(r7, r5); | 784 __ cmp(r7, r5); |
776 __ bne(&loop); | 785 __ bne(&loop); |
777 | 786 |
| 787 // Setup new.target and argc. |
| 788 __ mr(r7, r3); |
| 789 __ mr(r3, r6); |
| 790 __ mr(r6, r7); |
| 791 |
778 // Initialize all JavaScript callee-saved registers, since they will be seen | 792 // Initialize all JavaScript callee-saved registers, since they will be seen |
779 // by the garbage collector as part of handlers. | 793 // by the garbage collector as part of handlers. |
780 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); | 794 __ LoadRoot(r7, Heap::kUndefinedValueRootIndex); |
781 __ mr(r14, r7); | 795 __ mr(r14, r7); |
782 __ mr(r15, r7); | 796 __ mr(r15, r7); |
783 __ mr(r16, r7); | 797 __ mr(r16, r7); |
784 __ mr(r17, r7); | 798 __ mr(r17, r7); |
785 | 799 |
786 // Invoke the code and pass argc as r3. | 800 // Invoke the code. |
787 __ mr(r3, r6); | 801 Handle<Code> builtin = is_construct |
788 if (is_construct) { | 802 ? masm->isolate()->builtins()->Construct() |
789 // No type feedback cell is available | 803 : masm->isolate()->builtins()->Call(); |
790 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 804 __ Call(builtin, RelocInfo::CODE_TARGET); |
791 CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS); | 805 |
792 __ CallStub(&stub); | |
793 } else { | |
794 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
795 } | |
796 // Exit the JS frame and remove the parameters (except function), and | 806 // Exit the JS frame and remove the parameters (except function), and |
797 // return. | 807 // return. |
798 } | 808 } |
799 __ blr(); | 809 __ blr(); |
800 | 810 |
801 // r3: result | 811 // r3: result |
802 } | 812 } |
803 | 813 |
804 | 814 |
805 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 815 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 __ Pop(r3); | 1642 __ Pop(r3); |
1633 __ SmiUntag(r3); | 1643 __ SmiUntag(r3); |
1634 } | 1644 } |
1635 // The delegate is always a regular function. | 1645 // The delegate is always a regular function. |
1636 __ AssertFunction(r4); | 1646 __ AssertFunction(r4); |
1637 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1647 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
1638 } | 1648 } |
1639 | 1649 |
1640 | 1650 |
1641 // static | 1651 // static |
| 1652 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 1653 // ----------- S t a t e ------------- |
| 1654 // -- r3 : the number of arguments (not including the receiver) |
| 1655 // -- r4 : the constructor to call (checked to be a JSFunction) |
| 1656 // -- r6 : the original constructor (checked to be a JSFunction) |
| 1657 // ----------------------------------- |
| 1658 __ AssertFunction(r4); |
| 1659 __ AssertFunction(r6); |
| 1660 |
| 1661 // Calling convention for function specific ConstructStubs require |
| 1662 // r5 to contain either an AllocationSite or undefined. |
| 1663 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
| 1664 |
| 1665 // Tail call to the function-specific construct stub (still in the caller |
| 1666 // context at this point). |
| 1667 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 1668 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset)); |
| 1669 __ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1670 __ JumpToJSEntry(ip); |
| 1671 } |
| 1672 |
| 1673 |
| 1674 // static |
| 1675 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 1676 // ----------- S t a t e ------------- |
| 1677 // -- r3 : the number of arguments (not including the receiver) |
| 1678 // -- r4 : the constructor to call (can be any Object) |
| 1679 // -- r6 : the original constructor (either the same as the constructor or |
| 1680 // the JSFunction on which new was invoked initially) |
| 1681 // ----------------------------------- |
| 1682 |
| 1683 Label slow; |
| 1684 __ JumpIfSmi(r4, &slow); |
| 1685 __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE); |
| 1686 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
| 1687 RelocInfo::CODE_TARGET, eq); |
| 1688 __ cmpi(r8, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 1689 __ bne(&slow); |
| 1690 |
| 1691 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
| 1692 __ LoadP(r4, FieldMemOperand(r4, JSFunctionProxy::kConstructTrapOffset)); |
| 1693 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1694 |
| 1695 __ bind(&slow); |
| 1696 { |
| 1697 // Determine the delegate for the target (if any). |
| 1698 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 1699 __ SmiTag(r3); |
| 1700 __ Push(r3, r4); |
| 1701 __ CallRuntime(Runtime::kGetConstructorDelegate, 1); |
| 1702 __ mr(r4, r3); |
| 1703 __ Pop(r3); |
| 1704 __ SmiUntag(r3); |
| 1705 } |
| 1706 // The delegate is always a regular function. |
| 1707 __ AssertFunction(r4); |
| 1708 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
| 1709 } |
| 1710 |
| 1711 |
| 1712 // static |
1642 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { | 1713 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { |
1643 // ----------- S t a t e ------------- | 1714 // ----------- S t a t e ------------- |
1644 // -- r3 : the number of arguments (not including the receiver) | 1715 // -- r3 : the number of arguments (not including the receiver) |
1645 // -- r5 : the address of the first argument to be pushed. Subsequent | 1716 // -- r5 : the address of the first argument to be pushed. Subsequent |
1646 // arguments should be consecutive above this, in the same order as | 1717 // arguments should be consecutive above this, in the same order as |
1647 // they are to be pushed onto the stack. | 1718 // they are to be pushed onto the stack. |
1648 // -- r4 : the target to call (can be any Object). | 1719 // -- r4 : the target to call (can be any Object). |
1649 | 1720 |
1650 // Calculate number of arguments (add one for receiver). | 1721 // Calculate number of arguments (add one for receiver). |
1651 __ addi(r6, r3, Operand(1)); | 1722 __ addi(r6, r3, Operand(1)); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 __ bkpt(0); | 1892 __ bkpt(0); |
1822 } | 1893 } |
1823 } | 1894 } |
1824 | 1895 |
1825 | 1896 |
1826 #undef __ | 1897 #undef __ |
1827 } // namespace internal | 1898 } // namespace internal |
1828 } // namespace v8 | 1899 } // namespace v8 |
1829 | 1900 |
1830 #endif // V8_TARGET_ARCH_PPC | 1901 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |