Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Side by Side Diff: src/mips/builtins-mips.cc

Issue 1359583002: [builtins] Add support for NewTarget to Execution::New. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Merge mips and mips64 ports. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/frames-ia32.h ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 17
18 #define __ ACCESS_MASM(masm) 18 #define __ ACCESS_MASM(masm)
19 19
20 20
21 void Builtins::Generate_Adaptor(MacroAssembler* masm, 21 void Builtins::Generate_Adaptor(MacroAssembler* masm,
22 CFunctionId id, 22 CFunctionId id,
23 BuiltinExtraArguments extra_args) { 23 BuiltinExtraArguments extra_args) {
24 // ----------- S t a t e ------------- 24 // ----------- S t a t e -------------
25 // -- a0 : number of arguments excluding receiver 25 // -- a0 : number of arguments excluding receiver
26 // -- a1 : called function (only guaranteed when 26 // -- a1 : called function (only guaranteed when
27 // -- extra_args requires it) 27 // -- extra_args requires it)
28 // -- cp : context
29 // -- sp[0] : last argument 28 // -- sp[0] : last argument
30 // -- ... 29 // -- ...
31 // -- sp[4 * (argc - 1)] : first argument 30 // -- sp[4 * (argc - 1)] : first argument
32 // -- sp[4 * agrc] : receiver 31 // -- sp[4 * agrc] : receiver
33 // ----------------------------------- 32 // -----------------------------------
33 __ AssertFunction(a1);
34
35 // Make sure we operate in the context of the called function (for example
36 // ConstructStubs implemented in C++ will be run in the context of the caller
37 // instead of the callee, due to the way that [[Construct]] is defined for
38 // ordinary functions).
39 // TODO(bmeurer): Can we make this more robust?
40 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
34 41
35 // Insert extra arguments. 42 // Insert extra arguments.
36 int num_extra_args = 0; 43 int num_extra_args = 0;
37 if (extra_args == NEEDS_CALLED_FUNCTION) { 44 if (extra_args == NEEDS_CALLED_FUNCTION) {
38 num_extra_args = 1; 45 num_extra_args = 1;
39 __ push(a1); 46 __ push(a1);
40 } else { 47 } else {
41 DCHECK(extra_args == NO_EXTRA_ARGUMENTS); 48 DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
42 } 49 }
43 50
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 731
725 __ bind(&okay); 732 __ bind(&okay);
726 } 733 }
727 734
728 735
729 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 736 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
730 bool is_construct) { 737 bool is_construct) {
731 // Called from JSEntryStub::GenerateBody 738 // Called from JSEntryStub::GenerateBody
732 739
733 // ----------- S t a t e ------------- 740 // ----------- S t a t e -------------
734 // -- a0: code entry 741 // -- a0: new.target
735 // -- a1: function 742 // -- a1: function
736 // -- a2: receiver_pointer 743 // -- a2: receiver_pointer
737 // -- a3: argc 744 // -- a3: argc
738 // -- s0: argv 745 // -- s0: argv
739 // ----------------------------------- 746 // -----------------------------------
740 ProfileEntryHookStub::MaybeCallEntryHook(masm); 747 ProfileEntryHookStub::MaybeCallEntryHook(masm);
741 748
742 // Clear the context before we push it when entering the JS frame. 749 // Clear the context before we push it when entering the JS frame.
743 __ mov(cp, zero_reg); 750 __ mov(cp, zero_reg);
744 751
745 // Enter an internal frame. 752 // Enter an internal frame.
746 { 753 {
747 FrameScope scope(masm, StackFrame::INTERNAL); 754 FrameScope scope(masm, StackFrame::INTERNAL);
748 755
749 // Set up the context from the function argument. 756 // Setup the context (we need to use the caller context from the isolate).
750 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 757 ExternalReference context_address(Isolate::kContextAddress,
758 masm->isolate());
759 __ li(cp, Operand(context_address));
760 __ lw(cp, MemOperand(cp));
751 761
752 // Push the function and the receiver onto the stack. 762 // Push the function and the receiver onto the stack.
753 __ Push(a1, a2); 763 __ Push(a1, a2);
754 764
755 // Check if we have enough stack space to push all arguments. 765 // Check if we have enough stack space to push all arguments.
756 // The function is the first thing that was pushed above after entering 766 // The function is the first thing that was pushed above after entering
757 // the internal frame. 767 // the internal frame.
758 const int kFunctionOffset = 768 const int kFunctionOffset =
759 InternalFrameConstants::kCodeOffset - kPointerSize; 769 InternalFrameConstants::kCodeOffset - kPointerSize;
760 // Clobbers a2. 770 // Clobbers a2.
761 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); 771 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt);
762 772
773 // Remember new.target.
774 __ mov(t1, a0);
775
763 // Copy arguments to the stack in a loop. 776 // Copy arguments to the stack in a loop.
764 // a3: argc 777 // a3: argc
765 // s0: argv, i.e. points to first arg 778 // s0: argv, i.e. points to first arg
766 Label loop, entry; 779 Label loop, entry;
767 __ sll(t0, a3, kPointerSizeLog2); 780 __ sll(t0, a3, kPointerSizeLog2);
768 __ addu(t2, s0, t0); 781 __ addu(t2, s0, t0);
769 __ b(&entry); 782 __ b(&entry);
770 __ nop(); // Branch delay slot nop. 783 __ nop(); // Branch delay slot nop.
771 // t2 points past last arg. 784 // t2 points past last arg.
772 __ bind(&loop); 785 __ bind(&loop);
773 __ lw(t0, MemOperand(s0)); // Read next parameter. 786 __ lw(t0, MemOperand(s0)); // Read next parameter.
774 __ addiu(s0, s0, kPointerSize); 787 __ addiu(s0, s0, kPointerSize);
775 __ lw(t0, MemOperand(t0)); // Dereference handle. 788 __ lw(t0, MemOperand(t0)); // Dereference handle.
776 __ push(t0); // Push parameter. 789 __ push(t0); // Push parameter.
777 __ bind(&entry); 790 __ bind(&entry);
778 __ Branch(&loop, ne, s0, Operand(t2)); 791 __ Branch(&loop, ne, s0, Operand(t2));
779 792
793 // Setup new.target and argc.
794 __ mov(a0, a3);
795 __ mov(a3, t1);
796
780 // Initialize all JavaScript callee-saved registers, since they will be seen 797 // Initialize all JavaScript callee-saved registers, since they will be seen
781 // by the garbage collector as part of handlers. 798 // by the garbage collector as part of handlers.
782 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); 799 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
783 __ mov(s1, t0); 800 __ mov(s1, t0);
784 __ mov(s2, t0); 801 __ mov(s2, t0);
785 __ mov(s3, t0); 802 __ mov(s3, t0);
786 __ mov(s4, t0); 803 __ mov(s4, t0);
787 __ mov(s5, t0); 804 __ mov(s5, t0);
788 // s6 holds the root address. Do not clobber. 805 // s6 holds the root address. Do not clobber.
789 // s7 is cp. Do not init. 806 // s7 is cp. Do not init.
790 807
791 // Invoke the code and pass argc as a0. 808 // Invoke the code.
792 __ mov(a0, a3); 809 Handle<Code> builtin = is_construct
793 if (is_construct) { 810 ? masm->isolate()->builtins()->Construct()
794 // No type feedback cell is available 811 : masm->isolate()->builtins()->Call();
795 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 812 __ Call(builtin, RelocInfo::CODE_TARGET);
796 CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
797 __ CallStub(&stub);
798 } else {
799 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
800 }
801 813
802 // Leave internal frame. 814 // Leave internal frame.
803 } 815 }
804 816
805 __ Jump(ra); 817 __ Jump(ra);
806 } 818 }
807 819
808 820
809 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { 821 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
810 Generate_JSEntryTrampolineHelper(masm, false); 822 Generate_JSEntryTrampolineHelper(masm, false);
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
1622 __ Pop(a0); 1634 __ Pop(a0);
1623 __ sra(a0, a0, kSmiTagSize); // Un-tag. 1635 __ sra(a0, a0, kSmiTagSize); // Un-tag.
1624 } 1636 }
1625 // The delegate is always a regular function. 1637 // The delegate is always a regular function.
1626 __ AssertFunction(a1); 1638 __ AssertFunction(a1);
1627 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1639 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1628 } 1640 }
1629 1641
1630 1642
1631 // static 1643 // static
1644 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
1645 // ----------- S t a t e -------------
1646 // -- a0 : the number of arguments (not including the receiver)
1647 // -- a1 : the constructor to call (checked to be a JSFunction)
1648 // -- a3 : the original constructor (checked to be a JSFunction)
1649 // -----------------------------------
1650 __ AssertFunction(a1);
1651 __ AssertFunction(a3);
1652
1653 // Calling convention for function specific ConstructStubs require
1654 // a2 to contain either an AllocationSite or undefined.
1655 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1656
1657 // Tail call to the function-specific construct stub (still in the caller
1658 // context at this point).
1659 __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1660 __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
1661 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
1662 __ Jump(at);
1663 }
1664
1665
1666 // static
1667 void Builtins::Generate_Construct(MacroAssembler* masm) {
1668 // ----------- S t a t e -------------
1669 // -- a0 : the number of arguments (not including the receiver)
1670 // -- a1 : the constructor to call (can be any Object)
1671 // -- a3 : the original constructor (either the same as the constructor or
1672 // the JSFunction on which new was invoked initially)
1673 // -----------------------------------
1674
1675 Label slow;
1676 __ JumpIfSmi(a1, &slow);
1677 __ GetObjectType(a1, t1, t1);
1678 __ Jump(masm->isolate()->builtins()->ConstructFunction(),
1679 RelocInfo::CODE_TARGET, eq, t1, Operand(JS_FUNCTION_TYPE));
1680 __ Branch(&slow, ne, t1, Operand(JS_FUNCTION_PROXY_TYPE));
1681
1682 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
1683 __ lw(a1, FieldMemOperand(a1, JSFunctionProxy::kConstructTrapOffset));
1684 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1685
1686 __ bind(&slow);
1687 {
1688 // Determine the delegate for the target (if any).
1689 FrameScope scope(masm, StackFrame::INTERNAL);
1690 __ SmiTag(a0);
1691 __ Push(a0, a1);
1692 __ CallRuntime(Runtime::kGetConstructorDelegate, 1);
1693 __ mov(a1, v0);
1694 __ Pop(a0);
1695 __ SmiUntag(a0);
1696 }
1697 // The delegate is always a regular function.
1698 __ AssertFunction(a1);
1699 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1700 }
1701
1702
1703 // static
1632 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { 1704 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) {
1633 // ----------- S t a t e ------------- 1705 // ----------- S t a t e -------------
1634 // -- a0 : the number of arguments (not including the receiver) 1706 // -- a0 : the number of arguments (not including the receiver)
1635 // -- a2 : the address of the first argument to be pushed. Subsequent 1707 // -- a2 : the address of the first argument to be pushed. Subsequent
1636 // arguments should be consecutive above this, in the same order as 1708 // arguments should be consecutive above this, in the same order as
1637 // they are to be pushed onto the stack. 1709 // they are to be pushed onto the stack.
1638 // -- a1 : the target to call (can be any Object). 1710 // -- a1 : the target to call (can be any Object).
1639 1711
1640 // Find the address of the last argument. 1712 // Find the address of the last argument.
1641 __ Addu(a3, a0, Operand(1)); // Add one for receiver. 1713 __ Addu(a3, a0, Operand(1)); // Add one for receiver.
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 } 1881 }
1810 } 1882 }
1811 1883
1812 1884
1813 #undef __ 1885 #undef __
1814 1886
1815 } // namespace internal 1887 } // namespace internal
1816 } // namespace v8 1888 } // namespace v8
1817 1889
1818 #endif // V8_TARGET_ARCH_MIPS 1890 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ia32/frames-ia32.h ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698