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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1673 __ Bind(&stepping); | 1673 __ Bind(&stepping); |
1674 __ EnterStubFrame(); | 1674 __ EnterStubFrame(); |
1675 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1675 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1676 __ LeaveFrame(); | 1676 __ LeaveFrame(); |
1677 __ jmp(&done_stepping, Assembler::kNearJump); | 1677 __ jmp(&done_stepping, Assembler::kNearJump); |
1678 } | 1678 } |
1679 | 1679 |
1680 | 1680 |
1681 // Used to check class and type arguments. Arguments passed on stack: | 1681 // Used to check class and type arguments. Arguments passed on stack: |
1682 // TOS + 0: return address. | 1682 // TOS + 0: return address. |
1683 // TOS + 1: instantiator type arguments (can be NULL). | 1683 // TOS + 1: function type arguments (only if n == 4, can be raw_null). |
1684 // TOS + 2: instance. | 1684 // TOS + 2: instantiator type arguments (only if n == 4, can be raw_null). |
1685 // TOS + 3: SubtypeTestCache. | 1685 // TOS + 3: instance. |
| 1686 // TOS + 4: SubtypeTestCache. |
1686 // Result in ECX: null -> not found, otherwise result (true or false). | 1687 // Result in ECX: null -> not found, otherwise result (true or false). |
1687 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1688 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
1688 ASSERT((1 <= n) && (n <= 3)); | 1689 ASSERT((n == 1) || (n == 2) || (n == 4)); |
1689 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; | 1690 const intptr_t kFunctionTypeArgumentsInBytes = 1 * kWordSize; |
1690 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; | 1691 const intptr_t kInstantiatorTypeArgumentsInBytes = 2 * kWordSize; |
1691 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; | 1692 const intptr_t kInstanceOffsetInBytes = 3 * kWordSize; |
| 1693 const intptr_t kCacheOffsetInBytes = 4 * kWordSize; |
1692 const Immediate& raw_null = | 1694 const Immediate& raw_null = |
1693 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1695 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1694 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes)); | 1696 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes)); |
1695 if (n > 1) { | 1697 if (n > 1) { |
1696 // Get instance type arguments. | |
1697 __ LoadClass(ECX, EAX, EBX); | 1698 __ LoadClass(ECX, EAX, EBX); |
1698 // Compute instance type arguments into EBX. | 1699 // Compute instance type arguments into EBX. |
1699 Label has_no_type_arguments; | 1700 Label has_no_type_arguments; |
1700 __ movl(EBX, raw_null); | 1701 __ movl(EBX, raw_null); |
1701 __ movl(EDI, | 1702 __ movl(EDI, |
1702 FieldAddress(ECX, | 1703 FieldAddress(ECX, |
1703 Class::type_arguments_field_offset_in_words_offset())); | 1704 Class::type_arguments_field_offset_in_words_offset())); |
1704 __ cmpl(EDI, Immediate(Class::kNoTypeArguments)); | 1705 __ cmpl(EDI, Immediate(Class::kNoTypeArguments)); |
1705 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); | 1706 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); |
1706 __ movl(EBX, FieldAddress(EAX, EDI, TIMES_4, 0)); | 1707 __ movl(EBX, FieldAddress(EAX, EDI, TIMES_4, 0)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 Address(EDX, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); | 1739 Address(EDX, kWordSize * SubtypeTestCache::kInstanceTypeArguments)); |
1739 __ cmpl(EDI, EBX); | 1740 __ cmpl(EDI, EBX); |
1740 if (n == 2) { | 1741 if (n == 2) { |
1741 __ j(EQUAL, &found, Assembler::kNearJump); | 1742 __ j(EQUAL, &found, Assembler::kNearJump); |
1742 } else { | 1743 } else { |
1743 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); | 1744 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); |
1744 __ movl(EDI, | 1745 __ movl(EDI, |
1745 Address(EDX, kWordSize * | 1746 Address(EDX, kWordSize * |
1746 SubtypeTestCache::kInstantiatorTypeArguments)); | 1747 SubtypeTestCache::kInstantiatorTypeArguments)); |
1747 __ cmpl(EDI, Address(ESP, kInstantiatorTypeArgumentsInBytes)); | 1748 __ cmpl(EDI, Address(ESP, kInstantiatorTypeArgumentsInBytes)); |
| 1749 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); |
| 1750 __ movl(EDI, Address(EDX, kWordSize * |
| 1751 SubtypeTestCache::kFunctionTypeArguments)); |
| 1752 __ cmpl(EDI, Address(ESP, kFunctionTypeArgumentsInBytes)); |
1748 __ j(EQUAL, &found, Assembler::kNearJump); | 1753 __ j(EQUAL, &found, Assembler::kNearJump); |
1749 } | 1754 } |
1750 } | 1755 } |
1751 __ Bind(&next_iteration); | 1756 __ Bind(&next_iteration); |
1752 __ addl(EDX, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength)); | 1757 __ addl(EDX, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength)); |
1753 __ jmp(&loop, Assembler::kNearJump); | 1758 __ jmp(&loop, Assembler::kNearJump); |
1754 // Fall through to not found. | 1759 // Fall through to not found. |
1755 __ Bind(¬_found); | 1760 __ Bind(¬_found); |
1756 __ movl(ECX, raw_null); | 1761 __ movl(ECX, raw_null); |
1757 __ ret(); | 1762 __ ret(); |
1758 | 1763 |
1759 __ Bind(&found); | 1764 __ Bind(&found); |
1760 __ movl(ECX, Address(EDX, kWordSize * SubtypeTestCache::kTestResult)); | 1765 __ movl(ECX, Address(EDX, kWordSize * SubtypeTestCache::kTestResult)); |
1761 __ ret(); | 1766 __ ret(); |
1762 } | 1767 } |
1763 | 1768 |
1764 | 1769 |
1765 // Used to check class and type arguments. Arguments passed on stack: | 1770 // Used to check class and type arguments. Arguments passed on stack: |
1766 // TOS + 0: return address. | 1771 // TOS + 0: return address. |
1767 // TOS + 1: instantiator type arguments or NULL. | 1772 // TOS + 1: raw_null. |
1768 // TOS + 2: instance. | 1773 // TOS + 2: raw_null. |
1769 // TOS + 3: cache array. | 1774 // TOS + 3: instance. |
| 1775 // TOS + 4: SubtypeTestCache. |
1770 // Result in ECX: null -> not found, otherwise result (true or false). | 1776 // Result in ECX: null -> not found, otherwise result (true or false). |
1771 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { | 1777 void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) { |
1772 GenerateSubtypeNTestCacheStub(assembler, 1); | 1778 GenerateSubtypeNTestCacheStub(assembler, 1); |
1773 } | 1779 } |
1774 | 1780 |
1775 | 1781 |
1776 // Used to check class and type arguments. Arguments passed on stack: | 1782 // Used to check class and type arguments. Arguments passed on stack: |
1777 // TOS + 0: return address. | 1783 // TOS + 0: return address. |
1778 // TOS + 1: instantiator type arguments or NULL. | 1784 // TOS + 1: raw_null. |
1779 // TOS + 2: instance. | 1785 // TOS + 2: raw_null. |
1780 // TOS + 3: cache array. | 1786 // TOS + 3: instance. |
| 1787 // TOS + 4: SubtypeTestCache. |
1781 // Result in ECX: null -> not found, otherwise result (true or false). | 1788 // Result in ECX: null -> not found, otherwise result (true or false). |
1782 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { | 1789 void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) { |
1783 GenerateSubtypeNTestCacheStub(assembler, 2); | 1790 GenerateSubtypeNTestCacheStub(assembler, 2); |
1784 } | 1791 } |
1785 | 1792 |
1786 | 1793 |
1787 // Used to check class and type arguments. Arguments passed on stack: | 1794 // Used to check class and type arguments. Arguments passed on stack: |
1788 // TOS + 0: return address. | 1795 // TOS + 0: return address. |
1789 // TOS + 1: instantiator type arguments. | 1796 // TOS + 1: function type arguments (can be raw_null). |
1790 // TOS + 2: instance. | 1797 // TOS + 2: instantiator type arguments (can be raw_null). |
1791 // TOS + 3: cache array. | 1798 // TOS + 3: instance. |
| 1799 // TOS + 4: SubtypeTestCache. |
1792 // Result in ECX: null -> not found, otherwise result (true or false). | 1800 // Result in ECX: null -> not found, otherwise result (true or false). |
1793 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { | 1801 void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) { |
1794 GenerateSubtypeNTestCacheStub(assembler, 3); | 1802 GenerateSubtypeNTestCacheStub(assembler, 4); |
1795 } | 1803 } |
1796 | 1804 |
1797 | 1805 |
1798 // Return the current stack pointer address, used to do stack alignment checks. | 1806 // Return the current stack pointer address, used to do stack alignment checks. |
1799 // TOS + 0: return address | 1807 // TOS + 0: return address |
1800 // Result in EAX. | 1808 // Result in EAX. |
1801 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { | 1809 void StubCode::GenerateGetStackPointerStub(Assembler* assembler) { |
1802 __ leal(EAX, Address(ESP, kWordSize)); | 1810 __ leal(EAX, Address(ESP, kWordSize)); |
1803 __ ret(); | 1811 __ ret(); |
1804 } | 1812 } |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2103 } | 2111 } |
2104 | 2112 |
2105 | 2113 |
2106 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2114 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
2107 __ int3(); | 2115 __ int3(); |
2108 } | 2116 } |
2109 | 2117 |
2110 } // namespace dart | 2118 } // namespace dart |
2111 | 2119 |
2112 #endif // defined TARGET_ARCH_IA32 | 2120 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |