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

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

Issue 2132303002: X87: [builtins] Construct builtin frame in String/Number ctors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
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
« no previous file with comments | « no previous file | src/x87/macro-assembler-x87.h » ('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 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 Immediate(Smi::FromInt(field_index))); 1266 Immediate(Smi::FromInt(field_index)));
1267 __ CallCFunction( 1267 __ CallCFunction(
1268 ExternalReference::get_date_field_function(masm->isolate()), 2); 1268 ExternalReference::get_date_field_function(masm->isolate()), 2);
1269 } 1269 }
1270 __ ret(1 * kPointerSize); 1270 __ ret(1 * kPointerSize);
1271 1271
1272 // 3. Raise a TypeError if the receiver is not a date. 1272 // 3. Raise a TypeError if the receiver is not a date.
1273 __ bind(&receiver_not_date); 1273 __ bind(&receiver_not_date);
1274 { 1274 {
1275 FrameScope scope(masm, StackFrame::MANUAL); 1275 FrameScope scope(masm, StackFrame::MANUAL);
1276 __ Push(ebp); 1276 __ Move(ebx, Immediate(0));
1277 __ Move(ebp, esp); 1277 __ EnterBuiltinFrame(esi, edi, ebx);
1278 __ Push(esi);
1279 __ Push(edi);
1280 __ Push(Immediate(0));
1281 __ CallRuntime(Runtime::kThrowNotDateError); 1278 __ CallRuntime(Runtime::kThrowNotDateError);
1282 } 1279 }
1283 } 1280 }
1284 1281
1285 // static 1282 // static
1286 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { 1283 void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1287 // ----------- S t a t e ------------- 1284 // ----------- S t a t e -------------
1288 // -- eax : argc 1285 // -- eax : argc
1289 // -- esp[0] : return address 1286 // -- esp[0] : return address
1290 // -- esp[4] : argArray 1287 // -- esp[4] : argArray
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 // Load the double value of the parameter into stx_1, maybe converting the 1639 // Load the double value of the parameter into stx_1, maybe converting the
1643 // parameter to a number first using the ToNumber builtin if necessary. 1640 // parameter to a number first using the ToNumber builtin if necessary.
1644 Label convert, convert_smi, convert_number, done_convert; 1641 Label convert, convert_smi, convert_number, done_convert;
1645 __ bind(&convert); 1642 __ bind(&convert);
1646 __ JumpIfSmi(ebx, &convert_smi); 1643 __ JumpIfSmi(ebx, &convert_smi);
1647 __ JumpIfRoot(FieldOperand(ebx, HeapObject::kMapOffset), 1644 __ JumpIfRoot(FieldOperand(ebx, HeapObject::kMapOffset),
1648 Heap::kHeapNumberMapRootIndex, &convert_number); 1645 Heap::kHeapNumberMapRootIndex, &convert_number);
1649 { 1646 {
1650 // Parameter is not a Number, use the ToNumber builtin to convert it. 1647 // Parameter is not a Number, use the ToNumber builtin to convert it.
1651 FrameScope scope(masm, StackFrame::MANUAL); 1648 FrameScope scope(masm, StackFrame::MANUAL);
1652 __ Push(ebp);
1653 __ Move(ebp, esp);
1654 __ Push(esi);
1655 __ Push(edi);
1656 __ SmiTag(eax); 1649 __ SmiTag(eax);
1657 __ SmiTag(ecx); 1650 __ SmiTag(ecx);
1658 __ Push(eax); 1651 __ EnterBuiltinFrame(esi, edi, eax);
1659 __ Push(ecx); 1652 __ Push(ecx);
1660 __ Push(edx); 1653 __ Push(edx);
1661 __ mov(eax, ebx); 1654 __ mov(eax, ebx);
1662 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); 1655 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1663 __ mov(ebx, eax); 1656 __ mov(ebx, eax);
1664 __ Pop(edx); 1657 __ Pop(edx);
1665 __ Pop(ecx); 1658 __ Pop(ecx);
1666 __ Pop(eax); 1659 __ LeaveBuiltinFrame(esi, edi, eax);
1667 __ Pop(edi); 1660 __ SmiUntag(ecx);
1668 __ Pop(esi); 1661 __ SmiUntag(eax);
1669 { 1662 {
1670 // Restore the double accumulator value (stX_0). 1663 // Restore the double accumulator value (stX_0).
1671 Label restore_smi, done_restore; 1664 Label restore_smi, done_restore;
1672 __ JumpIfSmi(edx, &restore_smi, Label::kNear); 1665 __ JumpIfSmi(edx, &restore_smi, Label::kNear);
1673 __ fld_d(FieldOperand(edx, HeapNumber::kValueOffset)); 1666 __ fld_d(FieldOperand(edx, HeapNumber::kValueOffset));
1674 __ jmp(&done_restore, Label::kNear); 1667 __ jmp(&done_restore, Label::kNear);
1675 __ bind(&restore_smi); 1668 __ bind(&restore_smi);
1676 __ SmiUntag(edx); 1669 __ SmiUntag(edx);
1677 __ push(edx); 1670 __ push(edx);
1678 __ fild_s(Operand(esp, 0)); 1671 __ fild_s(Operand(esp, 0));
1679 __ pop(edx); 1672 __ pop(edx);
1680 __ SmiTag(edx); 1673 __ SmiTag(edx);
1681 __ bind(&done_restore); 1674 __ bind(&done_restore);
1682 } 1675 }
1683 __ SmiUntag(ecx);
1684 __ SmiUntag(eax);
1685 __ leave();
1686 } 1676 }
1687 __ jmp(&convert); 1677 __ jmp(&convert);
1688 __ bind(&convert_number); 1678 __ bind(&convert_number);
1689 // Load another value into stx_1 1679 // Load another value into stx_1
1690 __ fld_d(FieldOperand(ebx, HeapNumber::kValueOffset)); 1680 __ fld_d(FieldOperand(ebx, HeapNumber::kValueOffset));
1691 __ fxch(); 1681 __ fxch();
1692 __ jmp(&done_convert, Label::kNear); 1682 __ jmp(&done_convert, Label::kNear);
1693 __ bind(&convert_smi); 1683 __ bind(&convert_smi);
1694 __ SmiUntag(ebx); 1684 __ SmiUntag(ebx);
1695 __ push(ebx); 1685 __ push(ebx);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 __ PushReturnAddressFrom(ecx); 1737 __ PushReturnAddressFrom(ecx);
1748 __ mov(eax, edx); 1738 __ mov(eax, edx);
1749 __ Ret(); 1739 __ Ret();
1750 } 1740 }
1751 1741
1752 // static 1742 // static
1753 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { 1743 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
1754 // ----------- S t a t e ------------- 1744 // ----------- S t a t e -------------
1755 // -- eax : number of arguments 1745 // -- eax : number of arguments
1756 // -- edi : constructor function 1746 // -- edi : constructor function
1747 // -- esi : context
1757 // -- esp[0] : return address 1748 // -- esp[0] : return address
1758 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1749 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1759 // -- esp[(argc + 1) * 4] : receiver 1750 // -- esp[(argc + 1) * 4] : receiver
1760 // ----------------------------------- 1751 // -----------------------------------
1761 1752
1762 // 1. Load the first argument into eax and get rid of the rest (including the 1753 // 1. Load the first argument into ebx.
1763 // receiver).
1764 Label no_arguments; 1754 Label no_arguments;
1765 { 1755 {
1766 __ test(eax, eax); 1756 __ test(eax, eax);
1767 __ j(zero, &no_arguments, Label::kNear); 1757 __ j(zero, &no_arguments, Label::kNear);
1768 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); 1758 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1769 __ PopReturnAddressTo(ecx);
1770 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1771 __ PushReturnAddressFrom(ecx);
1772 __ mov(eax, ebx);
1773 } 1759 }
1774 1760
1775 // 2a. Convert the first argument to a number. 1761 // 2a. Convert the first argument to a number.
1776 __ Jump(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); 1762 {
1763 FrameScope scope(masm, StackFrame::MANUAL);
1764 __ SmiTag(eax);
1765 __ EnterBuiltinFrame(esi, edi, eax);
1766 __ mov(eax, ebx);
1767 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1768 __ LeaveBuiltinFrame(esi, edi, ebx); // Argc popped to ebx.
1769 __ SmiUntag(ebx);
1770 }
1771
1772 {
1773 // Drop all arguments including the receiver.
1774 __ PopReturnAddressTo(ecx);
1775 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
1776 __ PushReturnAddressFrom(ecx);
1777 __ Ret();
1778 }
1777 1779
1778 // 2b. No arguments, return +0 (already in eax). 1780 // 2b. No arguments, return +0 (already in eax).
1779 __ bind(&no_arguments); 1781 __ bind(&no_arguments);
1780 __ ret(1 * kPointerSize); 1782 __ ret(1 * kPointerSize);
1781 } 1783 }
1782 1784
1783 1785
1784 // static 1786 // static
1785 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) { 1787 void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
1786 // ----------- S t a t e ------------- 1788 // ----------- S t a t e -------------
1787 // -- eax : number of arguments 1789 // -- eax : number of arguments
1788 // -- edi : constructor function 1790 // -- edi : constructor function
1789 // -- edx : new target 1791 // -- edx : new target
1792 // -- esi : context
1790 // -- esp[0] : return address 1793 // -- esp[0] : return address
1791 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1794 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1792 // -- esp[(argc + 1) * 4] : receiver 1795 // -- esp[(argc + 1) * 4] : receiver
1793 // ----------------------------------- 1796 // -----------------------------------
1794 1797
1795 // 1. Make sure we operate in the context of the called function. 1798 // 1. Make sure we operate in the context of the called function.
1796 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 1799 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1797 1800
1798 // 2. Load the first argument into ebx and get rid of the rest (including the 1801 // Store argc in r8.
1799 // receiver). 1802 __ mov(ecx, eax);
1803 __ SmiTag(ecx);
1804
1805 // 2. Load the first argument into ebx.
1800 { 1806 {
1801 Label no_arguments, done; 1807 Label no_arguments, done;
1802 __ test(eax, eax); 1808 __ test(eax, eax);
1803 __ j(zero, &no_arguments, Label::kNear); 1809 __ j(zero, &no_arguments, Label::kNear);
1804 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); 1810 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0));
1805 __ jmp(&done, Label::kNear); 1811 __ jmp(&done, Label::kNear);
1806 __ bind(&no_arguments); 1812 __ bind(&no_arguments);
1807 __ Move(ebx, Smi::FromInt(0)); 1813 __ Move(ebx, Smi::FromInt(0));
1808 __ bind(&done); 1814 __ bind(&done);
1809 __ PopReturnAddressTo(ecx);
1810 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1811 __ PushReturnAddressFrom(ecx);
1812 } 1815 }
1813 1816
1814 // 3. Make sure ebx is a number. 1817 // 3. Make sure ebx is a number.
1815 { 1818 {
1816 Label done_convert; 1819 Label done_convert;
1817 __ JumpIfSmi(ebx, &done_convert); 1820 __ JumpIfSmi(ebx, &done_convert);
1818 __ CompareRoot(FieldOperand(ebx, HeapObject::kMapOffset), 1821 __ CompareRoot(FieldOperand(ebx, HeapObject::kMapOffset),
1819 Heap::kHeapNumberMapRootIndex); 1822 Heap::kHeapNumberMapRootIndex);
1820 __ j(equal, &done_convert); 1823 __ j(equal, &done_convert);
1821 { 1824 {
1822 FrameScope scope(masm, StackFrame::INTERNAL); 1825 FrameScope scope(masm, StackFrame::MANUAL);
1823 __ Push(edi); 1826 __ EnterBuiltinFrame(esi, edi, ecx);
1824 __ Push(edx); 1827 __ Push(edx);
1825 __ Move(eax, ebx); 1828 __ Move(eax, ebx);
1826 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET); 1829 __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
1827 __ Move(ebx, eax); 1830 __ Move(ebx, eax);
1828 __ Pop(edx); 1831 __ Pop(edx);
1829 __ Pop(edi); 1832 __ LeaveBuiltinFrame(esi, edi, ecx);
1830 } 1833 }
1831 __ bind(&done_convert); 1834 __ bind(&done_convert);
1832 } 1835 }
1833 1836
1834 // 4. Check if new target and constructor differ. 1837 // 4. Check if new target and constructor differ.
1835 Label new_object; 1838 Label drop_frame_and_ret, done_alloc, new_object;
1836 __ cmp(edx, edi); 1839 __ cmp(edx, edi);
1837 __ j(not_equal, &new_object); 1840 __ j(not_equal, &new_object);
1838 1841
1839 // 5. Allocate a JSValue wrapper for the number. 1842 // 5. Allocate a JSValue wrapper for the number.
1840 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); 1843 __ AllocateJSValue(eax, edi, ebx, esi, &done_alloc);
1841 __ Ret(); 1844 __ jmp(&drop_frame_and_ret);
1845
1846 __ bind(&done_alloc);
1847 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); // Restore esi.
1842 1848
1843 // 6. Fallback to the runtime to create new object. 1849 // 6. Fallback to the runtime to create new object.
1844 __ bind(&new_object); 1850 __ bind(&new_object);
1845 { 1851 {
1846 FrameScope scope(masm, StackFrame::INTERNAL); 1852 FrameScope scope(masm, StackFrame::MANUAL);
1853 __ EnterBuiltinFrame(esi, edi, ecx);
1847 __ Push(ebx); // the first argument 1854 __ Push(ebx); // the first argument
1848 FastNewObjectStub stub(masm->isolate()); 1855 FastNewObjectStub stub(masm->isolate());
1849 __ CallStub(&stub); 1856 __ CallStub(&stub);
1850 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); 1857 __ Pop(FieldOperand(eax, JSValue::kValueOffset));
1858 __ LeaveBuiltinFrame(esi, edi, ecx);
1851 } 1859 }
1852 __ Ret(); 1860
1861 __ bind(&drop_frame_and_ret);
1862 {
1863 // Drop all arguments including the receiver.
1864 __ PopReturnAddressTo(esi);
1865 __ SmiUntag(ecx);
1866 __ lea(esp, Operand(esp, ecx, times_pointer_size, kPointerSize));
1867 __ PushReturnAddressFrom(esi);
1868 __ Ret();
1869 }
1853 } 1870 }
1854 1871
1855 1872
1856 // static 1873 // static
1857 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { 1874 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
1858 // ----------- S t a t e ------------- 1875 // ----------- S t a t e -------------
1859 // -- eax : number of arguments 1876 // -- eax : number of arguments
1860 // -- edi : constructor function 1877 // -- edi : constructor function
1878 // -- esi : context
1861 // -- esp[0] : return address 1879 // -- esp[0] : return address
1862 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1880 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1863 // -- esp[(argc + 1) * 4] : receiver 1881 // -- esp[(argc + 1) * 4] : receiver
1864 // ----------------------------------- 1882 // -----------------------------------
1865 1883
1866 // 1. Load the first argument into eax and get rid of the rest (including the 1884 // 1. Load the first argument into eax.
1867 // receiver).
1868 Label no_arguments; 1885 Label no_arguments;
1869 { 1886 {
1887 __ mov(ebx, eax); // Store argc in ebx.
1870 __ test(eax, eax); 1888 __ test(eax, eax);
1871 __ j(zero, &no_arguments, Label::kNear); 1889 __ j(zero, &no_arguments, Label::kNear);
1872 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); 1890 __ mov(eax, Operand(esp, eax, times_pointer_size, 0));
1873 __ PopReturnAddressTo(ecx);
1874 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1875 __ PushReturnAddressFrom(ecx);
1876 __ mov(eax, ebx);
1877 } 1891 }
1878 1892
1879 // 2a. At least one argument, return eax if it's a string, otherwise 1893 // 2a. At least one argument, return eax if it's a string, otherwise
1880 // dispatch to appropriate conversion. 1894 // dispatch to appropriate conversion.
1881 Label to_string, symbol_descriptive_string; 1895 Label drop_frame_and_ret, to_string, symbol_descriptive_string;
1882 { 1896 {
1883 __ JumpIfSmi(eax, &to_string, Label::kNear); 1897 __ JumpIfSmi(eax, &to_string, Label::kNear);
1884 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE); 1898 STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
1885 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); 1899 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx);
1886 __ j(above, &to_string, Label::kNear); 1900 __ j(above, &to_string, Label::kNear);
1887 __ j(equal, &symbol_descriptive_string, Label::kNear); 1901 __ j(equal, &symbol_descriptive_string, Label::kNear);
1888 __ Ret(); 1902 __ jmp(&drop_frame_and_ret, Label::kNear);
1889 } 1903 }
1890 1904
1891 // 2b. No arguments, return the empty string (and pop the receiver). 1905 // 2b. No arguments, return the empty string (and pop the receiver).
1892 __ bind(&no_arguments); 1906 __ bind(&no_arguments);
1893 { 1907 {
1894 __ LoadRoot(eax, Heap::kempty_stringRootIndex); 1908 __ LoadRoot(eax, Heap::kempty_stringRootIndex);
1895 __ ret(1 * kPointerSize); 1909 __ ret(1 * kPointerSize);
1896 } 1910 }
1897 1911
1898 // 3a. Convert eax to a string. 1912 // 3a. Convert eax to a string.
1899 __ bind(&to_string); 1913 __ bind(&to_string);
1900 { 1914 {
1915 FrameScope scope(masm, StackFrame::MANUAL);
1901 ToStringStub stub(masm->isolate()); 1916 ToStringStub stub(masm->isolate());
1902 __ TailCallStub(&stub); 1917 __ SmiTag(ebx);
1918 __ EnterBuiltinFrame(esi, edi, ebx);
1919 __ CallStub(&stub);
1920 __ LeaveBuiltinFrame(esi, edi, ebx);
1921 __ SmiUntag(ebx);
1903 } 1922 }
1923 __ jmp(&drop_frame_and_ret, Label::kNear);
1904 1924
1905 // 3b. Convert symbol in eax to a string. 1925 // 3b. Convert symbol in eax to a string.
1906 __ bind(&symbol_descriptive_string); 1926 __ bind(&symbol_descriptive_string);
1907 { 1927 {
1908 __ PopReturnAddressTo(ecx); 1928 __ PopReturnAddressTo(ecx);
1929 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
1909 __ Push(eax); 1930 __ Push(eax);
1910 __ PushReturnAddressFrom(ecx); 1931 __ PushReturnAddressFrom(ecx);
1911 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); 1932 __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
1912 } 1933 }
1934
1935 __ bind(&drop_frame_and_ret);
1936 {
1937 // Drop all arguments including the receiver.
1938 __ PopReturnAddressTo(ecx);
1939 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
1940 __ PushReturnAddressFrom(ecx);
1941 __ Ret();
1942 }
1913 } 1943 }
1914 1944
1915 1945
1916 // static 1946 // static
1917 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { 1947 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
1918 // ----------- S t a t e ------------- 1948 // ----------- S t a t e -------------
1919 // -- eax : number of arguments 1949 // -- eax : number of arguments
1920 // -- edi : constructor function 1950 // -- edi : constructor function
1921 // -- edx : new target 1951 // -- edx : new target
1952 // -- esi : context
1922 // -- esp[0] : return address 1953 // -- esp[0] : return address
1923 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1954 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1924 // -- esp[(argc + 1) * 4] : receiver 1955 // -- esp[(argc + 1) * 4] : receiver
1925 // ----------------------------------- 1956 // -----------------------------------
1926 1957
1927 // 1. Make sure we operate in the context of the called function. 1958 // 1. Make sure we operate in the context of the called function.
1928 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 1959 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1929 1960
1930 // 2. Load the first argument into ebx and get rid of the rest (including the 1961 __ mov(ebx, eax);
1931 // receiver). 1962
1963 // 2. Load the first argument into eax.
1932 { 1964 {
1933 Label no_arguments, done; 1965 Label no_arguments, done;
1934 __ test(eax, eax); 1966 __ test(ebx, ebx);
1935 __ j(zero, &no_arguments, Label::kNear); 1967 __ j(zero, &no_arguments, Label::kNear);
1936 __ mov(ebx, Operand(esp, eax, times_pointer_size, 0)); 1968 __ mov(eax, Operand(esp, ebx, times_pointer_size, 0));
1937 __ jmp(&done, Label::kNear); 1969 __ jmp(&done, Label::kNear);
1938 __ bind(&no_arguments); 1970 __ bind(&no_arguments);
1939 __ LoadRoot(ebx, Heap::kempty_stringRootIndex); 1971 __ LoadRoot(eax, Heap::kempty_stringRootIndex);
1940 __ bind(&done); 1972 __ bind(&done);
1941 __ PopReturnAddressTo(ecx);
1942 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1943 __ PushReturnAddressFrom(ecx);
1944 } 1973 }
1945 1974
1946 // 3. Make sure ebx is a string. 1975 // 3. Make sure eax is a string.
1947 { 1976 {
1948 Label convert, done_convert; 1977 Label convert, done_convert;
1949 __ JumpIfSmi(ebx, &convert, Label::kNear); 1978 __ JumpIfSmi(eax, &convert, Label::kNear);
1950 __ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, ecx); 1979 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
1951 __ j(below, &done_convert); 1980 __ j(below, &done_convert);
1952 __ bind(&convert); 1981 __ bind(&convert);
1953 { 1982 {
1954 FrameScope scope(masm, StackFrame::INTERNAL); 1983 FrameScope scope(masm, StackFrame::MANUAL);
1955 ToStringStub stub(masm->isolate()); 1984 ToStringStub stub(masm->isolate());
1956 __ Push(edi); 1985 __ SmiTag(ebx);
1986 __ EnterBuiltinFrame(esi, edi, ebx);
1957 __ Push(edx); 1987 __ Push(edx);
1958 __ Move(eax, ebx);
1959 __ CallStub(&stub); 1988 __ CallStub(&stub);
1960 __ Move(ebx, eax);
1961 __ Pop(edx); 1989 __ Pop(edx);
1962 __ Pop(edi); 1990 __ LeaveBuiltinFrame(esi, edi, ebx);
1991 __ SmiUntag(ebx);
1963 } 1992 }
1964 __ bind(&done_convert); 1993 __ bind(&done_convert);
1965 } 1994 }
1966 1995
1967 // 4. Check if new target and constructor differ. 1996 // 4. Check if new target and constructor differ.
1968 Label new_object; 1997 Label drop_frame_and_ret, done_alloc, new_object;
1969 __ cmp(edx, edi); 1998 __ cmp(edx, edi);
1970 __ j(not_equal, &new_object); 1999 __ j(not_equal, &new_object);
1971 2000
1972 // 5. Allocate a JSValue wrapper for the string. 2001 // 5. Allocate a JSValue wrapper for the string.
1973 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); 2002 // AllocateJSValue can't handle src == dst register. Reuse esi and restore it
1974 __ Ret(); 2003 // as needed after the call.
2004 __ mov(esi, eax);
2005 __ AllocateJSValue(eax, edi, esi, ecx, &done_alloc);
2006 __ jmp(&drop_frame_and_ret);
2007
2008 __ bind(&done_alloc);
2009 {
2010 // Restore eax to the first argument and esi to the context.
2011 __ mov(eax, esi);
2012 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2013 }
1975 2014
1976 // 6. Fallback to the runtime to create new object. 2015 // 6. Fallback to the runtime to create new object.
1977 __ bind(&new_object); 2016 __ bind(&new_object);
1978 { 2017 {
1979 FrameScope scope(masm, StackFrame::INTERNAL); 2018 FrameScope scope(masm, StackFrame::MANUAL);
1980 __ Push(ebx); // the first argument 2019 __ SmiTag(ebx);
2020 __ EnterBuiltinFrame(esi, edi, ebx);
2021 __ Push(eax); // the first argument
1981 FastNewObjectStub stub(masm->isolate()); 2022 FastNewObjectStub stub(masm->isolate());
1982 __ CallStub(&stub); 2023 __ CallStub(&stub);
1983 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); 2024 __ Pop(FieldOperand(eax, JSValue::kValueOffset));
2025 __ LeaveBuiltinFrame(esi, edi, ebx);
2026 __ SmiUntag(ebx);
1984 } 2027 }
1985 __ Ret(); 2028
2029 __ bind(&drop_frame_and_ret);
2030 {
2031 // Drop all arguments including the receiver.
2032 __ PopReturnAddressTo(ecx);
2033 __ lea(esp, Operand(esp, ebx, times_pointer_size, kPointerSize));
2034 __ PushReturnAddressFrom(ecx);
2035 __ Ret();
2036 }
1986 } 2037 }
1987 2038
1988 2039
1989 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, 2040 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
1990 Label* stack_overflow) { 2041 Label* stack_overflow) {
1991 // ----------- S t a t e ------------- 2042 // ----------- S t a t e -------------
1992 // -- eax : actual number of arguments 2043 // -- eax : actual number of arguments
1993 // -- ebx : expected number of arguments 2044 // -- ebx : expected number of arguments
1994 // -- edx : new target (passed through to callee) 2045 // -- edx : new target (passed through to callee)
1995 // ----------------------------------- 2046 // -----------------------------------
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 // And "return" to the OSR entry point of the function. 3100 // And "return" to the OSR entry point of the function.
3050 __ ret(0); 3101 __ ret(0);
3051 } 3102 }
3052 3103
3053 3104
3054 #undef __ 3105 #undef __
3055 } // namespace internal 3106 } // namespace internal
3056 } // namespace v8 3107 } // namespace v8
3057 3108
3058 #endif // V8_TARGET_ARCH_X87 3109 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | src/x87/macro-assembler-x87.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698