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