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

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

Issue 1436493002: [builtins] Introduce specialized Call/CallFunction builtins. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/mips64/builtins-mips64.cc ('k') | no next file » | 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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.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"
(...skipping 1699 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 { 1710 {
1711 FrameScope frame(masm, StackFrame::MANUAL); 1711 FrameScope frame(masm, StackFrame::MANUAL);
1712 EnterArgumentsAdaptorFrame(masm); 1712 EnterArgumentsAdaptorFrame(masm);
1713 __ CallRuntime(Runtime::kThrowStackOverflow, 0); 1713 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
1714 __ int3(); 1714 __ int3();
1715 } 1715 }
1716 } 1716 }
1717 1717
1718 1718
1719 // static 1719 // static
1720 void Builtins::Generate_CallFunction(MacroAssembler* masm) { 1720 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1721 // ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1721 ConvertReceiverMode mode) {
1722 // ----------- S t a t e ------------- 1722 // ----------- S t a t e -------------
1723 // -- rax : the number of arguments (not including the receiver) 1723 // -- rax : the number of arguments (not including the receiver)
1724 // -- rdi : the function to call (checked to be a JSFunction) 1724 // -- rdi : the function to call (checked to be a JSFunction)
1725 // ----------------------------------- 1725 // -----------------------------------
1726
1727 Label convert, convert_global_proxy, convert_to_object, done_convert;
1728 StackArgumentsAccessor args(rsp, rax); 1726 StackArgumentsAccessor args(rsp, rax);
1729 __ AssertFunction(rdi); 1727 __ AssertFunction(rdi);
1728
1729 // ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1730 // Check that the function is not a "classConstructor".
1731 Label class_constructor;
1730 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 1732 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
1731 { 1733 __ testb(FieldOperand(rdx, SharedFunctionInfo::kFunctionKindByteOffset),
1732 Label non_class_constructor; 1734 Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1733 // Check whether the current function is a classConstructor 1735 __ j(not_zero, &class_constructor);
1734 __ testb(FieldOperand(rdx, SharedFunctionInfo::kFunctionKindByteOffset), 1736
1735 Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte)); 1737 // ----------- S t a t e -------------
1736 __ j(zero, &non_class_constructor); 1738 // -- rax : the number of arguments (not including the receiver)
1737 // Step: 2, If we call a classConstructor Function throw a TypeError. 1739 // -- rdx : the shared function info.
1738 { 1740 // -- rdi : the function to call (checked to be a JSFunction)
1739 FrameScope frame(masm, StackFrame::INTERNAL); 1741 // -----------------------------------
1740 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1741 }
1742 __ bind(&non_class_constructor);
1743 }
1744 1742
1745 // Enter the context of the function; ToObject has to run in the function 1743 // Enter the context of the function; ToObject has to run in the function
1746 // context, and we also need to take the global proxy from the function 1744 // context, and we also need to take the global proxy from the function
1747 // context in case of conversion. 1745 // context in case of conversion.
1748 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == 1746 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1749 SharedFunctionInfo::kStrictModeByteOffset); 1747 SharedFunctionInfo::kStrictModeByteOffset);
1750 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 1748 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1751 // We need to convert the receiver for non-native sloppy mode functions. 1749 // We need to convert the receiver for non-native sloppy mode functions.
1750 Label done_convert;
1752 __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset), 1751 __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
1753 Immediate((1 << SharedFunctionInfo::kNativeBitWithinByte) | 1752 Immediate((1 << SharedFunctionInfo::kNativeBitWithinByte) |
1754 (1 << SharedFunctionInfo::kStrictModeBitWithinByte))); 1753 (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
1755 __ j(not_zero, &done_convert); 1754 __ j(not_zero, &done_convert);
1756 { 1755 {
1757 __ movp(rcx, args.GetReceiverOperand());
1758
1759 // ----------- S t a t e ------------- 1756 // ----------- S t a t e -------------
1760 // -- rax : the number of arguments (not including the receiver) 1757 // -- rax : the number of arguments (not including the receiver)
1761 // -- rcx : the receiver
1762 // -- rdx : the shared function info. 1758 // -- rdx : the shared function info.
1763 // -- rdi : the function to call (checked to be a JSFunction) 1759 // -- rdi : the function to call (checked to be a JSFunction)
1764 // -- rsi : the function context. 1760 // -- rsi : the function context.
1765 // ----------------------------------- 1761 // -----------------------------------
1766 1762
1767 Label convert_receiver; 1763 if (mode == ConvertReceiverMode::kNullOrUndefined) {
1768 __ JumpIfSmi(rcx, &convert_to_object, Label::kNear);
1769 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1770 __ CmpObjectType(rcx, FIRST_JS_RECEIVER_TYPE, rbx);
1771 __ j(above_equal, &done_convert);
1772 __ JumpIfRoot(rcx, Heap::kUndefinedValueRootIndex, &convert_global_proxy,
1773 Label::kNear);
1774 __ JumpIfNotRoot(rcx, Heap::kNullValueRootIndex, &convert_to_object,
1775 Label::kNear);
1776 __ bind(&convert_global_proxy);
1777 {
1778 // Patch receiver to global proxy. 1764 // Patch receiver to global proxy.
1779 __ LoadGlobalProxy(rcx); 1765 __ LoadGlobalProxy(rcx);
1766 } else {
1767 Label convert_to_object, convert_receiver;
1768 __ movp(rcx, args.GetReceiverOperand());
1769 __ JumpIfSmi(rcx, &convert_to_object, Label::kNear);
1770 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1771 __ CmpObjectType(rcx, FIRST_JS_RECEIVER_TYPE, rbx);
1772 __ j(above_equal, &done_convert);
1773 if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
1774 Label convert_global_proxy;
1775 __ JumpIfRoot(rcx, Heap::kUndefinedValueRootIndex,
1776 &convert_global_proxy, Label::kNear);
1777 __ JumpIfNotRoot(rcx, Heap::kNullValueRootIndex, &convert_to_object,
1778 Label::kNear);
1779 __ bind(&convert_global_proxy);
1780 {
1781 // Patch receiver to global proxy.
1782 __ LoadGlobalProxy(rcx);
1783 }
1784 __ jmp(&convert_receiver);
1785 }
1786 __ bind(&convert_to_object);
1787 {
1788 // Convert receiver using ToObject.
1789 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1790 // in the fast case? (fall back to AllocateInNewSpace?)
1791 FrameScope scope(masm, StackFrame::INTERNAL);
1792 __ Integer32ToSmi(rax, rax);
1793 __ Push(rax);
1794 __ Push(rdi);
1795 __ movp(rax, rcx);
1796 ToObjectStub stub(masm->isolate());
1797 __ CallStub(&stub);
1798 __ movp(rcx, rax);
1799 __ Pop(rdi);
1800 __ Pop(rax);
1801 __ SmiToInteger32(rax, rax);
1802 }
1803 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
1804 __ bind(&convert_receiver);
1780 } 1805 }
1781 __ jmp(&convert_receiver);
1782 __ bind(&convert_to_object);
1783 {
1784 // Convert receiver using ToObject.
1785 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1786 // in the fast case? (fall back to AllocateInNewSpace?)
1787 FrameScope scope(masm, StackFrame::INTERNAL);
1788 __ Integer32ToSmi(rax, rax);
1789 __ Push(rax);
1790 __ Push(rdi);
1791 __ movp(rax, rcx);
1792 ToObjectStub stub(masm->isolate());
1793 __ CallStub(&stub);
1794 __ movp(rcx, rax);
1795 __ Pop(rdi);
1796 __ Pop(rax);
1797 __ SmiToInteger32(rax, rax);
1798 }
1799 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
1800 __ bind(&convert_receiver);
1801 __ movp(args.GetReceiverOperand(), rcx); 1806 __ movp(args.GetReceiverOperand(), rcx);
1802 } 1807 }
1803 __ bind(&done_convert); 1808 __ bind(&done_convert);
1804 1809
1805 // ----------- S t a t e ------------- 1810 // ----------- S t a t e -------------
1806 // -- rax : the number of arguments (not including the receiver) 1811 // -- rax : the number of arguments (not including the receiver)
1807 // -- rdx : the shared function info. 1812 // -- rdx : the shared function info.
1808 // -- rdi : the function to call (checked to be a JSFunction) 1813 // -- rdi : the function to call (checked to be a JSFunction)
1809 // -- rsi : the function context. 1814 // -- rsi : the function context.
1810 // ----------------------------------- 1815 // -----------------------------------
1811 1816
1812 __ LoadSharedFunctionInfoSpecialField( 1817 __ LoadSharedFunctionInfoSpecialField(
1813 rbx, rdx, SharedFunctionInfo::kFormalParameterCountOffset); 1818 rbx, rdx, SharedFunctionInfo::kFormalParameterCountOffset);
1814 __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 1819 __ movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1815 ParameterCount actual(rax); 1820 ParameterCount actual(rax);
1816 ParameterCount expected(rbx); 1821 ParameterCount expected(rbx);
1817 __ InvokeCode(rdx, expected, actual, JUMP_FUNCTION, NullCallWrapper()); 1822 __ InvokeCode(rdx, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1823
1824 // The function is a "classConstructor", need to raise an exception.
1825 __ bind(&class_constructor);
1826 {
1827 FrameScope frame(masm, StackFrame::INTERNAL);
1828 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0);
1829 }
1818 } 1830 }
1819 1831
1820 1832
1821 // static 1833 // static
1822 void Builtins::Generate_Call(MacroAssembler* masm) { 1834 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1823 // ----------- S t a t e ------------- 1835 // ----------- S t a t e -------------
1824 // -- rax : the number of arguments (not including the receiver) 1836 // -- rax : the number of arguments (not including the receiver)
1825 // -- rdi : the target to call (can be any Object) 1837 // -- rdi : the target to call (can be any Object)
1826 // ----------------------------------- 1838 // -----------------------------------
1827 StackArgumentsAccessor args(rsp, rax); 1839 StackArgumentsAccessor args(rsp, rax);
1828 1840
1829 Label non_callable, non_function, non_smi; 1841 Label non_callable, non_function, non_smi;
1830 __ JumpIfSmi(rdi, &non_callable); 1842 __ JumpIfSmi(rdi, &non_callable);
1831 __ bind(&non_smi); 1843 __ bind(&non_smi);
1832 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 1844 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
1833 __ j(equal, masm->isolate()->builtins()->CallFunction(), 1845 __ j(equal, masm->isolate()->builtins()->CallFunction(mode),
1834 RelocInfo::CODE_TARGET); 1846 RelocInfo::CODE_TARGET);
1835 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE); 1847 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
1836 __ j(not_equal, &non_function); 1848 __ j(not_equal, &non_function);
1837 1849
1838 // 1. Call to function proxy. 1850 // 1. Call to function proxy.
1839 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies. 1851 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1840 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kCallTrapOffset)); 1852 __ movp(rdi, FieldOperand(rdi, JSFunctionProxy::kCallTrapOffset));
1841 __ AssertNotSmi(rdi); 1853 __ AssertNotSmi(rdi);
1842 __ jmp(&non_smi); 1854 __ jmp(&non_smi);
1843 1855
1844 // 2. Call to something else, which might have a [[Call]] internal method (if 1856 // 2. Call to something else, which might have a [[Call]] internal method (if
1845 // not we raise an exception). 1857 // not we raise an exception).
1846 __ bind(&non_function); 1858 __ bind(&non_function);
1847 // Check if target has a [[Call]] internal method. 1859 // Check if target has a [[Call]] internal method.
1848 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 1860 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
1849 Immediate(1 << Map::kIsCallable)); 1861 Immediate(1 << Map::kIsCallable));
1850 __ j(zero, &non_callable, Label::kNear); 1862 __ j(zero, &non_callable, Label::kNear);
1851 // Overwrite the original receiver with the (original) target. 1863 // Overwrite the original receiver with the (original) target.
1852 __ movp(args.GetReceiverOperand(), rdi); 1864 __ movp(args.GetReceiverOperand(), rdi);
1853 // Let the "call_as_function_delegate" take care of the rest. 1865 // Let the "call_as_function_delegate" take care of the rest.
1854 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi); 1866 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, rdi);
1855 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET); 1867 __ Jump(masm->isolate()->builtins()->CallFunction(
1868 ConvertReceiverMode::kNotNullOrUndefined),
1869 RelocInfo::CODE_TARGET);
1856 1870
1857 // 3. Call to something that is not callable. 1871 // 3. Call to something that is not callable.
1858 __ bind(&non_callable); 1872 __ bind(&non_callable);
1859 { 1873 {
1860 FrameScope scope(masm, StackFrame::INTERNAL); 1874 FrameScope scope(masm, StackFrame::INTERNAL);
1861 __ Push(rdi); 1875 __ Push(rdi);
1862 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); 1876 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1);
1863 } 1877 }
1864 } 1878 }
1865 1879
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 __ ret(0); 2015 __ ret(0);
2002 } 2016 }
2003 2017
2004 2018
2005 #undef __ 2019 #undef __
2006 2020
2007 } // namespace internal 2021 } // namespace internal
2008 } // namespace v8 2022 } // namespace v8
2009 2023
2010 #endif // V8_TARGET_ARCH_X64 2024 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips64/builtins-mips64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698