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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.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 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 Generate_ConstructHelper(masm); | 1433 Generate_ConstructHelper(masm); |
1434 } | 1434 } |
1435 | 1435 |
1436 | 1436 |
1437 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, | 1437 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, |
1438 Label* stack_overflow) { | 1438 Label* stack_overflow) { |
1439 // ----------- S t a t e ------------- | 1439 // ----------- S t a t e ------------- |
1440 // -- a0 : actual number of arguments | 1440 // -- a0 : actual number of arguments |
1441 // -- a1 : function (passed through to callee) | 1441 // -- a1 : function (passed through to callee) |
1442 // -- a2 : expected number of arguments | 1442 // -- a2 : expected number of arguments |
| 1443 // -- a3 : new target (passed through to callee) |
1443 // ----------------------------------- | 1444 // ----------------------------------- |
1444 // Check the stack for overflow. We are not trying to catch | 1445 // Check the stack for overflow. We are not trying to catch |
1445 // interruptions (e.g. debug break and preemption) here, so the "real stack | 1446 // interruptions (e.g. debug break and preemption) here, so the "real stack |
1446 // limit" is checked. | 1447 // limit" is checked. |
1447 __ LoadRoot(t1, Heap::kRealStackLimitRootIndex); | 1448 __ LoadRoot(t1, Heap::kRealStackLimitRootIndex); |
1448 // Make t1 the space we have left. The stack might already be overflowed | 1449 // Make t1 the space we have left. The stack might already be overflowed |
1449 // here which will cause t1 to become negative. | 1450 // here which will cause t1 to become negative. |
1450 __ subu(t1, sp, t1); | 1451 __ subu(t1, sp, t1); |
1451 // Check if the arguments will overflow the stack. | 1452 // Check if the arguments will overflow the stack. |
1452 __ sll(at, a2, kPointerSizeLog2); | 1453 __ sll(at, a2, kPointerSizeLog2); |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1722 } | 1723 } |
1723 } | 1724 } |
1724 | 1725 |
1725 | 1726 |
1726 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1727 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1727 // State setup as expected by MacroAssembler::InvokePrologue. | 1728 // State setup as expected by MacroAssembler::InvokePrologue. |
1728 // ----------- S t a t e ------------- | 1729 // ----------- S t a t e ------------- |
1729 // -- a0: actual arguments count | 1730 // -- a0: actual arguments count |
1730 // -- a1: function (passed through to callee) | 1731 // -- a1: function (passed through to callee) |
1731 // -- a2: expected arguments count | 1732 // -- a2: expected arguments count |
| 1733 // -- a3: new target (passed through to callee) |
1732 // ----------------------------------- | 1734 // ----------------------------------- |
1733 | 1735 |
1734 Label stack_overflow; | 1736 Label invoke, dont_adapt_arguments, stack_overflow; |
1735 ArgumentAdaptorStackCheck(masm, &stack_overflow); | |
1736 Label invoke, dont_adapt_arguments; | |
1737 | 1737 |
1738 Label enough, too_few; | 1738 Label enough, too_few; |
1739 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
1740 __ Branch(&dont_adapt_arguments, eq, | 1739 __ Branch(&dont_adapt_arguments, eq, |
1741 a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); | 1740 a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); |
1742 // We use Uless as the number of argument should always be greater than 0. | 1741 // We use Uless as the number of argument should always be greater than 0. |
1743 __ Branch(&too_few, Uless, a0, Operand(a2)); | 1742 __ Branch(&too_few, Uless, a0, Operand(a2)); |
1744 | 1743 |
1745 { // Enough parameters: actual >= expected. | 1744 { // Enough parameters: actual >= expected. |
1746 // a0: actual number of arguments as a smi | 1745 // a0: actual number of arguments as a smi |
1747 // a1: function | 1746 // a1: function |
1748 // a2: expected number of arguments | 1747 // a2: expected number of arguments |
1749 // a3: code entry to call | 1748 // a3: new target (passed through to callee) |
1750 __ bind(&enough); | 1749 __ bind(&enough); |
1751 EnterArgumentsAdaptorFrame(masm); | 1750 EnterArgumentsAdaptorFrame(masm); |
| 1751 ArgumentAdaptorStackCheck(masm, &stack_overflow); |
1752 | 1752 |
1753 // Calculate copy start address into a0 and copy end address into t1. | 1753 // Calculate copy start address into a0 and copy end address into t1. |
1754 __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); | 1754 __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); |
1755 __ Addu(a0, fp, a0); | 1755 __ Addu(a0, fp, a0); |
1756 // Adjust for return address and receiver. | 1756 // Adjust for return address and receiver. |
1757 __ Addu(a0, a0, Operand(2 * kPointerSize)); | 1757 __ Addu(a0, a0, Operand(2 * kPointerSize)); |
1758 // Compute copy end address. | 1758 // Compute copy end address. |
1759 __ sll(t1, a2, kPointerSizeLog2); | 1759 __ sll(t1, a2, kPointerSizeLog2); |
1760 __ subu(t1, a0, t1); | 1760 __ subu(t1, a0, t1); |
1761 | 1761 |
1762 // Copy the arguments (including the receiver) to the new stack frame. | 1762 // Copy the arguments (including the receiver) to the new stack frame. |
1763 // a0: copy start address | 1763 // a0: copy start address |
1764 // a1: function | 1764 // a1: function |
1765 // a2: expected number of arguments | 1765 // a2: expected number of arguments |
1766 // a3: code entry to call | 1766 // a3: new target (passed through to callee) |
1767 // t1: copy end address | 1767 // t1: copy end address |
1768 | 1768 |
1769 Label copy; | 1769 Label copy; |
1770 __ bind(©); | 1770 __ bind(©); |
1771 __ lw(t0, MemOperand(a0)); | 1771 __ lw(t0, MemOperand(a0)); |
1772 __ push(t0); | 1772 __ push(t0); |
1773 __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t1)); | 1773 __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t1)); |
1774 __ addiu(a0, a0, -kPointerSize); // In delay slot. | 1774 __ addiu(a0, a0, -kPointerSize); // In delay slot. |
1775 | 1775 |
1776 __ jmp(&invoke); | 1776 __ jmp(&invoke); |
(...skipping 16 matching lines...) Expand all Loading... |
1793 __ Branch(&no_strong_error, ge, a0, Operand(t2)); | 1793 __ Branch(&no_strong_error, ge, a0, Operand(t2)); |
1794 | 1794 |
1795 { | 1795 { |
1796 FrameScope frame(masm, StackFrame::MANUAL); | 1796 FrameScope frame(masm, StackFrame::MANUAL); |
1797 EnterArgumentsAdaptorFrame(masm); | 1797 EnterArgumentsAdaptorFrame(masm); |
1798 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); | 1798 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); |
1799 } | 1799 } |
1800 | 1800 |
1801 __ bind(&no_strong_error); | 1801 __ bind(&no_strong_error); |
1802 EnterArgumentsAdaptorFrame(masm); | 1802 EnterArgumentsAdaptorFrame(masm); |
| 1803 ArgumentAdaptorStackCheck(masm, &stack_overflow); |
1803 | 1804 |
1804 // Calculate copy start address into a0 and copy end address into t3. | 1805 // Calculate copy start address into a0 and copy end address into t3. |
1805 // a0: actual number of arguments as a smi | 1806 // a0: actual number of arguments as a smi |
1806 // a1: function | 1807 // a1: function |
1807 // a2: expected number of arguments | 1808 // a2: expected number of arguments |
1808 // a3: code entry to call | 1809 // a3: new target (passed through to callee) |
1809 __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); | 1810 __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); |
1810 __ Addu(a0, fp, a0); | 1811 __ Addu(a0, fp, a0); |
1811 // Adjust for return address and receiver. | 1812 // Adjust for return address and receiver. |
1812 __ Addu(a0, a0, Operand(2 * kPointerSize)); | 1813 __ Addu(a0, a0, Operand(2 * kPointerSize)); |
1813 // Compute copy end address. Also adjust for return address. | 1814 // Compute copy end address. Also adjust for return address. |
1814 __ Addu(t3, fp, kPointerSize); | 1815 __ Addu(t3, fp, kPointerSize); |
1815 | 1816 |
1816 // Copy the arguments (including the receiver) to the new stack frame. | 1817 // Copy the arguments (including the receiver) to the new stack frame. |
1817 // a0: copy start address | 1818 // a0: copy start address |
1818 // a1: function | 1819 // a1: function |
1819 // a2: expected number of arguments | 1820 // a2: expected number of arguments |
1820 // a3: code entry to call | 1821 // a3: new target (passed through to callee) |
1821 // t3: copy end address | 1822 // t3: copy end address |
1822 Label copy; | 1823 Label copy; |
1823 __ bind(©); | 1824 __ bind(©); |
1824 __ lw(t0, MemOperand(a0)); // Adjusted above for return addr and receiver. | 1825 __ lw(t0, MemOperand(a0)); // Adjusted above for return addr and receiver. |
1825 __ Subu(sp, sp, kPointerSize); | 1826 __ Subu(sp, sp, kPointerSize); |
1826 __ Subu(a0, a0, kPointerSize); | 1827 __ Subu(a0, a0, kPointerSize); |
1827 __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t3)); | 1828 __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t3)); |
1828 __ sw(t0, MemOperand(sp)); // In the delay slot. | 1829 __ sw(t0, MemOperand(sp)); // In the delay slot. |
1829 | 1830 |
1830 // Fill the remaining expected arguments with undefined. | 1831 // Fill the remaining expected arguments with undefined. |
1831 // a1: function | 1832 // a1: function |
1832 // a2: expected number of arguments | 1833 // a2: expected number of arguments |
1833 // a3: code entry to call | 1834 // a3: new target (passed through to callee) |
1834 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); | 1835 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); |
1835 __ sll(t2, a2, kPointerSizeLog2); | 1836 __ sll(t2, a2, kPointerSizeLog2); |
1836 __ Subu(t1, fp, Operand(t2)); | 1837 __ Subu(t1, fp, Operand(t2)); |
1837 // Adjust for frame. | 1838 // Adjust for frame. |
1838 __ Subu(t1, t1, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + | 1839 __ Subu(t1, t1, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + |
1839 2 * kPointerSize)); | 1840 2 * kPointerSize)); |
1840 | 1841 |
1841 Label fill; | 1842 Label fill; |
1842 __ bind(&fill); | 1843 __ bind(&fill); |
1843 __ Subu(sp, sp, kPointerSize); | 1844 __ Subu(sp, sp, kPointerSize); |
1844 __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(t1)); | 1845 __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(t1)); |
1845 __ sw(t0, MemOperand(sp)); | 1846 __ sw(t0, MemOperand(sp)); |
1846 } | 1847 } |
1847 | 1848 |
1848 // Call the entry point. | 1849 // Call the entry point. |
1849 __ bind(&invoke); | 1850 __ bind(&invoke); |
1850 __ mov(a0, a2); | 1851 __ mov(a0, a2); |
1851 // a0 : expected number of arguments | 1852 // a0 : expected number of arguments |
1852 // a1 : function (passed through to callee) | 1853 // a1 : function (passed through to callee) |
1853 __ Call(a3); | 1854 // a3 : new target (passed through to callee) |
| 1855 __ lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 1856 __ Call(t0); |
1854 | 1857 |
1855 // Store offset of return address for deoptimizer. | 1858 // Store offset of return address for deoptimizer. |
1856 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); | 1859 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); |
1857 | 1860 |
1858 // Exit frame and return. | 1861 // Exit frame and return. |
1859 LeaveArgumentsAdaptorFrame(masm); | 1862 LeaveArgumentsAdaptorFrame(masm); |
1860 __ Ret(); | 1863 __ Ret(); |
1861 | 1864 |
1862 | 1865 |
1863 // ------------------------------------------- | 1866 // ------------------------------------------- |
1864 // Don't adapt arguments. | 1867 // Don't adapt arguments. |
1865 // ------------------------------------------- | 1868 // ------------------------------------------- |
1866 __ bind(&dont_adapt_arguments); | 1869 __ bind(&dont_adapt_arguments); |
1867 __ Jump(a3); | 1870 __ lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 1871 __ Jump(t0); |
1868 | 1872 |
1869 __ bind(&stack_overflow); | 1873 __ bind(&stack_overflow); |
1870 { | 1874 { |
1871 FrameScope frame(masm, StackFrame::MANUAL); | 1875 FrameScope frame(masm, StackFrame::MANUAL); |
1872 EnterArgumentsAdaptorFrame(masm); | |
1873 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1876 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
1874 __ break_(0xCC); | 1877 __ break_(0xCC); |
1875 } | 1878 } |
1876 } | 1879 } |
1877 | 1880 |
1878 | 1881 |
1879 #undef __ | 1882 #undef __ |
1880 | 1883 |
1881 } // namespace internal | 1884 } // namespace internal |
1882 } // namespace v8 | 1885 } // namespace v8 |
1883 | 1886 |
1884 #endif // V8_TARGET_ARCH_MIPS | 1887 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |