OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 Generate_ConstructHelper(masm); | 1420 Generate_ConstructHelper(masm); |
1421 } | 1421 } |
1422 | 1422 |
1423 | 1423 |
1424 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, | 1424 static void ArgumentAdaptorStackCheck(MacroAssembler* masm, |
1425 Label* stack_overflow) { | 1425 Label* stack_overflow) { |
1426 // ----------- S t a t e ------------- | 1426 // ----------- S t a t e ------------- |
1427 // -- x0 : actual number of arguments | 1427 // -- x0 : actual number of arguments |
1428 // -- x1 : function (passed through to callee) | 1428 // -- x1 : function (passed through to callee) |
1429 // -- x2 : expected number of arguments | 1429 // -- x2 : expected number of arguments |
| 1430 // -- x3 : new target (passed through to callee) |
1430 // ----------------------------------- | 1431 // ----------------------------------- |
1431 // Check the stack for overflow. | 1432 // Check the stack for overflow. |
1432 // We are not trying to catch interruptions (e.g. debug break and | 1433 // We are not trying to catch interruptions (e.g. debug break and |
1433 // preemption) here, so the "real stack limit" is checked. | 1434 // preemption) here, so the "real stack limit" is checked. |
1434 Label enough_stack_space; | 1435 Label enough_stack_space; |
1435 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); | 1436 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); |
1436 // Make x10 the space we have left. The stack might already be overflowed | 1437 // Make x10 the space we have left. The stack might already be overflowed |
1437 // here which will cause x10 to become negative. | 1438 // here which will cause x10 to become negative. |
1438 __ Sub(x10, jssp, x10); | 1439 __ Sub(x10, jssp, x10); |
1439 // Check if the arguments will overflow the stack. | 1440 // Check if the arguments will overflow the stack. |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1770 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL); | 1771 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CONSTRUCT_CALL); |
1771 } | 1772 } |
1772 | 1773 |
1773 | 1774 |
1774 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1775 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1775 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); | 1776 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); |
1776 // ----------- S t a t e ------------- | 1777 // ----------- S t a t e ------------- |
1777 // -- x0 : actual number of arguments | 1778 // -- x0 : actual number of arguments |
1778 // -- x1 : function (passed through to callee) | 1779 // -- x1 : function (passed through to callee) |
1779 // -- x2 : expected number of arguments | 1780 // -- x2 : expected number of arguments |
| 1781 // -- x3 : new target (passed through to callee) |
1780 // ----------------------------------- | 1782 // ----------------------------------- |
1781 | 1783 |
1782 Label stack_overflow; | |
1783 ArgumentAdaptorStackCheck(masm, &stack_overflow); | |
1784 | |
1785 Register argc_actual = x0; // Excluding the receiver. | 1784 Register argc_actual = x0; // Excluding the receiver. |
1786 Register argc_expected = x2; // Excluding the receiver. | 1785 Register argc_expected = x2; // Excluding the receiver. |
1787 Register function = x1; | 1786 Register function = x1; |
1788 Register code_entry = x3; | 1787 Register code_entry = x10; |
1789 | 1788 |
1790 Label invoke, dont_adapt_arguments; | 1789 Label invoke, dont_adapt_arguments, stack_overflow; |
1791 | 1790 |
1792 Label enough, too_few; | 1791 Label enough, too_few; |
1793 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | |
1794 __ Cmp(argc_actual, argc_expected); | 1792 __ Cmp(argc_actual, argc_expected); |
1795 __ B(lt, &too_few); | 1793 __ B(lt, &too_few); |
1796 __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1794 __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1797 __ B(eq, &dont_adapt_arguments); | 1795 __ B(eq, &dont_adapt_arguments); |
1798 | 1796 |
1799 { // Enough parameters: actual >= expected | 1797 { // Enough parameters: actual >= expected |
1800 EnterArgumentsAdaptorFrame(masm); | 1798 EnterArgumentsAdaptorFrame(masm); |
| 1799 ArgumentAdaptorStackCheck(masm, &stack_overflow); |
1801 | 1800 |
1802 Register copy_start = x10; | 1801 Register copy_start = x10; |
1803 Register copy_end = x11; | 1802 Register copy_end = x11; |
1804 Register copy_to = x12; | 1803 Register copy_to = x12; |
1805 Register scratch1 = x13, scratch2 = x14; | 1804 Register scratch1 = x13, scratch2 = x14; |
1806 | 1805 |
1807 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); | 1806 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); |
1808 | 1807 |
1809 // Adjust for fp, lr, and the receiver. | 1808 // Adjust for fp, lr, and the receiver. |
1810 __ Add(copy_start, fp, 3 * kPointerSize); | 1809 __ Add(copy_start, fp, 3 * kPointerSize); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 __ B(ge, &no_strong_error); | 1860 __ B(ge, &no_strong_error); |
1862 | 1861 |
1863 { | 1862 { |
1864 FrameScope frame(masm, StackFrame::MANUAL); | 1863 FrameScope frame(masm, StackFrame::MANUAL); |
1865 EnterArgumentsAdaptorFrame(masm); | 1864 EnterArgumentsAdaptorFrame(masm); |
1866 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); | 1865 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); |
1867 } | 1866 } |
1868 | 1867 |
1869 __ Bind(&no_strong_error); | 1868 __ Bind(&no_strong_error); |
1870 EnterArgumentsAdaptorFrame(masm); | 1869 EnterArgumentsAdaptorFrame(masm); |
| 1870 ArgumentAdaptorStackCheck(masm, &stack_overflow); |
1871 | 1871 |
1872 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); | 1872 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); |
1873 __ Lsl(argc_actual, argc_actual, kPointerSizeLog2); | 1873 __ Lsl(argc_actual, argc_actual, kPointerSizeLog2); |
1874 | 1874 |
1875 // Adjust for fp, lr, and the receiver. | 1875 // Adjust for fp, lr, and the receiver. |
1876 __ Add(copy_from, fp, 3 * kPointerSize); | 1876 __ Add(copy_from, fp, 3 * kPointerSize); |
1877 __ Add(copy_from, copy_from, argc_actual); | 1877 __ Add(copy_from, copy_from, argc_actual); |
1878 __ Mov(copy_to, jssp); | 1878 __ Mov(copy_to, jssp); |
1879 __ Sub(copy_end, copy_to, 1 * kPointerSize); // Adjust for the receiver. | 1879 __ Sub(copy_end, copy_to, 1 * kPointerSize); // Adjust for the receiver. |
1880 __ Sub(copy_end, copy_end, argc_actual); | 1880 __ Sub(copy_end, copy_end, argc_actual); |
(...skipping 29 matching lines...) Expand all Loading... |
1910 | 1910 |
1911 // Correct the space allocated for the extra slot. | 1911 // Correct the space allocated for the extra slot. |
1912 __ Drop(1); | 1912 __ Drop(1); |
1913 } | 1913 } |
1914 | 1914 |
1915 // Arguments have been adapted. Now call the entry point. | 1915 // Arguments have been adapted. Now call the entry point. |
1916 __ Bind(&invoke); | 1916 __ Bind(&invoke); |
1917 __ Mov(argc_actual, argc_expected); | 1917 __ Mov(argc_actual, argc_expected); |
1918 // x0 : expected number of arguments | 1918 // x0 : expected number of arguments |
1919 // x1 : function (passed through to callee) | 1919 // x1 : function (passed through to callee) |
| 1920 // x3 : new target (passed through to callee) |
| 1921 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
1920 __ Call(code_entry); | 1922 __ Call(code_entry); |
1921 | 1923 |
1922 // Store offset of return address for deoptimizer. | 1924 // Store offset of return address for deoptimizer. |
1923 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); | 1925 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); |
1924 | 1926 |
1925 // Exit frame and return. | 1927 // Exit frame and return. |
1926 LeaveArgumentsAdaptorFrame(masm); | 1928 LeaveArgumentsAdaptorFrame(masm); |
1927 __ Ret(); | 1929 __ Ret(); |
1928 | 1930 |
1929 // Call the entry point without adapting the arguments. | 1931 // Call the entry point without adapting the arguments. |
1930 __ Bind(&dont_adapt_arguments); | 1932 __ Bind(&dont_adapt_arguments); |
| 1933 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
1931 __ Jump(code_entry); | 1934 __ Jump(code_entry); |
1932 | 1935 |
1933 __ Bind(&stack_overflow); | 1936 __ Bind(&stack_overflow); |
1934 { | 1937 { |
1935 FrameScope frame(masm, StackFrame::MANUAL); | 1938 FrameScope frame(masm, StackFrame::MANUAL); |
1936 EnterArgumentsAdaptorFrame(masm); | |
1937 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1939 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
1938 __ Unreachable(); | 1940 __ Unreachable(); |
1939 } | 1941 } |
1940 } | 1942 } |
1941 | 1943 |
1942 | 1944 |
1943 #undef __ | 1945 #undef __ |
1944 | 1946 |
1945 } // namespace internal | 1947 } // namespace internal |
1946 } // namespace v8 | 1948 } // namespace v8 |
1947 | 1949 |
1948 #endif // V8_TARGET_ARCH_ARM | 1950 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |