| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1791 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { | 1791 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { |
| 1792 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1792 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
| 1793 } | 1793 } |
| 1794 | 1794 |
| 1795 | 1795 |
| 1796 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1796 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
| 1797 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1797 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
| 1798 } | 1798 } |
| 1799 | 1799 |
| 1800 | 1800 |
| 1801 // Intermediary stub between a static call and its target. ICData contains |
| 1802 // the target function and the call count. |
| 1803 // S5: ICData |
| 1804 void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1805 GenerateUsageCounterIncrement(assembler, T0); |
| 1806 __ TraceSimMsg("UnoptimizedStaticCallStub"); |
| 1807 #if defined(DEBUG) |
| 1808 { Label ok; |
| 1809 // Check that the IC data array has NumberOfArgumentsChecked() == 0. |
| 1810 // 'num_args_tested' is stored as an untagged int. |
| 1811 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset())); |
| 1812 __ beq(T0, ZR, &ok); |
| 1813 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1814 __ Bind(&ok); |
| 1815 } |
| 1816 #endif // DEBUG |
| 1817 |
| 1818 // S5: IC data object (preserved). |
| 1819 __ lw(T0, FieldAddress(S5, ICData::ic_data_offset())); |
| 1820 // T0: ic_data_array with entries: target functions and count. |
| 1821 __ AddImmediate(T0, Array::data_offset() - kHeapObjectTag); |
| 1822 // T0: points directly to the first ic data array element. |
| 1823 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| 1824 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
| 1825 |
| 1826 // Increment count for this call. |
| 1827 Label increment_done; |
| 1828 __ lw(T4, Address(T0, count_offset)); |
| 1829 __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6); |
| 1830 __ bgez(T5, &increment_done); // No overflow. |
| 1831 __ delay_slot()->sw(T4, Address(T0, count_offset)); |
| 1832 |
| 1833 __ LoadImmediate(T1, Smi::RawValue(Smi::kMaxValue)); |
| 1834 __ sw(T1, Address(T0, count_offset)); |
| 1835 |
| 1836 __ Bind(&increment_done); |
| 1837 |
| 1838 Label target_is_compiled; |
| 1839 // Get function and call it, if possible. |
| 1840 __ lw(T3, Address(T0, target_offset)); |
| 1841 __ lw(T4, FieldAddress(T3, Function::code_offset())); |
| 1842 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 1843 __ bne(T4, TMP, &target_is_compiled); |
| 1844 |
| 1845 __ EnterStubFrame(); |
| 1846 // Preserve target function and IC data object. |
| 1847 // Two preserved registers, one argument (function) => 3 slots. |
| 1848 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
| 1849 __ sw(S5, Address(SP, 2 * kWordSize)); // Preserve IC data. |
| 1850 __ sw(T3, Address(SP, 1 * kWordSize)); // Preserve function. |
| 1851 __ sw(T3, Address(SP, 0 * kWordSize)); // Function argument. |
| 1852 __ CallRuntime(kCompileFunctionRuntimeEntry); |
| 1853 __ lw(T3, Address(SP, 1 * kWordSize)); // Restore function. |
| 1854 __ lw(S5, Address(SP, 2 * kWordSize)); // Restore IC data. |
| 1855 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
| 1856 // T3: target function. |
| 1857 __ lw(T4, FieldAddress(T3, Function::code_offset())); |
| 1858 __ LeaveStubFrame(); |
| 1859 |
| 1860 __ Bind(&target_is_compiled); |
| 1861 // T4: target code. |
| 1862 __ lw(T3, FieldAddress(T4, Code::instructions_offset())); |
| 1863 __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag); |
| 1864 __ jr(T3); |
| 1865 // Load arguments descriptor into S4. |
| 1866 __ delay_slot()-> |
| 1867 lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
| 1868 } |
| 1869 |
| 1870 |
| 1801 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { | 1871 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { |
| 1802 __ Unimplemented("BreakpointRuntime stub"); | 1872 __ Unimplemented("BreakpointRuntime stub"); |
| 1803 } | 1873 } |
| 1804 | 1874 |
| 1805 | 1875 |
| 1806 // RA: return address (Dart code). | 1876 // RA: return address (Dart code). |
| 1807 // S4: Arguments descriptor array. | 1877 // S5: IC data (unoptimized static call). |
| 1808 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1878 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1809 __ TraceSimMsg("BreakpointStaticStub"); | 1879 __ TraceSimMsg("BreakpointStaticStub"); |
| 1810 // Create a stub frame as we are pushing some objects on the stack before | 1880 // Create a stub frame as we are pushing some objects on the stack before |
| 1811 // calling into the runtime. | 1881 // calling into the runtime. |
| 1812 __ EnterStubFrame(); | 1882 __ EnterStubFrame(); |
| 1813 // Preserve arguments descriptor and make room for result. | 1883 // Preserve arguments descriptor and make room for result. |
| 1814 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1884 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1815 __ sw(S4, Address(SP, 1 * kWordSize)); | 1885 __ sw(S5, Address(SP, 1 * kWordSize)); |
| 1816 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1886 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
| 1817 __ sw(TMP, Address(SP, 0 * kWordSize)); | 1887 __ sw(TMP, Address(SP, 0 * kWordSize)); |
| 1818 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1888 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1819 // Pop code object result and restore arguments descriptor. | 1889 // Pop code object result and restore arguments descriptor. |
| 1820 __ lw(T0, Address(SP, 0 * kWordSize)); | 1890 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 1821 __ lw(S4, Address(SP, 1 * kWordSize)); | 1891 __ lw(S5, Address(SP, 1 * kWordSize)); |
| 1822 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1892 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1823 __ LeaveStubFrame(); | 1893 __ LeaveStubFrame(); |
| 1824 | 1894 |
| 1825 // Now call the static function. The breakpoint handler function | 1895 // Now call the static function. The breakpoint handler function |
| 1826 // ensures that the call target is compiled. | 1896 // ensures that the call target is compiled. |
| 1827 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 1897 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
| 1828 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | 1898 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
| 1899 // Load arguments descriptor into S4. |
| 1900 __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset())); |
| 1829 __ jr(T0); | 1901 __ jr(T0); |
| 1830 } | 1902 } |
| 1831 | 1903 |
| 1832 | 1904 |
| 1833 // V0: return value. | 1905 // V0: return value. |
| 1834 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1906 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| 1835 __ TraceSimMsg("BreakpoingReturnStub"); | 1907 __ TraceSimMsg("BreakpoingReturnStub"); |
| 1836 // Create a stub frame as we are pushing some objects on the stack before | 1908 // Create a stub frame as we are pushing some objects on the stack before |
| 1837 // calling into the runtime. | 1909 // calling into the runtime. |
| 1838 __ EnterStubFrame(); | 1910 __ EnterStubFrame(); |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2245 __ lw(left, Address(SP, 1 * kWordSize)); | 2317 __ lw(left, Address(SP, 1 * kWordSize)); |
| 2246 __ lw(temp2, Address(SP, 2 * kWordSize)); | 2318 __ lw(temp2, Address(SP, 2 * kWordSize)); |
| 2247 __ lw(temp1, Address(SP, 3 * kWordSize)); | 2319 __ lw(temp1, Address(SP, 3 * kWordSize)); |
| 2248 __ Ret(); | 2320 __ Ret(); |
| 2249 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); | 2321 __ delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize)); |
| 2250 } | 2322 } |
| 2251 | 2323 |
| 2252 } // namespace dart | 2324 } // namespace dart |
| 2253 | 2325 |
| 2254 #endif // defined TARGET_ARCH_MIPS | 2326 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |