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_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 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 __ Move(arg_reg_2, Smi::FromInt(field_index)); | 1316 __ Move(arg_reg_2, Smi::FromInt(field_index)); |
1317 __ CallCFunction( | 1317 __ CallCFunction( |
1318 ExternalReference::get_date_field_function(masm->isolate()), 2); | 1318 ExternalReference::get_date_field_function(masm->isolate()), 2); |
1319 } | 1319 } |
1320 __ ret(1 * kPointerSize); | 1320 __ ret(1 * kPointerSize); |
1321 | 1321 |
1322 // 3. Raise a TypeError if the receiver is not a date. | 1322 // 3. Raise a TypeError if the receiver is not a date. |
1323 __ bind(&receiver_not_date); | 1323 __ bind(&receiver_not_date); |
1324 { | 1324 { |
1325 FrameScope scope(masm, StackFrame::MANUAL); | 1325 FrameScope scope(masm, StackFrame::MANUAL); |
1326 __ Push(rbp); | 1326 __ Move(rbx, Smi::FromInt(0)); |
1327 __ Move(rbp, rsp); | 1327 __ EnterBuiltinFrame(rsi, rdi, rbx); |
1328 __ Push(rsi); | |
1329 __ Push(rdi); | |
1330 __ Push(Immediate(0)); | |
1331 __ CallRuntime(Runtime::kThrowNotDateError); | 1328 __ CallRuntime(Runtime::kThrowNotDateError); |
1332 } | 1329 } |
1333 } | 1330 } |
1334 | 1331 |
1335 // static | 1332 // static |
1336 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { | 1333 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { |
1337 // ----------- S t a t e ------------- | 1334 // ----------- S t a t e ------------- |
1338 // -- rax : argc | 1335 // -- rax : argc |
1339 // -- rsp[0] : return address | 1336 // -- rsp[0] : return address |
1340 // -- rsp[8] : argArray | 1337 // -- rsp[8] : argArray |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 } | 1663 } |
1667 | 1664 |
1668 __ movp(rdx, rdi); | 1665 __ movp(rdx, rdi); |
1669 // Run the native code for the Array function called as a normal function. | 1666 // Run the native code for the Array function called as a normal function. |
1670 // tail call a stub | 1667 // tail call a stub |
1671 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1668 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
1672 ArrayConstructorStub stub(masm->isolate()); | 1669 ArrayConstructorStub stub(masm->isolate()); |
1673 __ TailCallStub(&stub); | 1670 __ TailCallStub(&stub); |
1674 } | 1671 } |
1675 | 1672 |
1676 | |
1677 // static | 1673 // static |
1678 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { | 1674 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
1679 // ----------- S t a t e ------------- | 1675 // ----------- S t a t e ------------- |
1680 // -- rax : number of arguments | 1676 // -- rax : number of arguments |
1681 // -- rdi : function | 1677 // -- rdi : function |
1682 // -- rsi : context | 1678 // -- rsi : context |
1683 // -- rsp[0] : return address | 1679 // -- rsp[0] : return address |
1684 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1680 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1685 // -- rsp[(argc + 1) * 8] : receiver | 1681 // -- rsp[(argc + 1) * 8] : receiver |
1686 // ----------------------------------- | 1682 // ----------------------------------- |
(...skipping 22 matching lines...) Expand all Loading... |
1709 // Load the double value of the parameter into xmm1, maybe converting the | 1705 // Load the double value of the parameter into xmm1, maybe converting the |
1710 // parameter to a number first using the ToNumber builtin if necessary. | 1706 // parameter to a number first using the ToNumber builtin if necessary. |
1711 Label convert, convert_smi, convert_number, done_convert; | 1707 Label convert, convert_smi, convert_number, done_convert; |
1712 __ bind(&convert); | 1708 __ bind(&convert); |
1713 __ JumpIfSmi(rbx, &convert_smi); | 1709 __ JumpIfSmi(rbx, &convert_smi); |
1714 __ JumpIfRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 1710 __ JumpIfRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
1715 Heap::kHeapNumberMapRootIndex, &convert_number); | 1711 Heap::kHeapNumberMapRootIndex, &convert_number); |
1716 { | 1712 { |
1717 // Parameter is not a Number, use the ToNumber builtin to convert it. | 1713 // Parameter is not a Number, use the ToNumber builtin to convert it. |
1718 FrameScope scope(masm, StackFrame::MANUAL); | 1714 FrameScope scope(masm, StackFrame::MANUAL); |
1719 __ Push(rbp); | |
1720 __ Move(rbp, rsp); | |
1721 __ Push(rsi); | |
1722 __ Push(rdi); | |
1723 __ Integer32ToSmi(rax, rax); | 1715 __ Integer32ToSmi(rax, rax); |
1724 __ Integer32ToSmi(rcx, rcx); | 1716 __ Integer32ToSmi(rcx, rcx); |
1725 __ Push(rax); | 1717 __ EnterBuiltinFrame(rsi, rdi, rax); |
1726 __ Push(rcx); | 1718 __ Push(rcx); |
1727 __ Push(rdx); | 1719 __ Push(rdx); |
1728 __ movp(rax, rbx); | 1720 __ movp(rax, rbx); |
1729 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 1721 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
1730 __ movp(rbx, rax); | 1722 __ movp(rbx, rax); |
1731 __ Pop(rdx); | 1723 __ Pop(rdx); |
1732 __ Pop(rcx); | 1724 __ Pop(rcx); |
1733 __ Pop(rax); | 1725 __ LeaveBuiltinFrame(rsi, rdi, rax); |
1734 __ Pop(rdi); | 1726 __ SmiToInteger32(rcx, rcx); |
1735 __ Pop(rsi); | 1727 __ SmiToInteger32(rax, rax); |
1736 { | 1728 { |
1737 // Restore the double accumulator value (xmm0). | 1729 // Restore the double accumulator value (xmm0). |
1738 Label restore_smi, done_restore; | 1730 Label restore_smi, done_restore; |
1739 __ JumpIfSmi(rdx, &restore_smi, Label::kNear); | 1731 __ JumpIfSmi(rdx, &restore_smi, Label::kNear); |
1740 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); | 1732 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
1741 __ jmp(&done_restore, Label::kNear); | 1733 __ jmp(&done_restore, Label::kNear); |
1742 __ bind(&restore_smi); | 1734 __ bind(&restore_smi); |
1743 __ SmiToDouble(xmm0, rdx); | 1735 __ SmiToDouble(xmm0, rdx); |
1744 __ bind(&done_restore); | 1736 __ bind(&done_restore); |
1745 } | 1737 } |
1746 __ SmiToInteger32(rcx, rcx); | |
1747 __ SmiToInteger32(rax, rax); | |
1748 __ leave(); | |
1749 } | 1738 } |
1750 __ jmp(&convert); | 1739 __ jmp(&convert); |
1751 __ bind(&convert_number); | 1740 __ bind(&convert_number); |
1752 __ Movsd(xmm1, FieldOperand(rbx, HeapNumber::kValueOffset)); | 1741 __ Movsd(xmm1, FieldOperand(rbx, HeapNumber::kValueOffset)); |
1753 __ jmp(&done_convert, Label::kNear); | 1742 __ jmp(&done_convert, Label::kNear); |
1754 __ bind(&convert_smi); | 1743 __ bind(&convert_smi); |
1755 __ SmiToDouble(xmm1, rbx); | 1744 __ SmiToDouble(xmm1, rbx); |
1756 __ bind(&done_convert); | 1745 __ bind(&done_convert); |
1757 | 1746 |
1758 // Perform the actual comparison with the accumulator value on the left hand | 1747 // Perform the actual comparison with the accumulator value on the left hand |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1792 __ PushReturnAddressFrom(rcx); | 1781 __ PushReturnAddressFrom(rcx); |
1793 __ movp(rax, rdx); | 1782 __ movp(rax, rdx); |
1794 __ Ret(); | 1783 __ Ret(); |
1795 } | 1784 } |
1796 | 1785 |
1797 // static | 1786 // static |
1798 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 1787 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
1799 // ----------- S t a t e ------------- | 1788 // ----------- S t a t e ------------- |
1800 // -- rax : number of arguments | 1789 // -- rax : number of arguments |
1801 // -- rdi : constructor function | 1790 // -- rdi : constructor function |
| 1791 // -- rsi : context |
1802 // -- rsp[0] : return address | 1792 // -- rsp[0] : return address |
1803 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1793 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1804 // -- rsp[(argc + 1) * 8] : receiver | 1794 // -- rsp[(argc + 1) * 8] : receiver |
1805 // ----------------------------------- | 1795 // ----------------------------------- |
1806 | 1796 |
1807 // 1. Load the first argument into rax and get rid of the rest (including the | 1797 // 1. Load the first argument into rbx. |
1808 // receiver). | |
1809 Label no_arguments; | 1798 Label no_arguments; |
1810 { | 1799 { |
1811 StackArgumentsAccessor args(rsp, rax); | 1800 StackArgumentsAccessor args(rsp, rax); |
1812 __ testp(rax, rax); | 1801 __ testp(rax, rax); |
1813 __ j(zero, &no_arguments, Label::kNear); | 1802 __ j(zero, &no_arguments, Label::kNear); |
1814 __ movp(rbx, args.GetArgumentOperand(1)); | 1803 __ movp(rbx, args.GetArgumentOperand(1)); |
1815 __ PopReturnAddressTo(rcx); | |
1816 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
1817 __ PushReturnAddressFrom(rcx); | |
1818 __ movp(rax, rbx); | |
1819 } | 1804 } |
1820 | 1805 |
1821 // 2a. Convert the first argument to a number. | 1806 // 2a. Convert the first argument to a number. |
1822 __ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 1807 { |
| 1808 FrameScope scope(masm, StackFrame::MANUAL); |
| 1809 __ Integer32ToSmi(rax, rax); |
| 1810 __ EnterBuiltinFrame(rsi, rdi, rax); |
| 1811 __ movp(rax, rbx); |
| 1812 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
| 1813 __ LeaveBuiltinFrame(rsi, rdi, rbx); // Argc popped to rbx. |
| 1814 __ SmiToInteger32(rbx, rbx); |
| 1815 } |
| 1816 |
| 1817 { |
| 1818 // Drop all arguments including the receiver. |
| 1819 __ PopReturnAddressTo(rcx); |
| 1820 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, kPointerSize)); |
| 1821 __ PushReturnAddressFrom(rcx); |
| 1822 __ Ret(); |
| 1823 } |
1823 | 1824 |
1824 // 2b. No arguments, return +0 (already in rax). | 1825 // 2b. No arguments, return +0 (already in rax). |
1825 __ bind(&no_arguments); | 1826 __ bind(&no_arguments); |
1826 __ ret(1 * kPointerSize); | 1827 __ ret(1 * kPointerSize); |
1827 } | 1828 } |
1828 | 1829 |
1829 | 1830 |
1830 // static | 1831 // static |
1831 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { | 1832 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { |
1832 // ----------- S t a t e ------------- | 1833 // ----------- S t a t e ------------- |
1833 // -- rax : number of arguments | 1834 // -- rax : number of arguments |
1834 // -- rdi : constructor function | 1835 // -- rdi : constructor function |
1835 // -- rdx : new target | 1836 // -- rdx : new target |
| 1837 // -- rsi : context |
1836 // -- rsp[0] : return address | 1838 // -- rsp[0] : return address |
1837 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1839 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1838 // -- rsp[(argc + 1) * 8] : receiver | 1840 // -- rsp[(argc + 1) * 8] : receiver |
1839 // ----------------------------------- | 1841 // ----------------------------------- |
1840 | 1842 |
1841 // 1. Make sure we operate in the context of the called function. | 1843 // 1. Make sure we operate in the context of the called function. |
1842 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 1844 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
1843 | 1845 |
1844 // 2. Load the first argument into rbx and get rid of the rest (including the | 1846 // Store argc in r8. |
1845 // receiver). | 1847 __ Integer32ToSmi(r8, rax); |
| 1848 |
| 1849 // 2. Load the first argument into rbx. |
1846 { | 1850 { |
1847 StackArgumentsAccessor args(rsp, rax); | 1851 StackArgumentsAccessor args(rsp, rax); |
1848 Label no_arguments, done; | 1852 Label no_arguments, done; |
1849 __ testp(rax, rax); | 1853 __ testp(rax, rax); |
1850 __ j(zero, &no_arguments, Label::kNear); | 1854 __ j(zero, &no_arguments, Label::kNear); |
1851 __ movp(rbx, args.GetArgumentOperand(1)); | 1855 __ movp(rbx, args.GetArgumentOperand(1)); |
1852 __ jmp(&done, Label::kNear); | 1856 __ jmp(&done, Label::kNear); |
1853 __ bind(&no_arguments); | 1857 __ bind(&no_arguments); |
1854 __ Move(rbx, Smi::FromInt(0)); | 1858 __ Move(rbx, Smi::FromInt(0)); |
1855 __ bind(&done); | 1859 __ bind(&done); |
1856 __ PopReturnAddressTo(rcx); | |
1857 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
1858 __ PushReturnAddressFrom(rcx); | |
1859 } | 1860 } |
1860 | 1861 |
1861 // 3. Make sure rbx is a number. | 1862 // 3. Make sure rbx is a number. |
1862 { | 1863 { |
1863 Label done_convert; | 1864 Label done_convert; |
1864 __ JumpIfSmi(rbx, &done_convert); | 1865 __ JumpIfSmi(rbx, &done_convert); |
1865 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 1866 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
1866 Heap::kHeapNumberMapRootIndex); | 1867 Heap::kHeapNumberMapRootIndex); |
1867 __ j(equal, &done_convert); | 1868 __ j(equal, &done_convert); |
1868 { | 1869 { |
1869 FrameScope scope(masm, StackFrame::INTERNAL); | 1870 FrameScope scope(masm, StackFrame::MANUAL); |
| 1871 __ EnterBuiltinFrame(rsi, rdi, r8); |
1870 __ Push(rdx); | 1872 __ Push(rdx); |
1871 __ Push(rdi); | |
1872 __ Move(rax, rbx); | 1873 __ Move(rax, rbx); |
1873 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); | 1874 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); |
1874 __ Move(rbx, rax); | 1875 __ Move(rbx, rax); |
1875 __ Pop(rdi); | |
1876 __ Pop(rdx); | 1876 __ Pop(rdx); |
| 1877 __ LeaveBuiltinFrame(rsi, rdi, r8); |
1877 } | 1878 } |
1878 __ bind(&done_convert); | 1879 __ bind(&done_convert); |
1879 } | 1880 } |
1880 | 1881 |
1881 // 4. Check if new target and constructor differ. | 1882 // 4. Check if new target and constructor differ. |
1882 Label new_object; | 1883 Label drop_frame_and_ret, new_object; |
1883 __ cmpp(rdx, rdi); | 1884 __ cmpp(rdx, rdi); |
1884 __ j(not_equal, &new_object); | 1885 __ j(not_equal, &new_object); |
1885 | 1886 |
1886 // 5. Allocate a JSValue wrapper for the number. | 1887 // 5. Allocate a JSValue wrapper for the number. |
1887 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); | 1888 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); |
1888 __ Ret(); | 1889 __ jmp(&drop_frame_and_ret, Label::kNear); |
1889 | 1890 |
1890 // 6. Fallback to the runtime to create new object. | 1891 // 6. Fallback to the runtime to create new object. |
1891 __ bind(&new_object); | 1892 __ bind(&new_object); |
1892 { | 1893 { |
1893 FrameScope scope(masm, StackFrame::INTERNAL); | 1894 FrameScope scope(masm, StackFrame::MANUAL); |
| 1895 __ EnterBuiltinFrame(rsi, rdi, r8); |
1894 __ Push(rbx); // the first argument | 1896 __ Push(rbx); // the first argument |
1895 FastNewObjectStub stub(masm->isolate()); | 1897 FastNewObjectStub stub(masm->isolate()); |
1896 __ CallStub(&stub); | 1898 __ CallStub(&stub); |
1897 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 1899 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
| 1900 __ LeaveBuiltinFrame(rsi, rdi, r8); |
1898 } | 1901 } |
1899 __ Ret(); | 1902 |
| 1903 __ bind(&drop_frame_and_ret); |
| 1904 { |
| 1905 // Drop all arguments including the receiver. |
| 1906 __ PopReturnAddressTo(rcx); |
| 1907 __ SmiToInteger32(r8, r8); |
| 1908 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
| 1909 __ PushReturnAddressFrom(rcx); |
| 1910 __ Ret(); |
| 1911 } |
1900 } | 1912 } |
1901 | 1913 |
1902 | 1914 |
1903 // static | 1915 // static |
1904 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1916 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
1905 // ----------- S t a t e ------------- | 1917 // ----------- S t a t e ------------- |
1906 // -- rax : number of arguments | 1918 // -- rax : number of arguments |
1907 // -- rdi : constructor function | 1919 // -- rdi : constructor function |
| 1920 // -- rsi : context |
1908 // -- rsp[0] : return address | 1921 // -- rsp[0] : return address |
1909 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1922 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1910 // -- rsp[(argc + 1) * 8] : receiver | 1923 // -- rsp[(argc + 1) * 8] : receiver |
1911 // ----------------------------------- | 1924 // ----------------------------------- |
1912 | 1925 |
1913 // 1. Load the first argument into rax and get rid of the rest (including the | 1926 // 1. Load the first argument into rax. |
1914 // receiver). | |
1915 Label no_arguments; | 1927 Label no_arguments; |
1916 { | 1928 { |
1917 StackArgumentsAccessor args(rsp, rax); | 1929 StackArgumentsAccessor args(rsp, rax); |
| 1930 __ Integer32ToSmi(r8, rax); // Store argc in r8. |
1918 __ testp(rax, rax); | 1931 __ testp(rax, rax); |
1919 __ j(zero, &no_arguments, Label::kNear); | 1932 __ j(zero, &no_arguments, Label::kNear); |
1920 __ movp(rbx, args.GetArgumentOperand(1)); | 1933 __ movp(rax, args.GetArgumentOperand(1)); |
1921 __ PopReturnAddressTo(rcx); | |
1922 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
1923 __ PushReturnAddressFrom(rcx); | |
1924 __ movp(rax, rbx); | |
1925 } | 1934 } |
1926 | 1935 |
1927 // 2a. At least one argument, return rax if it's a string, otherwise | 1936 // 2a. At least one argument, return rax if it's a string, otherwise |
1928 // dispatch to appropriate conversion. | 1937 // dispatch to appropriate conversion. |
1929 Label to_string, symbol_descriptive_string; | 1938 Label drop_frame_and_ret, to_string, symbol_descriptive_string; |
1930 { | 1939 { |
1931 __ JumpIfSmi(rax, &to_string, Label::kNear); | 1940 __ JumpIfSmi(rax, &to_string, Label::kNear); |
1932 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); | 1941 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); |
1933 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); | 1942 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); |
1934 __ j(above, &to_string, Label::kNear); | 1943 __ j(above, &to_string, Label::kNear); |
1935 __ j(equal, &symbol_descriptive_string, Label::kNear); | 1944 __ j(equal, &symbol_descriptive_string, Label::kNear); |
1936 __ Ret(); | 1945 __ jmp(&drop_frame_and_ret, Label::kNear); |
1937 } | 1946 } |
1938 | 1947 |
1939 // 2b. No arguments, return the empty string (and pop the receiver). | 1948 // 2b. No arguments, return the empty string (and pop the receiver). |
1940 __ bind(&no_arguments); | 1949 __ bind(&no_arguments); |
1941 { | 1950 { |
1942 __ LoadRoot(rax, Heap::kempty_stringRootIndex); | 1951 __ LoadRoot(rax, Heap::kempty_stringRootIndex); |
1943 __ ret(1 * kPointerSize); | 1952 __ ret(1 * kPointerSize); |
1944 } | 1953 } |
1945 | 1954 |
1946 // 3a. Convert rax to a string. | 1955 // 3a. Convert rax to a string. |
1947 __ bind(&to_string); | 1956 __ bind(&to_string); |
1948 { | 1957 { |
| 1958 FrameScope scope(masm, StackFrame::MANUAL); |
1949 ToStringStub stub(masm->isolate()); | 1959 ToStringStub stub(masm->isolate()); |
1950 __ TailCallStub(&stub); | 1960 __ EnterBuiltinFrame(rsi, rdi, r8); |
| 1961 __ CallStub(&stub); |
| 1962 __ LeaveBuiltinFrame(rsi, rdi, r8); |
1951 } | 1963 } |
| 1964 __ jmp(&drop_frame_and_ret, Label::kNear); |
1952 | 1965 |
1953 // 3b. Convert symbol in rax to a string. | 1966 // 3b. Convert symbol in rax to a string. |
1954 __ bind(&symbol_descriptive_string); | 1967 __ bind(&symbol_descriptive_string); |
1955 { | 1968 { |
1956 __ PopReturnAddressTo(rcx); | 1969 __ PopReturnAddressTo(rcx); |
| 1970 __ SmiToInteger32(r8, r8); |
| 1971 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
1957 __ Push(rax); | 1972 __ Push(rax); |
1958 __ PushReturnAddressFrom(rcx); | 1973 __ PushReturnAddressFrom(rcx); |
1959 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); | 1974 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); |
1960 } | 1975 } |
| 1976 |
| 1977 __ bind(&drop_frame_and_ret); |
| 1978 { |
| 1979 // Drop all arguments including the receiver. |
| 1980 __ PopReturnAddressTo(rcx); |
| 1981 __ SmiToInteger32(r8, r8); |
| 1982 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
| 1983 __ PushReturnAddressFrom(rcx); |
| 1984 __ Ret(); |
| 1985 } |
1961 } | 1986 } |
1962 | 1987 |
1963 | 1988 |
1964 // static | 1989 // static |
1965 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1990 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1966 // ----------- S t a t e ------------- | 1991 // ----------- S t a t e ------------- |
1967 // -- rax : number of arguments | 1992 // -- rax : number of arguments |
1968 // -- rdi : constructor function | 1993 // -- rdi : constructor function |
1969 // -- rdx : new target | 1994 // -- rdx : new target |
| 1995 // -- rsi : context |
1970 // -- rsp[0] : return address | 1996 // -- rsp[0] : return address |
1971 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1997 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1972 // -- rsp[(argc + 1) * 8] : receiver | 1998 // -- rsp[(argc + 1) * 8] : receiver |
1973 // ----------------------------------- | 1999 // ----------------------------------- |
1974 | 2000 |
1975 // 1. Make sure we operate in the context of the called function. | 2001 // 1. Make sure we operate in the context of the called function. |
1976 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2002 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
1977 | 2003 |
1978 // 2. Load the first argument into rbx and get rid of the rest (including the | 2004 // Store argc in r8. |
1979 // receiver). | 2005 __ Integer32ToSmi(r8, rax); |
| 2006 |
| 2007 // 2. Load the first argument into rbx. |
1980 { | 2008 { |
1981 StackArgumentsAccessor args(rsp, rax); | 2009 StackArgumentsAccessor args(rsp, rax); |
1982 Label no_arguments, done; | 2010 Label no_arguments, done; |
1983 __ testp(rax, rax); | 2011 __ testp(rax, rax); |
1984 __ j(zero, &no_arguments, Label::kNear); | 2012 __ j(zero, &no_arguments, Label::kNear); |
1985 __ movp(rbx, args.GetArgumentOperand(1)); | 2013 __ movp(rbx, args.GetArgumentOperand(1)); |
1986 __ jmp(&done, Label::kNear); | 2014 __ jmp(&done, Label::kNear); |
1987 __ bind(&no_arguments); | 2015 __ bind(&no_arguments); |
1988 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); | 2016 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
1989 __ bind(&done); | 2017 __ bind(&done); |
1990 __ PopReturnAddressTo(rcx); | |
1991 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | |
1992 __ PushReturnAddressFrom(rcx); | |
1993 } | 2018 } |
1994 | 2019 |
1995 // 3. Make sure rbx is a string. | 2020 // 3. Make sure rbx is a string. |
1996 { | 2021 { |
1997 Label convert, done_convert; | 2022 Label convert, done_convert; |
1998 __ JumpIfSmi(rbx, &convert, Label::kNear); | 2023 __ JumpIfSmi(rbx, &convert, Label::kNear); |
1999 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); | 2024 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); |
2000 __ j(below, &done_convert); | 2025 __ j(below, &done_convert); |
2001 __ bind(&convert); | 2026 __ bind(&convert); |
2002 { | 2027 { |
2003 FrameScope scope(masm, StackFrame::INTERNAL); | 2028 FrameScope scope(masm, StackFrame::MANUAL); |
2004 ToStringStub stub(masm->isolate()); | 2029 ToStringStub stub(masm->isolate()); |
| 2030 __ EnterBuiltinFrame(rsi, rdi, r8); |
2005 __ Push(rdx); | 2031 __ Push(rdx); |
2006 __ Push(rdi); | |
2007 __ Move(rax, rbx); | 2032 __ Move(rax, rbx); |
2008 __ CallStub(&stub); | 2033 __ CallStub(&stub); |
2009 __ Move(rbx, rax); | 2034 __ Move(rbx, rax); |
2010 __ Pop(rdi); | |
2011 __ Pop(rdx); | 2035 __ Pop(rdx); |
| 2036 __ LeaveBuiltinFrame(rsi, rdi, r8); |
2012 } | 2037 } |
2013 __ bind(&done_convert); | 2038 __ bind(&done_convert); |
2014 } | 2039 } |
2015 | 2040 |
2016 // 4. Check if new target and constructor differ. | 2041 // 4. Check if new target and constructor differ. |
2017 Label new_object; | 2042 Label drop_frame_and_ret, new_object; |
2018 __ cmpp(rdx, rdi); | 2043 __ cmpp(rdx, rdi); |
2019 __ j(not_equal, &new_object); | 2044 __ j(not_equal, &new_object); |
2020 | 2045 |
2021 // 5. Allocate a JSValue wrapper for the string. | 2046 // 5. Allocate a JSValue wrapper for the string. |
2022 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); | 2047 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); |
2023 __ Ret(); | 2048 __ jmp(&drop_frame_and_ret, Label::kNear); |
2024 | 2049 |
2025 // 6. Fallback to the runtime to create new object. | 2050 // 6. Fallback to the runtime to create new object. |
2026 __ bind(&new_object); | 2051 __ bind(&new_object); |
2027 { | 2052 { |
2028 FrameScope scope(masm, StackFrame::INTERNAL); | 2053 FrameScope scope(masm, StackFrame::MANUAL); |
| 2054 __ EnterBuiltinFrame(rsi, rdi, r8); |
2029 __ Push(rbx); // the first argument | 2055 __ Push(rbx); // the first argument |
2030 FastNewObjectStub stub(masm->isolate()); | 2056 FastNewObjectStub stub(masm->isolate()); |
2031 __ CallStub(&stub); | 2057 __ CallStub(&stub); |
2032 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); | 2058 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); |
| 2059 __ LeaveBuiltinFrame(rsi, rdi, r8); |
2033 } | 2060 } |
2034 __ Ret(); | 2061 |
| 2062 __ bind(&drop_frame_and_ret); |
| 2063 { |
| 2064 // Drop all arguments including the receiver. |
| 2065 __ PopReturnAddressTo(rcx); |
| 2066 __ SmiToInteger32(r8, r8); |
| 2067 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize)); |
| 2068 __ PushReturnAddressFrom(rcx); |
| 2069 __ Ret(); |
| 2070 } |
2035 } | 2071 } |
2036 | 2072 |
2037 | 2073 |
2038 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 2074 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
2039 Label* stack_overflow) { | 2075 Label* stack_overflow) { |
2040 // ----------- S t a t e ------------- | 2076 // ----------- S t a t e ------------- |
2041 // -- rax : actual number of arguments | 2077 // -- rax : actual number of arguments |
2042 // -- rbx : expected number of arguments | 2078 // -- rbx : expected number of arguments |
2043 // -- rdx : new target (passed through to callee) | 2079 // -- rdx : new target (passed through to callee) |
2044 // -- rdi : function (passed through to callee) | 2080 // -- rdi : function (passed through to callee) |
(...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3084 __ ret(0); | 3120 __ ret(0); |
3085 } | 3121 } |
3086 | 3122 |
3087 | 3123 |
3088 #undef __ | 3124 #undef __ |
3089 | 3125 |
3090 } // namespace internal | 3126 } // namespace internal |
3091 } // namespace v8 | 3127 } // namespace v8 |
3092 | 3128 |
3093 #endif // V8_TARGET_ARCH_X64 | 3129 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |