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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 | 1741 |
1742 // Place the necessary arguments. | 1742 // Place the necessary arguments. |
1743 Mov(x0, num_arguments); | 1743 Mov(x0, num_arguments); |
1744 Mov(x1, ExternalReference(f, isolate())); | 1744 Mov(x1, ExternalReference(f, isolate())); |
1745 | 1745 |
1746 CEntryStub stub(isolate(), 1, save_doubles); | 1746 CEntryStub stub(isolate(), 1, save_doubles); |
1747 CallStub(&stub); | 1747 CallStub(&stub); |
1748 } | 1748 } |
1749 | 1749 |
1750 | 1750 |
1751 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | |
1752 return ref0.address() - ref1.address(); | |
1753 } | |
1754 | |
1755 | |
1756 void MacroAssembler::CallApiFunctionAndReturn( | |
1757 Register function_address, ExternalReference thunk_ref, int stack_space, | |
1758 MemOperand* stack_space_operand, int spill_offset, | |
1759 MemOperand return_value_operand, MemOperand* context_restore_operand) { | |
1760 ASM_LOCATION("CallApiFunctionAndReturn"); | |
1761 ExternalReference next_address = | |
1762 ExternalReference::handle_scope_next_address(isolate()); | |
1763 const int kNextOffset = 0; | |
1764 const int kLimitOffset = AddressOffset( | |
1765 ExternalReference::handle_scope_limit_address(isolate()), | |
1766 next_address); | |
1767 const int kLevelOffset = AddressOffset( | |
1768 ExternalReference::handle_scope_level_address(isolate()), | |
1769 next_address); | |
1770 | |
1771 DCHECK(function_address.is(x1) || function_address.is(x2)); | |
1772 | |
1773 Label profiler_disabled; | |
1774 Label end_profiler_check; | |
1775 Mov(x10, ExternalReference::is_profiling_address(isolate())); | |
1776 Ldrb(w10, MemOperand(x10)); | |
1777 Cbz(w10, &profiler_disabled); | |
1778 Mov(x3, thunk_ref); | |
1779 B(&end_profiler_check); | |
1780 | |
1781 Bind(&profiler_disabled); | |
1782 Mov(x3, function_address); | |
1783 Bind(&end_profiler_check); | |
1784 | |
1785 // Save the callee-save registers we are going to use. | |
1786 // TODO(all): Is this necessary? ARM doesn't do it. | |
1787 STATIC_ASSERT(kCallApiFunctionSpillSpace == 4); | |
1788 Poke(x19, (spill_offset + 0) * kXRegSize); | |
1789 Poke(x20, (spill_offset + 1) * kXRegSize); | |
1790 Poke(x21, (spill_offset + 2) * kXRegSize); | |
1791 Poke(x22, (spill_offset + 3) * kXRegSize); | |
1792 | |
1793 // Allocate HandleScope in callee-save registers. | |
1794 // We will need to restore the HandleScope after the call to the API function, | |
1795 // by allocating it in callee-save registers they will be preserved by C code. | |
1796 Register handle_scope_base = x22; | |
1797 Register next_address_reg = x19; | |
1798 Register limit_reg = x20; | |
1799 Register level_reg = w21; | |
1800 | |
1801 Mov(handle_scope_base, next_address); | |
1802 Ldr(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); | |
1803 Ldr(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); | |
1804 Ldr(level_reg, MemOperand(handle_scope_base, kLevelOffset)); | |
1805 Add(level_reg, level_reg, 1); | |
1806 Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); | |
1807 | |
1808 if (FLAG_log_timer_events) { | |
1809 FrameScope frame(this, StackFrame::MANUAL); | |
1810 PushSafepointRegisters(); | |
1811 Mov(x0, ExternalReference::isolate_address(isolate())); | |
1812 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); | |
1813 PopSafepointRegisters(); | |
1814 } | |
1815 | |
1816 // Native call returns to the DirectCEntry stub which redirects to the | |
1817 // return address pushed on stack (could have moved after GC). | |
1818 // DirectCEntry stub itself is generated early and never moves. | |
1819 DirectCEntryStub stub(isolate()); | |
1820 stub.GenerateCall(this, x3); | |
1821 | |
1822 if (FLAG_log_timer_events) { | |
1823 FrameScope frame(this, StackFrame::MANUAL); | |
1824 PushSafepointRegisters(); | |
1825 Mov(x0, ExternalReference::isolate_address(isolate())); | |
1826 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | |
1827 PopSafepointRegisters(); | |
1828 } | |
1829 | |
1830 Label promote_scheduled_exception; | |
1831 Label exception_handled; | |
1832 Label delete_allocated_handles; | |
1833 Label leave_exit_frame; | |
1834 Label return_value_loaded; | |
1835 | |
1836 // Load value from ReturnValue. | |
1837 Ldr(x0, return_value_operand); | |
1838 Bind(&return_value_loaded); | |
1839 // No more valid handles (the result handle was the last one). Restore | |
1840 // previous handle scope. | |
1841 Str(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); | |
1842 if (emit_debug_code()) { | |
1843 Ldr(w1, MemOperand(handle_scope_base, kLevelOffset)); | |
1844 Cmp(w1, level_reg); | |
1845 Check(eq, kUnexpectedLevelAfterReturnFromApiCall); | |
1846 } | |
1847 Sub(level_reg, level_reg, 1); | |
1848 Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); | |
1849 Ldr(x1, MemOperand(handle_scope_base, kLimitOffset)); | |
1850 Cmp(limit_reg, x1); | |
1851 B(ne, &delete_allocated_handles); | |
1852 | |
1853 Bind(&leave_exit_frame); | |
1854 // Restore callee-saved registers. | |
1855 Peek(x19, (spill_offset + 0) * kXRegSize); | |
1856 Peek(x20, (spill_offset + 1) * kXRegSize); | |
1857 Peek(x21, (spill_offset + 2) * kXRegSize); | |
1858 Peek(x22, (spill_offset + 3) * kXRegSize); | |
1859 | |
1860 // Check if the function scheduled an exception. | |
1861 Mov(x5, ExternalReference::scheduled_exception_address(isolate())); | |
1862 Ldr(x5, MemOperand(x5)); | |
1863 JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex, &promote_scheduled_exception); | |
1864 Bind(&exception_handled); | |
1865 | |
1866 bool restore_context = context_restore_operand != NULL; | |
1867 if (restore_context) { | |
1868 Ldr(cp, *context_restore_operand); | |
1869 } | |
1870 | |
1871 if (stack_space_operand != NULL) { | |
1872 Ldr(w2, *stack_space_operand); | |
1873 } | |
1874 | |
1875 LeaveExitFrame(false, x1, !restore_context); | |
1876 if (stack_space_operand != NULL) { | |
1877 Drop(x2, 1); | |
1878 } else { | |
1879 Drop(stack_space); | |
1880 } | |
1881 Ret(); | |
1882 | |
1883 Bind(&promote_scheduled_exception); | |
1884 { | |
1885 FrameScope frame(this, StackFrame::INTERNAL); | |
1886 CallExternalReference( | |
1887 ExternalReference( | |
1888 Runtime::kPromoteScheduledException, isolate()), 0); | |
1889 } | |
1890 B(&exception_handled); | |
1891 | |
1892 // HandleScope limit has changed. Delete allocated extensions. | |
1893 Bind(&delete_allocated_handles); | |
1894 Str(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); | |
1895 // Save the return value in a callee-save register. | |
1896 Register saved_result = x19; | |
1897 Mov(saved_result, x0); | |
1898 Mov(x0, ExternalReference::isolate_address(isolate())); | |
1899 CallCFunction( | |
1900 ExternalReference::delete_handle_scope_extensions(isolate()), 1); | |
1901 Mov(x0, saved_result); | |
1902 B(&leave_exit_frame); | |
1903 } | |
1904 | |
1905 | |
1906 void MacroAssembler::CallExternalReference(const ExternalReference& ext, | 1751 void MacroAssembler::CallExternalReference(const ExternalReference& ext, |
1907 int num_arguments) { | 1752 int num_arguments) { |
1908 Mov(x0, num_arguments); | 1753 Mov(x0, num_arguments); |
1909 Mov(x1, ext); | 1754 Mov(x1, ext); |
1910 | 1755 |
1911 CEntryStub stub(isolate(), 1); | 1756 CEntryStub stub(isolate(), 1); |
1912 CallStub(&stub); | 1757 CallStub(&stub); |
1913 } | 1758 } |
1914 | 1759 |
1915 | 1760 |
(...skipping 3482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5398 } | 5243 } |
5399 } | 5244 } |
5400 | 5245 |
5401 | 5246 |
5402 #undef __ | 5247 #undef __ |
5403 | 5248 |
5404 | 5249 |
5405 } } // namespace v8::internal | 5250 } } // namespace v8::internal |
5406 | 5251 |
5407 #endif // V8_TARGET_ARCH_ARM64 | 5252 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |