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

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

Powered by Google App Engine
This is Rietveld 408576698