| 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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1747 __ EnterStubFrame(); | 1747 __ EnterStubFrame(); |
| 1748 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1748 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1749 __ LeaveStubFrame(); | 1749 __ LeaveStubFrame(); |
| 1750 __ b(&done_stepping); | 1750 __ b(&done_stepping); |
| 1751 } | 1751 } |
| 1752 | 1752 |
| 1753 | 1753 |
| 1754 // Used to check class and type arguments. Arguments passed in registers: | 1754 // Used to check class and type arguments. Arguments passed in registers: |
| 1755 // LR: return address. | 1755 // LR: return address. |
| 1756 // R0: instance (must be preserved). | 1756 // R0: instance (must be preserved). |
| 1757 // R1: instantiator type arguments or NULL. | 1757 // R1: instantiator type arguments (only if n == 4, can be raw_null). |
| 1758 // R2: cache array. | 1758 // R2: function type arguments (only if n == 4, can be raw_null). |
| 1759 // R3: SubtypeTestCache. |
| 1759 // Result in R1: null -> not found, otherwise result (true or false). | 1760 // Result in R1: null -> not found, otherwise result (true or false). |
| 1760 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1761 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
| 1761 ASSERT((1 <= n) && (n <= 3)); | 1762 ASSERT((n == 1) || (n == 2) || (n == 4)); |
| 1762 if (n > 1) { | 1763 if (n > 1) { |
| 1763 // Get instance type arguments. | 1764 __ LoadClass(R8, R0, R4); |
| 1764 __ LoadClass(R3, R0, R4); | |
| 1765 // Compute instance type arguments into R4. | 1765 // Compute instance type arguments into R4. |
| 1766 Label has_no_type_arguments; | 1766 Label has_no_type_arguments; |
| 1767 __ LoadObject(R4, Object::null_object()); | 1767 __ LoadObject(R4, Object::null_object()); |
| 1768 __ ldr(R9, FieldAddress( | 1768 __ ldr(R9, FieldAddress( |
| 1769 R3, Class::type_arguments_field_offset_in_words_offset())); | 1769 R8, Class::type_arguments_field_offset_in_words_offset())); |
| 1770 __ CompareImmediate(R9, Class::kNoTypeArguments); | 1770 __ CompareImmediate(R9, Class::kNoTypeArguments); |
| 1771 __ b(&has_no_type_arguments, EQ); | 1771 __ b(&has_no_type_arguments, EQ); |
| 1772 __ add(R9, R0, Operand(R9, LSL, 2)); | 1772 __ add(R9, R0, Operand(R9, LSL, 2)); |
| 1773 __ ldr(R4, FieldAddress(R9, 0)); | 1773 __ ldr(R4, FieldAddress(R9, 0)); |
| 1774 __ Bind(&has_no_type_arguments); | 1774 __ Bind(&has_no_type_arguments); |
| 1775 } | 1775 } |
| 1776 __ LoadClassId(R3, R0); | 1776 __ LoadClassId(R8, R0); |
| 1777 // R0: instance. | 1777 // R0: instance. |
| 1778 // R1: instantiator type arguments or NULL. | 1778 // R1: instantiator type arguments (only if n == 4, can be raw_null). |
| 1779 // R2: SubtypeTestCache. | 1779 // R2: function type arguments (only if n == 4, can be raw_null). |
| 1780 // R3: instance class id. | 1780 // R3: SubtypeTestCache. |
| 1781 // R8: instance class id. |
| 1781 // R4: instance type arguments (null if none), used only if n > 1. | 1782 // R4: instance type arguments (null if none), used only if n > 1. |
| 1782 __ ldr(R2, FieldAddress(R2, SubtypeTestCache::cache_offset())); | 1783 __ ldr(R3, FieldAddress(R3, SubtypeTestCache::cache_offset())); |
| 1783 __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag); | 1784 __ AddImmediate(R3, Array::data_offset() - kHeapObjectTag); |
| 1784 | 1785 |
| 1785 Label loop, found, not_found, next_iteration; | 1786 Label loop, found, not_found, next_iteration; |
| 1786 // R2: entry start. | 1787 // R3: entry start. |
| 1787 // R3: instance class id. | 1788 // R8: instance class id. |
| 1788 // R4: instance type arguments (still null if closure). | 1789 // R4: instance type arguments (still null if closure). |
| 1789 __ SmiTag(R3); | 1790 __ SmiTag(R8); |
| 1790 __ CompareImmediate(R3, Smi::RawValue(kClosureCid)); | 1791 __ CompareImmediate(R8, Smi::RawValue(kClosureCid)); |
| 1791 __ ldr(R4, FieldAddress(R0, Closure::instantiator_offset()), EQ); | 1792 __ ldr(R4, FieldAddress(R0, Closure::instantiator_offset()), EQ); |
| 1792 __ ldr(R3, FieldAddress(R0, Closure::function_offset()), EQ); | 1793 __ ldr(R8, FieldAddress(R0, Closure::function_offset()), EQ); |
| 1793 // R3: instance class id as Smi or function. | 1794 // R8: instance class id as Smi or function. |
| 1794 __ Bind(&loop); | 1795 __ Bind(&loop); |
| 1795 __ ldr(R9, | 1796 __ ldr(R9, |
| 1796 Address(R2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction)); | 1797 Address(R3, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction)); |
| 1797 __ CompareObject(R9, Object::null_object()); | 1798 __ CompareObject(R9, Object::null_object()); |
| 1798 __ b(¬_found, EQ); | 1799 __ b(¬_found, EQ); |
| 1799 __ cmp(R9, Operand(R3)); | 1800 __ cmp(R9, Operand(R8)); |
| 1800 if (n == 1) { | 1801 if (n == 1) { |
| 1801 __ b(&found, EQ); | 1802 __ b(&found, EQ); |
| 1802 } else { | 1803 } else { |
| 1803 __ b(&next_iteration, NE); | 1804 __ b(&next_iteration, NE); |
| 1804 __ ldr(R9, | 1805 __ ldr(R9, |
| 1805 Address(R2, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); | 1806 Address(R3, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); |
| 1806 __ cmp(R9, Operand(R4)); | 1807 __ cmp(R9, Operand(R4)); |
| 1807 if (n == 2) { | 1808 if (n == 2) { |
| 1808 __ b(&found, EQ); | 1809 __ b(&found, EQ); |
| 1809 } else { | 1810 } else { |
| 1810 __ b(&next_iteration, NE); | 1811 __ b(&next_iteration, NE); |
| 1811 __ ldr(R9, Address(R2, kWordSize * | 1812 __ ldr(R9, Address(R3, kWordSize * |
| 1812 SubtypeTestCache::kInstantiatorTypeArguments)); | 1813 SubtypeTestCache::kInstantiatorTypeArguments)); |
| 1813 __ cmp(R9, Operand(R1)); | 1814 __ cmp(R9, Operand(R1)); |
| 1815 __ b(&next_iteration, NE); |
| 1816 __ ldr(R9, |
| 1817 Address(R3, kWordSize * SubtypeTestCache::kFunctionTypeArguments)); |
| 1818 __ cmp(R9, Operand(R2)); |
| 1814 __ b(&found, EQ); | 1819 __ b(&found, EQ); |
| 1815 } | 1820 } |
| 1816 } | 1821 } |
| 1817 __ Bind(&next_iteration); | 1822 __ Bind(&next_iteration); |
| 1818 __ AddImmediate(R2, kWordSize * SubtypeTestCache::kTestEntryLength); | 1823 __ AddImmediate(R3, kWordSize * SubtypeTestCache::kTestEntryLength); |
| 1819 __ b(&loop); | 1824 __ b(&loop); |
| 1820 // Fall through to not found. | 1825 // Fall through to not found. |
| 1821 __ Bind(¬_found); | 1826 __ Bind(¬_found); |
| 1822 __ LoadObject(R1, Object::null_object()); | 1827 __ LoadObject(R1, Object::null_object()); |
| 1823 __ Ret(); | 1828 __ Ret(); |
| 1824 | 1829 |
| 1825 __ Bind(&found); | 1830 __ Bind(&found); |
| 1826 __ ldr(R1, Address(R2, kWordSize * SubtypeTestCache::kTestResult)); | 1831 __ ldr(R1, Address(R3, kWordSize * SubtypeTestCache::kTestResult)); |
| 1827 __ Ret(); | 1832 __ Ret(); |
| 1828 } | 1833 } |
| 1829 | 1834 |
| 1830 | 1835 |
| 1831 // Used to check class and type arguments. Arguments passed in registers: | 1836 // Used to check class and type arguments. Arguments passed in registers: |
| 1832 // LR: return address. | 1837 // LR: return address. |
| 1833 // R0: instance (must be preserved). | 1838 // R0: instance (must be preserved). |
| 1834 // R1: instantiator type arguments or NULL. | 1839 // R1: unused. |
| 1835 // R2: cache array. | 1840 // R2: unused. |
| 1841 // R3: SubtypeTestCache. |
| 1836 // Result in R1: null -> not found, otherwise result (true or false). | 1842 // Result in R1: null -> not found, otherwise result (true or false). |
| 1837 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { | 1843 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { |
| 1838 GenerateSubtypeNTestCacheStub(assembler, 1); | 1844 GenerateSubtypeNTestCacheStub(assembler, 1); |
| 1839 } | 1845 } |
| 1840 | 1846 |
| 1841 | 1847 |
| 1842 // Used to check class and type arguments. Arguments passed in registers: | 1848 // Used to check class and type arguments. Arguments passed in registers: |
| 1843 // LR: return address. | 1849 // LR: return address. |
| 1844 // R0: instance (must be preserved). | 1850 // R0: instance (must be preserved). |
| 1845 // R1: instantiator type arguments or NULL. | 1851 // R1: unused. |
| 1846 // R2: cache array. | 1852 // R2: unused. |
| 1853 // R3: SubtypeTestCache. |
| 1847 // Result in R1: null -> not found, otherwise result (true or false). | 1854 // Result in R1: null -> not found, otherwise result (true or false). |
| 1848 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { | 1855 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { |
| 1849 GenerateSubtypeNTestCacheStub(assembler, 2); | 1856 GenerateSubtypeNTestCacheStub(assembler, 2); |
| 1850 } | 1857 } |
| 1851 | 1858 |
| 1852 | 1859 |
| 1853 // Used to check class and type arguments. Arguments passed in registers: | 1860 // Used to check class and type arguments. Arguments passed in registers: |
| 1854 // LR: return address. | 1861 // LR: return address. |
| 1855 // R0: instance (must be preserved). | 1862 // R0: instance (must be preserved). |
| 1856 // R1: instantiator type arguments or NULL. | 1863 // R1: instantiator type arguments (can be raw_null). |
| 1857 // R2: cache array. | 1864 // R2: function type arguments (can be raw_null). |
| 1865 // R3: SubtypeTestCache. |
| 1858 // Result in R1: null -> not found, otherwise result (true or false). | 1866 // Result in R1: null -> not found, otherwise result (true or false). |
| 1859 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { | 1867 void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) { |
| 1860 GenerateSubtypeNTestCacheStub(assembler, 3); | 1868 GenerateSubtypeNTestCacheStub(assembler, 4); |
| 1861 } | 1869 } |
| 1862 | 1870 |
| 1863 | 1871 |
| 1864 // Return the current stack pointer address, used to do stack alignment checks. | 1872 // Return the current stack pointer address, used to do stack alignment checks. |
| 1865 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { | 1873 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { |
| 1866 __ mov(R0, Operand(SP)); | 1874 __ mov(R0, Operand(SP)); |
| 1867 __ Ret(); | 1875 __ Ret(); |
| 1868 } | 1876 } |
| 1869 | 1877 |
| 1870 | 1878 |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2301 } | 2309 } |
| 2302 | 2310 |
| 2303 | 2311 |
| 2304 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2312 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
| 2305 __ bkpt(0); | 2313 __ bkpt(0); |
| 2306 } | 2314 } |
| 2307 | 2315 |
| 2308 } // namespace dart | 2316 } // namespace dart |
| 2309 | 2317 |
| 2310 #endif // defined TARGET_ARCH_ARM | 2318 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |