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

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

Issue 1548253002: X87: [runtime] Introduce dedicated JSBoundFunction to represent bound functions. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/code-stubs-x87.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_X87 5 #if V8_TARGET_ARCH_X87
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 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 // The function is a "classConstructor", need to raise an exception. 1766 // The function is a "classConstructor", need to raise an exception.
1767 __ bind(&class_constructor); 1767 __ bind(&class_constructor);
1768 { 1768 {
1769 FrameScope frame(masm, StackFrame::INTERNAL); 1769 FrameScope frame(masm, StackFrame::INTERNAL);
1770 __ push(edi); 1770 __ push(edi);
1771 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); 1771 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1);
1772 } 1772 }
1773 } 1773 }
1774 1774
1775 1775
1776 namespace {
1777
1778 void Generate_PushBoundArguments(MacroAssembler* masm) {
1779 // ----------- S t a t e -------------
1780 // -- eax : the number of arguments (not including the receiver)
1781 // -- edx : new.target (only in case of [[Construct]])
1782 // -- edi : target (checked to be a JSBoundFunction)
1783 // -----------------------------------
1784
1785 // Load [[BoundArguments]] into ecx and length of that into ebx.
1786 Label no_bound_arguments;
1787 __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
1788 __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1789 __ SmiUntag(ebx);
1790 __ test(ebx, ebx);
1791 __ j(zero, &no_bound_arguments);
1792 {
1793 // ----------- S t a t e -------------
1794 // -- eax : the number of arguments (not including the receiver)
1795 // -- edx : new.target (only in case of [[Construct]])
1796 // -- edi : target (checked to be a JSBoundFunction)
1797 // -- ecx : the [[BoundArguments]] (implemented as FixedArray)
1798 // -- ebx : the number of [[BoundArguments]]
1799 // -----------------------------------
1800
1801 // Reserve stack space for the [[BoundArguments]].
1802 {
1803 Label done;
1804 __ lea(ecx, Operand(ebx, times_pointer_size, 0));
1805 __ sub(esp, ecx);
1806 // Check the stack for overflow. We are not trying to catch interruptions
1807 // (i.e. debug break and preemption) here, so check the "real stack
1808 // limit".
1809 __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex);
1810 __ j(greater, &done, Label::kNear); // Signed comparison.
1811 // Restore the stack pointer.
1812 __ lea(esp, Operand(esp, ebx, times_pointer_size, 0));
1813 {
1814 FrameScope scope(masm, StackFrame::MANUAL);
1815 __ EnterFrame(StackFrame::INTERNAL);
1816 __ CallRuntime(Runtime::kThrowStackOverflow, 0);
1817 }
1818 __ bind(&done);
1819 }
1820
1821 // Adjust effective number of arguments to include return address.
1822 __ inc(eax);
1823
1824 // Relocate arguments and return address down the stack.
1825 {
1826 Label loop;
1827 __ Set(ecx, 0);
1828 __ lea(ebx, Operand(esp, ebx, times_pointer_size, 0));
1829 __ bind(&loop);
1830 __ fld_s(Operand(ebx, ecx, times_pointer_size, 0));
1831 __ fstp_s(Operand(esp, ecx, times_pointer_size, 0));
1832 __ inc(ecx);
1833 __ cmp(ecx, eax);
1834 __ j(less, &loop);
1835 }
1836
1837 // Copy [[BoundArguments]] to the stack (below the arguments).
1838 {
1839 Label loop;
1840 __ mov(ecx, FieldOperand(edi, JSBoundFunction::kBoundArgumentsOffset));
1841 __ mov(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1842 __ SmiUntag(ebx);
1843 __ bind(&loop);
1844 __ dec(ebx);
1845 __ fld_s(
1846 FieldOperand(ecx, ebx, times_pointer_size, FixedArray::kHeaderSize));
1847 __ fstp_s(Operand(esp, eax, times_pointer_size, 0));
1848 __ lea(eax, Operand(eax, 1));
1849 __ j(greater, &loop);
1850 }
1851
1852 // Adjust effective number of arguments (eax contains the number of
1853 // arguments from the call plus return address plus the number of
1854 // [[BoundArguments]]), so we need to subtract one for the return address.
1855 __ dec(eax);
1856 }
1857 __ bind(&no_bound_arguments);
1858 }
1859
1860 } // namespace
1861
1862
1863 // static
1864 void Builtins::Generate_CallBoundFunction(MacroAssembler* masm) {
1865 // ----------- S t a t e -------------
1866 // -- eax : the number of arguments (not including the receiver)
1867 // -- edi : the function to call (checked to be a JSBoundFunction)
1868 // -----------------------------------
1869 __ AssertBoundFunction(edi);
1870
1871 // Patch the receiver to [[BoundThis]].
1872 __ mov(ebx, FieldOperand(edi, JSBoundFunction::kBoundThisOffset));
1873 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), ebx);
1874
1875 // Push the [[BoundArguments]] onto the stack.
1876 Generate_PushBoundArguments(masm);
1877
1878 // Call the [[BoundTargetFunction]] via the Call builtin.
1879 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
1880 __ mov(ecx, Operand::StaticVariable(ExternalReference(
1881 Builtins::kCall_ReceiverIsAny, masm->isolate())));
1882 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
1883 __ jmp(ecx);
1884 }
1885
1886
1776 // static 1887 // static
1777 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { 1888 void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
1778 // ----------- S t a t e ------------- 1889 // ----------- S t a t e -------------
1779 // -- eax : the number of arguments (not including the receiver) 1890 // -- eax : the number of arguments (not including the receiver)
1780 // -- edi : the target to call (can be any Object). 1891 // -- edi : the target to call (can be any Object).
1781 // ----------------------------------- 1892 // -----------------------------------
1782 1893
1783 Label non_callable, non_function, non_smi; 1894 Label non_callable, non_function, non_smi;
1784 __ JumpIfSmi(edi, &non_callable); 1895 __ JumpIfSmi(edi, &non_callable);
1785 __ bind(&non_smi); 1896 __ bind(&non_smi);
1786 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 1897 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
1787 __ j(equal, masm->isolate()->builtins()->CallFunction(mode), 1898 __ j(equal, masm->isolate()->builtins()->CallFunction(mode),
1788 RelocInfo::CODE_TARGET); 1899 RelocInfo::CODE_TARGET);
1900 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
1901 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(),
1902 RelocInfo::CODE_TARGET);
1789 __ CmpInstanceType(ecx, JS_PROXY_TYPE); 1903 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
1790 __ j(not_equal, &non_function); 1904 __ j(not_equal, &non_function);
1791 1905
1792 // 1. Runtime fallback for Proxy [[Call]]. 1906 // 1. Runtime fallback for Proxy [[Call]].
1793 __ PopReturnAddressTo(ecx); 1907 __ PopReturnAddressTo(ecx);
1794 __ Push(edi); 1908 __ Push(edi);
1795 __ PushReturnAddressFrom(ecx); 1909 __ PushReturnAddressFrom(ecx);
1796 // Increase the arguments size to include the pushed function and the 1910 // Increase the arguments size to include the pushed function and the
1797 // existing receiver on the stack. 1911 // existing receiver on the stack.
1798 __ add(eax, Immediate(2)); 1912 __ add(eax, Immediate(2));
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 // Tail call to the function-specific construct stub (still in the caller 1954 // Tail call to the function-specific construct stub (still in the caller
1841 // context at this point). 1955 // context at this point).
1842 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 1956 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1843 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); 1957 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
1844 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); 1958 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
1845 __ jmp(ecx); 1959 __ jmp(ecx);
1846 } 1960 }
1847 1961
1848 1962
1849 // static 1963 // static
1964 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
1965 // ----------- S t a t e -------------
1966 // -- eax : the number of arguments (not including the receiver)
1967 // -- edx : the new target (checked to be a constructor)
1968 // -- edi : the constructor to call (checked to be a JSBoundFunction)
1969 // -----------------------------------
1970 __ AssertBoundFunction(edi);
1971
1972 // Push the [[BoundArguments]] onto the stack.
1973 Generate_PushBoundArguments(masm);
1974
1975 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
1976 {
1977 Label done;
1978 __ cmp(edi, edx);
1979 __ j(not_equal, &done, Label::kNear);
1980 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
1981 __ bind(&done);
1982 }
1983
1984 // Construct the [[BoundTargetFunction]] via the Construct builtin.
1985 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
1986 __ mov(ecx, Operand::StaticVariable(
1987 ExternalReference(Builtins::kConstruct, masm->isolate())));
1988 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
1989 __ jmp(ecx);
1990 }
1991
1992
1993 // static
1850 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) { 1994 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
1851 // ----------- S t a t e ------------- 1995 // ----------- S t a t e -------------
1852 // -- eax : the number of arguments (not including the receiver) 1996 // -- eax : the number of arguments (not including the receiver)
1853 // -- edi : the constructor to call (checked to be a JSProxy) 1997 // -- edi : the constructor to call (checked to be a JSProxy)
1854 // -- edx : the new target (either the same as the constructor or 1998 // -- edx : the new target (either the same as the constructor or
1855 // the JSFunction on which new was invoked initially) 1999 // the JSFunction on which new was invoked initially)
1856 // ----------------------------------- 2000 // -----------------------------------
1857 2001
1858 // Call into the Runtime for Proxy [[Construct]]. 2002 // Call into the Runtime for Proxy [[Construct]].
1859 __ PopReturnAddressTo(ecx); 2003 __ PopReturnAddressTo(ecx);
(...skipping 23 matching lines...) Expand all
1883 2027
1884 // Dispatch based on instance type. 2028 // Dispatch based on instance type.
1885 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2029 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
1886 __ j(equal, masm->isolate()->builtins()->ConstructFunction(), 2030 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
1887 RelocInfo::CODE_TARGET); 2031 RelocInfo::CODE_TARGET);
1888 2032
1889 // Check if target has a [[Construct]] internal method. 2033 // Check if target has a [[Construct]] internal method.
1890 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); 2034 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
1891 __ j(zero, &non_constructor, Label::kNear); 2035 __ j(zero, &non_constructor, Label::kNear);
1892 2036
2037 // Only dispatch to bound functions after checking whether they are
2038 // constructors.
2039 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2040 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2041 RelocInfo::CODE_TARGET);
2042
1893 // Only dispatch to proxies after checking whether they are constructors. 2043 // Only dispatch to proxies after checking whether they are constructors.
1894 __ CmpInstanceType(ecx, JS_PROXY_TYPE); 2044 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
1895 __ j(equal, masm->isolate()->builtins()->ConstructProxy(), 2045 __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
1896 RelocInfo::CODE_TARGET); 2046 RelocInfo::CODE_TARGET);
1897 2047
1898 // Called Construct on an exotic Object with a [[Construct]] internal method. 2048 // Called Construct on an exotic Object with a [[Construct]] internal method.
1899 { 2049 {
1900 // Overwrite the original receiver with the (original) target. 2050 // Overwrite the original receiver with the (original) target.
1901 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi); 2051 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
1902 // Let the "call_as_constructor_delegate" take care of the rest. 2052 // Let the "call_as_constructor_delegate" take care of the rest.
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 2373
2224 __ bind(&ok); 2374 __ bind(&ok);
2225 __ ret(0); 2375 __ ret(0);
2226 } 2376 }
2227 2377
2228 #undef __ 2378 #undef __
2229 } // namespace internal 2379 } // namespace internal
2230 } // namespace v8 2380 } // namespace v8
2231 2381
2232 #endif // V8_TARGET_ARCH_X87 2382 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/code-stubs-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698