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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
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, | 20 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
21 CFunctionId id, | 21 CFunctionId id, |
22 BuiltinExtraArguments extra_args) { | 22 BuiltinExtraArguments extra_args) { |
23 // ----------- S t a t e ------------- | 23 // ----------- S t a t e ------------- |
24 // -- a0 : number of arguments excluding receiver | 24 // -- a0 : number of arguments excluding receiver |
25 // -- a1 : called function (only guaranteed when | 25 // -- a1 : called function (only guaranteed when |
26 // -- extra_args requires it) | 26 // -- extra_args requires it) |
27 // -- cp : context | |
28 // -- sp[0] : last argument | 27 // -- sp[0] : last argument |
29 // -- ... | 28 // -- ... |
30 // -- sp[8 * (argc - 1)] : first argument | 29 // -- sp[8 * (argc - 1)] : first argument |
31 // -- sp[8 * agrc] : receiver | 30 // -- sp[8 * agrc] : receiver |
32 // ----------------------------------- | 31 // ----------------------------------- |
| 32 __ AssertFunction(a1); |
| 33 |
| 34 // Make sure we operate in the context of the called function (for example |
| 35 // ConstructStubs implemented in C++ will be run in the context of the caller |
| 36 // instead of the callee, due to the way that [[Construct]] is defined for |
| 37 // ordinary functions). |
| 38 // TODO(bmeurer): Can we make this more robust? |
| 39 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
33 | 40 |
34 // Insert extra arguments. | 41 // Insert extra arguments. |
35 int num_extra_args = 0; | 42 int num_extra_args = 0; |
36 if (extra_args == NEEDS_CALLED_FUNCTION) { | 43 if (extra_args == NEEDS_CALLED_FUNCTION) { |
37 num_extra_args = 1; | 44 num_extra_args = 1; |
38 __ push(a1); | 45 __ push(a1); |
39 } else { | 46 } else { |
40 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); | 47 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); |
41 } | 48 } |
42 | 49 |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 | 730 |
724 __ bind(&okay); | 731 __ bind(&okay); |
725 } | 732 } |
726 | 733 |
727 | 734 |
728 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 735 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
729 bool is_construct) { | 736 bool is_construct) { |
730 // Called from JSEntryStub::GenerateBody | 737 // Called from JSEntryStub::GenerateBody |
731 | 738 |
732 // ----------- S t a t e ------------- | 739 // ----------- S t a t e ------------- |
733 // -- a0: code entry | 740 // -- a0: new.target |
734 // -- a1: function | 741 // -- a1: function |
735 // -- a2: receiver_pointer | 742 // -- a2: receiver_pointer |
736 // -- a3: argc | 743 // -- a3: argc |
737 // -- s0: argv | 744 // -- s0: argv |
738 // ----------------------------------- | 745 // ----------------------------------- |
739 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 746 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
740 // Clear the context before we push it when entering the JS frame. | 747 // Clear the context before we push it when entering the JS frame. |
741 __ mov(cp, zero_reg); | 748 __ mov(cp, zero_reg); |
742 | 749 |
743 // Enter an internal frame. | 750 // Enter an internal frame. |
744 { | 751 { |
745 FrameScope scope(masm, StackFrame::INTERNAL); | 752 FrameScope scope(masm, StackFrame::INTERNAL); |
746 | 753 |
747 // Set up the context from the function argument. | 754 // Setup the context (we need to use the caller context from the isolate). |
748 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 755 ExternalReference context_address(Isolate::kContextAddress, |
| 756 masm->isolate()); |
| 757 __ li(cp, Operand(context_address)); |
| 758 __ ld(cp, MemOperand(cp)); |
749 | 759 |
750 // Push the function and the receiver onto the stack. | 760 // Push the function and the receiver onto the stack. |
751 __ Push(a1, a2); | 761 __ Push(a1, a2); |
752 | 762 |
753 // Check if we have enough stack space to push all arguments. | 763 // Check if we have enough stack space to push all arguments. |
754 // The function is the first thing that was pushed above after entering | 764 // The function is the first thing that was pushed above after entering |
755 // the internal frame. | 765 // the internal frame. |
756 const int kFunctionOffset = | 766 const int kFunctionOffset = |
757 InternalFrameConstants::kCodeOffset - kPointerSize; | 767 InternalFrameConstants::kCodeOffset - kPointerSize; |
758 // Clobbers a2. | 768 // Clobbers a2. |
759 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); | 769 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); |
760 | 770 |
| 771 // Remember new.target. |
| 772 __ mov(a5, a0); |
| 773 |
761 // Copy arguments to the stack in a loop. | 774 // Copy arguments to the stack in a loop. |
762 // a3: argc | 775 // a3: argc |
763 // s0: argv, i.e. points to first arg | 776 // s0: argv, i.e. points to first arg |
764 Label loop, entry; | 777 Label loop, entry; |
765 __ dsll(a4, a3, kPointerSizeLog2); | 778 __ dsll(a4, a3, kPointerSizeLog2); |
766 __ daddu(a6, s0, a4); | 779 __ daddu(a6, s0, a4); |
767 __ b(&entry); | 780 __ b(&entry); |
768 __ nop(); // Branch delay slot nop. | 781 __ nop(); // Branch delay slot nop. |
769 // a6 points past last arg. | 782 // a6 points past last arg. |
770 __ bind(&loop); | 783 __ bind(&loop); |
771 __ ld(a4, MemOperand(s0)); // Read next parameter. | 784 __ ld(a4, MemOperand(s0)); // Read next parameter. |
772 __ daddiu(s0, s0, kPointerSize); | 785 __ daddiu(s0, s0, kPointerSize); |
773 __ ld(a4, MemOperand(a4)); // Dereference handle. | 786 __ ld(a4, MemOperand(a4)); // Dereference handle. |
774 __ push(a4); // Push parameter. | 787 __ push(a4); // Push parameter. |
775 __ bind(&entry); | 788 __ bind(&entry); |
776 __ Branch(&loop, ne, s0, Operand(a6)); | 789 __ Branch(&loop, ne, s0, Operand(a6)); |
777 | 790 |
| 791 // Setup new.target and argc. |
| 792 __ mov(a0, a3); |
| 793 __ mov(a3, a5); |
| 794 |
778 // Initialize all JavaScript callee-saved registers, since they will be seen | 795 // Initialize all JavaScript callee-saved registers, since they will be seen |
779 // by the garbage collector as part of handlers. | 796 // by the garbage collector as part of handlers. |
780 __ LoadRoot(a4, Heap::kUndefinedValueRootIndex); | 797 __ LoadRoot(a4, Heap::kUndefinedValueRootIndex); |
781 __ mov(s1, a4); | 798 __ mov(s1, a4); |
782 __ mov(s2, a4); | 799 __ mov(s2, a4); |
783 __ mov(s3, a4); | 800 __ mov(s3, a4); |
784 __ mov(s4, a4); | 801 __ mov(s4, a4); |
785 __ mov(s5, a4); | 802 __ mov(s5, a4); |
786 // s6 holds the root address. Do not clobber. | 803 // s6 holds the root address. Do not clobber. |
787 // s7 is cp. Do not init. | 804 // s7 is cp. Do not init. |
788 | 805 |
789 // Invoke the code and pass argc as a0. | 806 // Invoke the code. |
790 __ mov(a0, a3); | 807 Handle<Code> builtin = is_construct |
791 if (is_construct) { | 808 ? masm->isolate()->builtins()->Construct() |
792 // No type feedback cell is available | 809 : masm->isolate()->builtins()->Call(); |
793 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 810 __ Call(builtin, RelocInfo::CODE_TARGET); |
794 CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS); | |
795 __ CallStub(&stub); | |
796 } else { | |
797 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | |
798 } | |
799 | 811 |
800 // Leave internal frame. | 812 // Leave internal frame. |
801 } | 813 } |
802 __ Jump(ra); | 814 __ Jump(ra); |
803 } | 815 } |
804 | 816 |
805 | 817 |
806 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 818 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
807 Generate_JSEntryTrampolineHelper(masm, false); | 819 Generate_JSEntryTrampolineHelper(masm, false); |
808 } | 820 } |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1617 __ mov(a1, v0); | 1629 __ mov(a1, v0); |
1618 __ Pop(a0); | 1630 __ Pop(a0); |
1619 __ SmiUntag(a0); | 1631 __ SmiUntag(a0); |
1620 } | 1632 } |
1621 // The delegate is always a regular function. | 1633 // The delegate is always a regular function. |
1622 __ AssertFunction(a1); | 1634 __ AssertFunction(a1); |
1623 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); | 1635 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
1624 } | 1636 } |
1625 | 1637 |
1626 | 1638 |
| 1639 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 1640 // ----------- S t a t e ------------- |
| 1641 // -- a0 : the number of arguments (not including the receiver) |
| 1642 // -- a1 : the constructor to call (checked to be a JSFunction) |
| 1643 // -- a3 : the original constructor (checked to be a JSFunction) |
| 1644 // ----------------------------------- |
| 1645 __ AssertFunction(a1); |
| 1646 __ AssertFunction(a3); |
| 1647 |
| 1648 // Calling convention for function specific ConstructStubs require |
| 1649 // a2 to contain either an AllocationSite or undefined. |
| 1650 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
| 1651 |
| 1652 // Tail call to the function-specific construct stub (still in the caller |
| 1653 // context at this point). |
| 1654 __ ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 1655 __ ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset)); |
| 1656 __ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 1657 __ Jump(at); |
| 1658 } |
| 1659 |
| 1660 |
| 1661 // static |
| 1662 void Builtins::Generate_Construct(MacroAssembler* masm) { |
| 1663 // ----------- S t a t e ------------- |
| 1664 // -- a0 : the number of arguments (not including the receiver) |
| 1665 // -- a1 : the constructor to call (can be any Object) |
| 1666 // -- a3 : the original constructor (either the same as the constructor or |
| 1667 // the JSFunction on which new was invoked initially) |
| 1668 // ----------------------------------- |
| 1669 |
| 1670 Label slow; |
| 1671 __ JumpIfSmi(a1, &slow); |
| 1672 __ GetObjectType(a1, a5, a5); |
| 1673 __ Jump(masm->isolate()->builtins()->ConstructFunction(), |
| 1674 RelocInfo::CODE_TARGET, eq, a5, Operand(JS_FUNCTION_TYPE)); |
| 1675 __ Branch(&slow, ne, a5, Operand(JS_FUNCTION_PROXY_TYPE)); |
| 1676 |
| 1677 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies. |
| 1678 __ ld(a1, FieldMemOperand(a1, JSFunctionProxy::kConstructTrapOffset)); |
| 1679 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1680 |
| 1681 __ bind(&slow); |
| 1682 { |
| 1683 // Determine the delegate for the target (if any). |
| 1684 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1685 __ SmiTag(a0); |
| 1686 __ Push(a0, a1); |
| 1687 __ CallRuntime(Runtime::kGetConstructorDelegate, 1); |
| 1688 __ mov(a1, v0); |
| 1689 __ Pop(a0); |
| 1690 __ SmiUntag(a0); |
| 1691 } |
| 1692 // The delegate is always a regular function. |
| 1693 __ AssertFunction(a1); |
| 1694 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); |
| 1695 } |
| 1696 |
| 1697 |
1627 // static | 1698 // static |
1628 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { | 1699 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { |
1629 // ----------- S t a t e ------------- | 1700 // ----------- S t a t e ------------- |
1630 // -- a0 : the number of arguments (not including the receiver) | 1701 // -- a0 : the number of arguments (not including the receiver) |
1631 // -- a2 : the address of the first argument to be pushed. Subsequent | 1702 // -- a2 : the address of the first argument to be pushed. Subsequent |
1632 // arguments should be consecutive above this, in the same order as | 1703 // arguments should be consecutive above this, in the same order as |
1633 // they are to be pushed onto the stack. | 1704 // they are to be pushed onto the stack. |
1634 // -- a1 : the target to call (can be any Object). | 1705 // -- a1 : the target to call (can be any Object). |
1635 | 1706 |
1636 // Find the address of the last argument. | 1707 // Find the address of the last argument. |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 } | 1876 } |
1806 } | 1877 } |
1807 | 1878 |
1808 | 1879 |
1809 #undef __ | 1880 #undef __ |
1810 | 1881 |
1811 } // namespace internal | 1882 } // namespace internal |
1812 } // namespace v8 | 1883 } // namespace v8 |
1813 | 1884 |
1814 #endif // V8_TARGET_ARCH_MIPS64 | 1885 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |