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

Side by Side Diff: src/arm/builtins-arm.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 | « no previous file | src/arm/code-stubs-arm.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_ARM 5 #if V8_TARGET_ARCH_ARM
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 // -- r0 : number of arguments excluding receiver 24 // -- r0 : number of arguments excluding receiver
25 // -- r1 : called function (only guaranteed when 25 // -- r1 : 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[4 * (argc - 1)] : first argument (argc == r0) 29 // -- sp[4 * (argc - 1)] : first argument (argc == r0)
31 // -- sp[4 * argc] : receiver 30 // -- sp[4 * argc] : receiver
32 // ----------------------------------- 31 // -----------------------------------
32 __ AssertFunction(r1);
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 __ ldr(cp, FieldMemOperand(r1, 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(r1); 45 __ push(r1);
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
723 __ Push(r1, argc); 730 __ Push(r1, argc);
724 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 731 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
725 732
726 __ bind(&okay); 733 __ bind(&okay);
727 } 734 }
728 735
729 736
730 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 737 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
731 bool is_construct) { 738 bool is_construct) {
732 // Called from Generate_JS_Entry 739 // Called from Generate_JS_Entry
733 // r0: code entry 740 // r0: new.target
734 // r1: function 741 // r1: function
735 // r2: receiver 742 // r2: receiver
736 // r3: argc 743 // r3: argc
737 // r4: argv 744 // r4: argv
738 // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered 745 // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered
739 ProfileEntryHookStub::MaybeCallEntryHook(masm); 746 ProfileEntryHookStub::MaybeCallEntryHook(masm);
740 747
741 // Clear the context before we push it when entering the internal frame. 748 // Clear the context before we push it when entering the internal frame.
742 __ mov(cp, Operand::Zero()); 749 __ mov(cp, Operand::Zero());
743 750
744 // Enter an internal frame. 751 // Enter an internal frame.
745 { 752 {
746 FrameScope scope(masm, StackFrame::INTERNAL); 753 FrameScope scope(masm, StackFrame::INTERNAL);
747 754
748 // Set up the context from the function argument. 755 // Setup the context (we need to use the caller context from the isolate).
749 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 756 ExternalReference context_address(Isolate::kContextAddress,
757 masm->isolate());
758 __ mov(cp, Operand(context_address));
759 __ ldr(cp, MemOperand(cp));
750 760
751 __ InitializeRootRegister(); 761 __ InitializeRootRegister();
752 762
753 // Push the function and the receiver onto the stack. 763 // Push the function and the receiver onto the stack.
754 __ push(r1); 764 __ Push(r1, r2);
755 __ push(r2);
756 765
757 // Check if we have enough stack space to push all arguments. 766 // Check if we have enough stack space to push all arguments.
758 // The function is the first thing that was pushed above after entering 767 // The function is the first thing that was pushed above after entering
759 // the internal frame. 768 // the internal frame.
760 const int kFunctionOffset = 769 const int kFunctionOffset =
761 InternalFrameConstants::kCodeOffset - kPointerSize; 770 InternalFrameConstants::kCodeOffset - kPointerSize;
762 // Clobbers r2. 771 // Clobbers r2.
763 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsUntaggedInt); 772 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsUntaggedInt);
764 773
774 // Remember new.target.
775 __ mov(r5, r0);
776
765 // Copy arguments to the stack in a loop. 777 // Copy arguments to the stack in a loop.
766 // r1: function 778 // r1: function
767 // r3: argc 779 // r3: argc
768 // r4: argv, i.e. points to first arg 780 // r4: argv, i.e. points to first arg
769 Label loop, entry; 781 Label loop, entry;
770 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); 782 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2));
771 // r2 points past last arg. 783 // r2 points past last arg.
772 __ b(&entry); 784 __ b(&entry);
773 __ bind(&loop); 785 __ bind(&loop);
774 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter 786 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter
775 __ ldr(r0, MemOperand(r0)); // dereference handle 787 __ ldr(r0, MemOperand(r0)); // dereference handle
776 __ push(r0); // push parameter 788 __ push(r0); // push parameter
777 __ bind(&entry); 789 __ bind(&entry);
778 __ cmp(r4, r2); 790 __ cmp(r4, r2);
779 __ b(ne, &loop); 791 __ b(ne, &loop);
780 792
793 // Setup new.target and argc.
794 __ mov(r0, Operand(r3));
795 __ mov(r3, Operand(r5));
796
781 // Initialize all JavaScript callee-saved registers, since they will be seen 797 // Initialize all JavaScript callee-saved registers, since they will be seen
782 // by the garbage collector as part of handlers. 798 // by the garbage collector as part of handlers.
783 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 799 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
784 __ mov(r5, Operand(r4)); 800 __ mov(r5, Operand(r4));
785 __ mov(r6, Operand(r4)); 801 __ mov(r6, Operand(r4));
786 if (!FLAG_enable_embedded_constant_pool) { 802 if (!FLAG_enable_embedded_constant_pool) {
787 __ mov(r8, Operand(r4)); 803 __ mov(r8, Operand(r4));
788 } 804 }
789 if (kR9Available == 1) { 805 if (kR9Available == 1) {
790 __ mov(r9, Operand(r4)); 806 __ mov(r9, Operand(r4));
791 } 807 }
792 808
793 // Invoke the code and pass argc as r0. 809 // Invoke the code.
794 __ mov(r0, Operand(r3)); 810 Handle<Code> builtin = is_construct
795 if (is_construct) { 811 ? masm->isolate()->builtins()->Construct()
796 // No type feedback cell is available 812 : masm->isolate()->builtins()->Call();
797 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 813 __ Call(builtin, RelocInfo::CODE_TARGET);
798 CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 814
799 __ CallStub(&stub);
800 } else {
801 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
802 }
803 // Exit the JS frame and remove the parameters (except function), and 815 // Exit the JS frame and remove the parameters (except function), and
804 // return. 816 // return.
805 // Respect ABI stack constraint. 817 // Respect ABI stack constraint.
806 } 818 }
807 __ Jump(lr); 819 __ Jump(lr);
808 820
809 // r0: result 821 // r0: result
810 } 822 }
811 823
812 824
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 __ Pop(r0); 1621 __ Pop(r0);
1610 __ SmiUntag(r0); 1622 __ SmiUntag(r0);
1611 } 1623 }
1612 // The delegate is always a regular function. 1624 // The delegate is always a regular function.
1613 __ AssertFunction(r1); 1625 __ AssertFunction(r1);
1614 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1626 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1615 } 1627 }
1616 1628
1617 1629
1618 // static 1630 // static
1631 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
1632 // ----------- S t a t e -------------
1633 // -- r0 : the number of arguments (not including the receiver)
1634 // -- r1 : the constructor to call (checked to be a JSFunction)
1635 // -- r3 : the original constructor (checked to be a JSFunction)
1636 // -----------------------------------
1637 __ AssertFunction(r1);
1638 __ AssertFunction(r3);
1639
1640 // Calling convention for function specific ConstructStubs require
1641 // r2 to contain either an AllocationSite or undefined.
1642 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1643
1644 // Tail call to the function-specific construct stub (still in the caller
1645 // context at this point).
1646 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1647 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1648 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1649 }
1650
1651
1652 // static
1653 void Builtins::Generate_Construct(MacroAssembler* masm) {
1654 // ----------- S t a t e -------------
1655 // -- r0 : the number of arguments (not including the receiver)
1656 // -- r1 : the constructor to call (can be any Object)
1657 // -- r3 : the original constructor (either the same as the constructor or
1658 // the JSFunction on which new was invoked initially)
1659 // -----------------------------------
1660
1661 Label slow;
1662 __ JumpIfSmi(r1, &slow);
1663 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE);
1664 __ Jump(masm->isolate()->builtins()->ConstructFunction(),
1665 RelocInfo::CODE_TARGET, eq);
1666 __ cmp(r5, Operand(JS_FUNCTION_PROXY_TYPE));
1667 __ b(ne, &slow);
1668
1669 // TODO(neis): This doesn't match the ES6 spec for [[Construct]] on proxies.
1670 __ ldr(r1, FieldMemOperand(r1, JSFunctionProxy::kConstructTrapOffset));
1671 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1672
1673 __ bind(&slow);
1674 {
1675 // Determine the delegate for the target (if any).
1676 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1677 __ SmiTag(r0);
1678 __ Push(r0, r1);
1679 __ CallRuntime(Runtime::kGetConstructorDelegate, 1);
1680 __ mov(r1, r0);
1681 __ Pop(r0);
1682 __ SmiUntag(r0);
1683 }
1684 // The delegate is always a regular function.
1685 __ AssertFunction(r1);
1686 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1687 }
1688
1689
1690 // static
1619 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) { 1691 void Builtins::Generate_PushArgsAndCall(MacroAssembler* masm) {
1620 // ----------- S t a t e ------------- 1692 // ----------- S t a t e -------------
1621 // -- r0 : the number of arguments (not including the receiver) 1693 // -- r0 : the number of arguments (not including the receiver)
1622 // -- r2 : the address of the first argument to be pushed. Subsequent 1694 // -- r2 : the address of the first argument to be pushed. Subsequent
1623 // arguments should be consecutive above this, in the same order as 1695 // arguments should be consecutive above this, in the same order as
1624 // they are to be pushed onto the stack. 1696 // they are to be pushed onto the stack.
1625 // -- r1 : the target to call (can be any Object). 1697 // -- r1 : the target to call (can be any Object).
1626 1698
1627 // Find the address of the last argument. 1699 // Find the address of the last argument.
1628 __ add(r3, r0, Operand(1)); // Add one for receiver. 1700 __ add(r3, r0, Operand(1)); // Add one for receiver.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 } 1859 }
1788 } 1860 }
1789 1861
1790 1862
1791 #undef __ 1863 #undef __
1792 1864
1793 } // namespace internal 1865 } // namespace internal
1794 } // namespace v8 1866 } // namespace v8
1795 1867
1796 #endif // V8_TARGET_ARCH_ARM 1868 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698