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

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

Issue 2118283003: [builtins] Construct builtin frame in String/Number ctors (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@20160630-tostringtag
Patch Set: Created 4 years, 5 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
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 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 rbc.
1814 __ SmiToInteger32(rbx, rbx);
1815 }
1816
1817 __ PopReturnAddressTo(rcx);
1818 __ leap(rsp, Operand(rsp, rbx, times_pointer_size, kPointerSize));
1819 __ PushReturnAddressFrom(rcx);
1820 __ Ret();
1823 1821
1824 // 2b. No arguments, return +0 (already in rax). 1822 // 2b. No arguments, return +0 (already in rax).
1825 __ bind(&no_arguments); 1823 __ bind(&no_arguments);
1826 __ ret(1 * kPointerSize); 1824 __ ret(1 * kPointerSize);
1827 } 1825 }
1828 1826
1829 1827
1830 // static 1828 // static
1831 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { 1829 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
1832 // ----------- S t a t e ------------- 1830 // ----------- S t a t e -------------
1833 // -- rax : number of arguments 1831 // -- rax : number of arguments
1834 // -- rdi : constructor function 1832 // -- rdi : constructor function
1833 // -- rsi : context
1835 // -- rdx : new target 1834 // -- rdx : new target
1836 // -- rsp[0] : return address 1835 // -- rsp[0] : return address
1837 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1836 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1838 // -- rsp[(argc + 1) * 8] : receiver 1837 // -- rsp[(argc + 1) * 8] : receiver
1839 // ----------------------------------- 1838 // -----------------------------------
1840 1839
1841 // 1. Make sure we operate in the context of the called function. 1840 // 1. Make sure we operate in the context of the called function.
1842 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 1841 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1843 1842
1844 // 2. Load the first argument into rbx and get rid of the rest (including the 1843 // 2. Load the first argument into rbx.
1845 // receiver).
1846 { 1844 {
1847 StackArgumentsAccessor args(rsp, rax); 1845 StackArgumentsAccessor args(rsp, rax);
1848 Label no_arguments, done; 1846 Label no_arguments, done;
1849 __ testp(rax, rax); 1847 __ testp(rax, rax);
1850 __ j(zero, &no_arguments, Label::kNear); 1848 __ j(zero, &no_arguments, Label::kNear);
1851 __ movp(rbx, args.GetArgumentOperand(1)); 1849 __ movp(rbx, args.GetArgumentOperand(1));
1852 __ jmp(&done, Label::kNear); 1850 __ jmp(&done, Label::kNear);
1853 __ bind(&no_arguments); 1851 __ bind(&no_arguments);
1854 __ Move(rbx, Smi::FromInt(0)); 1852 __ Move(rbx, Smi::FromInt(0));
1855 __ bind(&done); 1853 __ bind(&done);
1856 __ PopReturnAddressTo(rcx);
1857 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1858 __ PushReturnAddressFrom(rcx);
1859 } 1854 }
1860 1855
1861 // 3. Make sure rbx is a number. 1856 // 3. Make sure rbx is a number.
1862 { 1857 {
1863 Label done_convert; 1858 Label done_convert;
1864 __ JumpIfSmi(rbx, &done_convert); 1859 __ JumpIfSmi(rbx, &done_convert);
1865 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 1860 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
1866 Heap::kHeapNumberMapRootIndex); 1861 Heap::kHeapNumberMapRootIndex);
1867 __ j(equal, &done_convert); 1862 __ j(equal, &done_convert);
1868 { 1863 {
1869 FrameScope scope(masm, StackFrame::INTERNAL); 1864 FrameScope scope(masm, StackFrame::MANUAL);
1865 __ Integer32ToSmi(rax, rax);
1866 __ EnterBuiltinFrame(rsi, rdi, rax);
1870 __ Push(rdx); 1867 __ Push(rdx);
1871 __ Push(rdi);
1872 __ Move(rax, rbx); 1868 __ Move(rax, rbx);
1873 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); 1869 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1874 __ Move(rbx, rax); 1870 __ Move(rbx, rax);
1875 __ Pop(rdi);
1876 __ Pop(rdx); 1871 __ Pop(rdx);
1872 __ LeaveBuiltinFrame(rsi, rdi, rax);
1873 __ SmiToInteger32(rax, rax);
1877 } 1874 }
1878 __ bind(&done_convert); 1875 __ bind(&done_convert);
1876
1877 // Drop all arguments including the receiver.
1878 __ PopReturnAddressTo(rcx);
1879 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1880 __ PushReturnAddressFrom(rcx);
1879 } 1881 }
1880 1882
1881 // 4. Check if new target and constructor differ. 1883 // 4. Check if new target and constructor differ.
1882 Label new_object; 1884 Label new_object;
1883 __ cmpp(rdx, rdi); 1885 __ cmpp(rdx, rdi);
1884 __ j(not_equal, &new_object); 1886 __ j(not_equal, &new_object);
1885 1887
1886 // 5. Allocate a JSValue wrapper for the number. 1888 // 5. Allocate a JSValue wrapper for the number.
1887 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); 1889 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object);
1888 __ Ret(); 1890 __ Ret();
1889 1891
1890 // 6. Fallback to the runtime to create new object. 1892 // 6. Fallback to the runtime to create new object.
1891 __ bind(&new_object); 1893 __ bind(&new_object);
1892 { 1894 {
1895 // TODO(jgruber): Is a builtin frame needed here?
jgruber 2016/07/04 13:25:45 Just double-checking - do we want a builtin frame
Benedikt Meurer 2016/07/04 16:45:36 Yes because of new.target this is actually observa
jgruber 2016/07/07 11:50:52 Done.
1893 FrameScope scope(masm, StackFrame::INTERNAL); 1896 FrameScope scope(masm, StackFrame::INTERNAL);
1894 __ Push(rbx); // the first argument 1897 __ Push(rbx); // the first argument
1895 FastNewObjectStub stub(masm->isolate()); 1898 FastNewObjectStub stub(masm->isolate());
1896 __ CallStub(&stub); 1899 __ CallStub(&stub);
1897 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); 1900 __ Pop(FieldOperand(rax, JSValue::kValueOffset));
1898 } 1901 }
1902
1899 __ Ret(); 1903 __ Ret();
1900 } 1904 }
1901 1905
1902 1906
1903 // static 1907 // static
1904 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { 1908 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
1905 // ----------- S t a t e ------------- 1909 // ----------- S t a t e -------------
1906 // -- rax : number of arguments 1910 // -- rax : number of arguments
1907 // -- rdi : constructor function 1911 // -- rdi : constructor function
1912 // -- rsi : context
1908 // -- rsp[0] : return address 1913 // -- rsp[0] : return address
1909 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1914 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1910 // -- rsp[(argc + 1) * 8] : receiver 1915 // -- rsp[(argc + 1) * 8] : receiver
1911 // ----------------------------------- 1916 // -----------------------------------
1912 1917
1913 // 1. Load the first argument into rax and get rid of the rest (including the 1918 // 1. Load the first argument into rax and get rid of the rest (including the
1914 // receiver). 1919 // receiver).
1915 Label no_arguments; 1920 Label no_arguments;
1916 { 1921 {
1917 StackArgumentsAccessor args(rsp, rax); 1922 StackArgumentsAccessor args(rsp, rax);
1923 __ movp(r8, rax); // Store argc in r8.
1918 __ testp(rax, rax); 1924 __ testp(rax, rax);
1919 __ j(zero, &no_arguments, Label::kNear); 1925 __ j(zero, &no_arguments, Label::kNear);
1920 __ movp(rbx, args.GetArgumentOperand(1)); 1926 __ 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 } 1927 }
1926 1928
1927 // 2a. At least one argument, return rax if it's a string, otherwise 1929 // 2a. At least one argument, return rax if it's a string, otherwise
1928 // dispatch to appropriate conversion. 1930 // dispatch to appropriate conversion.
1929 Label to_string, symbol_descriptive_string; 1931 Label done, to_string, symbol_descriptive_string;
1930 { 1932 {
1931 __ JumpIfSmi(rax, &to_string, Label::kNear); 1933 __ JumpIfSmi(rax, &to_string, Label::kNear);
1932 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); 1934 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
1933 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 1935 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
1934 __ j(above, &to_string, Label::kNear); 1936 __ j(above, &to_string, Label::kNear);
1935 __ j(equal, &symbol_descriptive_string, Label::kNear); 1937 __ j(equal, &symbol_descriptive_string, Label::kNear);
1936 __ Ret(); 1938 __ jmp(&done, Label::kNear);
1937 } 1939 }
1938 1940
1939 // 2b. No arguments, return the empty string (and pop the receiver). 1941 // 2b. No arguments, return the empty string (and pop the receiver).
1940 __ bind(&no_arguments); 1942 __ bind(&no_arguments);
1941 { 1943 {
1942 __ LoadRoot(rax, Heap::kempty_stringRootIndex); 1944 __ LoadRoot(rax, Heap::kempty_stringRootIndex);
1943 __ ret(1 * kPointerSize); 1945 __ ret(1 * kPointerSize);
1944 } 1946 }
1945 1947
1946 // 3a. Convert rax to a string. 1948 // 3a. Convert rax to a string.
1947 __ bind(&to_string); 1949 __ bind(&to_string);
1948 { 1950 {
1951 FrameScope scope(masm, StackFrame::MANUAL);
1949 ToStringStub stub(masm->isolate()); 1952 ToStringStub stub(masm->isolate());
1950 __ TailCallStub(&stub); 1953 __ Integer32ToSmi(r8, r8);
1954 __ EnterBuiltinFrame(rsi, rdi, r8);
1955 __ CallStub(&stub);
1956 __ LeaveBuiltinFrame(rsi, rdi, r8);
1957 __ SmiToInteger32(r8, r8);
1951 } 1958 }
1959 __ jmp(&done, Label::kNear);
1952 1960
1953 // 3b. Convert symbol in rax to a string. 1961 // 3b. Convert symbol in rax to a string.
1954 __ bind(&symbol_descriptive_string); 1962 __ bind(&symbol_descriptive_string);
1955 { 1963 {
1956 __ PopReturnAddressTo(rcx); 1964 __ PopReturnAddressTo(rcx);
1965 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize));
1957 __ Push(rax); 1966 __ Push(rax);
1958 __ PushReturnAddressFrom(rcx); 1967 __ PushReturnAddressFrom(rcx);
1959 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); 1968 __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
jgruber 2016/07/04 13:25:44 No builtin frame here because SymbolDescriptiveStr
Benedikt Meurer 2016/07/04 16:45:36 Acknowledged.
1960 } 1969 }
1970
1971 __ bind(&done);
1972 {
1973 __ PopReturnAddressTo(rcx);
1974 __ leap(rsp, Operand(rsp, r8, times_pointer_size, kPointerSize));
1975 __ PushReturnAddressFrom(rcx);
1976 __ Ret();
1977 }
1961 } 1978 }
1962 1979
1963 1980
1964 // static 1981 // static
1965 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { 1982 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
1966 // ----------- S t a t e ------------- 1983 // ----------- S t a t e -------------
1967 // -- rax : number of arguments 1984 // -- rax : number of arguments
1968 // -- rdi : constructor function 1985 // -- rdi : constructor function
1969 // -- rdx : new target 1986 // -- rdx : new target
1987 // -- rsi : context
1970 // -- rsp[0] : return address 1988 // -- rsp[0] : return address
1971 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1989 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1972 // -- rsp[(argc + 1) * 8] : receiver 1990 // -- rsp[(argc + 1) * 8] : receiver
1973 // ----------------------------------- 1991 // -----------------------------------
1974 1992
1975 // 1. Make sure we operate in the context of the called function. 1993 // 1. Make sure we operate in the context of the called function.
1976 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 1994 __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1977 1995
1978 // 2. Load the first argument into rbx and get rid of the rest (including the 1996 // 2. Load the first argument into rbx.
1979 // receiver).
1980 { 1997 {
1981 StackArgumentsAccessor args(rsp, rax); 1998 StackArgumentsAccessor args(rsp, rax);
1982 Label no_arguments, done; 1999 Label no_arguments, done;
1983 __ testp(rax, rax); 2000 __ testp(rax, rax);
1984 __ j(zero, &no_arguments, Label::kNear); 2001 __ j(zero, &no_arguments, Label::kNear);
1985 __ movp(rbx, args.GetArgumentOperand(1)); 2002 __ movp(rbx, args.GetArgumentOperand(1));
1986 __ jmp(&done, Label::kNear); 2003 __ jmp(&done, Label::kNear);
1987 __ bind(&no_arguments); 2004 __ bind(&no_arguments);
1988 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); 2005 __ LoadRoot(rbx, Heap::kempty_stringRootIndex);
1989 __ bind(&done); 2006 __ bind(&done);
1990 __ PopReturnAddressTo(rcx);
1991 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
1992 __ PushReturnAddressFrom(rcx);
1993 } 2007 }
1994 2008
1995 // 3. Make sure rbx is a string. 2009 // 3. Make sure rbx is a string.
1996 { 2010 {
1997 Label convert, done_convert; 2011 Label convert, done_convert;
1998 __ JumpIfSmi(rbx, &convert, Label::kNear); 2012 __ JumpIfSmi(rbx, &convert, Label::kNear);
1999 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); 2013 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx);
2000 __ j(below, &done_convert); 2014 __ j(below, &done_convert);
2001 __ bind(&convert); 2015 __ bind(&convert);
2002 { 2016 {
2003 FrameScope scope(masm, StackFrame::INTERNAL); 2017 FrameScope scope(masm, StackFrame::MANUAL);
2004 ToStringStub stub(masm->isolate()); 2018 ToStringStub stub(masm->isolate());
2019 __ Integer32ToSmi(rax, rax);
2020 __ EnterBuiltinFrame(rsi, rdi, rax);
2005 __ Push(rdx); 2021 __ Push(rdx);
2006 __ Push(rdi);
2007 __ Move(rax, rbx); 2022 __ Move(rax, rbx);
2008 __ CallStub(&stub); 2023 __ CallStub(&stub);
2009 __ Move(rbx, rax); 2024 __ Move(rbx, rax);
2010 __ Pop(rdi);
2011 __ Pop(rdx); 2025 __ Pop(rdx);
2026 __ LeaveBuiltinFrame(rsi, rdi, rax);
2027 __ SmiToInteger32(rax, rax);
2012 } 2028 }
2013 __ bind(&done_convert); 2029 __ bind(&done_convert);
2030
2031 // Drop all arguments including the receiver.
2032 __ PopReturnAddressTo(rcx);
2033 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
2034 __ PushReturnAddressFrom(rcx);
2014 } 2035 }
2015 2036
2016 // 4. Check if new target and constructor differ. 2037 // 4. Check if new target and constructor differ.
2017 Label new_object; 2038 Label new_object;
2018 __ cmpp(rdx, rdi); 2039 __ cmpp(rdx, rdi);
2019 __ j(not_equal, &new_object); 2040 __ j(not_equal, &new_object);
2020 2041
2021 // 5. Allocate a JSValue wrapper for the string. 2042 // 5. Allocate a JSValue wrapper for the string.
2022 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); 2043 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object);
2023 __ Ret(); 2044 __ Ret();
2024 2045
2025 // 6. Fallback to the runtime to create new object. 2046 // 6. Fallback to the runtime to create new object.
2026 __ bind(&new_object); 2047 __ bind(&new_object);
2027 { 2048 {
2028 FrameScope scope(masm, StackFrame::INTERNAL); 2049 FrameScope scope(masm, StackFrame::INTERNAL);
2029 __ Push(rbx); // the first argument 2050 __ Push(rbx); // the first argument
jgruber 2016/07/04 13:25:44 As above.
Benedikt Meurer 2016/07/04 16:45:36 Yes, this is observable (thx to new.target...)
jgruber 2016/07/07 11:50:52 Done.
2030 FastNewObjectStub stub(masm->isolate()); 2051 FastNewObjectStub stub(masm->isolate());
2031 __ CallStub(&stub); 2052 __ CallStub(&stub);
2032 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); 2053 __ Pop(FieldOperand(rax, JSValue::kValueOffset));
2033 } 2054 }
2034 __ Ret(); 2055 __ Ret();
2035 } 2056 }
2036 2057
2037 2058
2038 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, 2059 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
2039 Label* stack_overflow) { 2060 Label* stack_overflow) {
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after
3084 __ ret(0); 3105 __ ret(0);
3085 } 3106 }
3086 3107
3087 3108
3088 #undef __ 3109 #undef __
3089 3110
3090 } // namespace internal 3111 } // namespace internal
3091 } // namespace v8 3112 } // namespace v8
3092 3113
3093 #endif // V8_TARGET_ARCH_X64 3114 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698