| 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" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 field_has_length || (field().guarded_cid() == kIllegalCid); | 1605 field_has_length || (field().guarded_cid() == kIllegalCid); |
| 1606 if (field_has_length) { | 1606 if (field_has_length) { |
| 1607 // Currently, we should only see final fields that remember length. | 1607 // Currently, we should only see final fields that remember length. |
| 1608 ASSERT(field().is_final()); | 1608 ASSERT(field().is_final()); |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 if (field_cid == kDynamicCid) { | 1611 if (field_cid == kDynamicCid) { |
| 1612 ASSERT(!compiler->is_optimizing()); | 1612 ASSERT(!compiler->is_optimizing()); |
| 1613 return; // Nothing to emit. | 1613 return; // Nothing to emit. |
| 1614 } | 1614 } |
| 1615 | |
| 1616 const intptr_t value_cid = value()->Type()->ToCid(); | 1615 const intptr_t value_cid = value()->Type()->ToCid(); |
| 1617 | 1616 |
| 1618 Register value_reg = locs()->in(0).reg(); | 1617 Register value_reg = locs()->in(0).reg(); |
| 1619 | 1618 |
| 1620 Register value_cid_reg = needs_value_temp_reg ? | 1619 Register value_cid_reg = needs_value_temp_reg ? |
| 1621 locs()->temp(0).reg() : kNoRegister; | 1620 locs()->temp(0).reg() : kNoRegister; |
| 1622 | 1621 |
| 1623 Register field_reg = needs_field_temp_reg ? | 1622 Register field_reg = needs_field_temp_reg ? |
| 1624 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; | 1623 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; |
| 1625 | 1624 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1651 field_reg, Field::guarded_list_length_offset()); | 1650 field_reg, Field::guarded_list_length_offset()); |
| 1652 | 1651 |
| 1653 if (value_cid == kDynamicCid) { | 1652 if (value_cid == kDynamicCid) { |
| 1654 if (value_cid_reg == kNoRegister) { | 1653 if (value_cid_reg == kNoRegister) { |
| 1655 ASSERT(!compiler->is_optimizing()); | 1654 ASSERT(!compiler->is_optimizing()); |
| 1656 value_cid_reg = EDX; | 1655 value_cid_reg = EDX; |
| 1657 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 1656 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); |
| 1658 } | 1657 } |
| 1659 | 1658 |
| 1660 LoadValueCid(compiler, value_cid_reg, value_reg); | 1659 LoadValueCid(compiler, value_cid_reg, value_reg); |
| 1661 | |
| 1662 Label skip_length_check; | 1660 Label skip_length_check; |
| 1663 __ cmpl(value_cid_reg, field_cid_operand); | 1661 __ cmpl(value_cid_reg, field_cid_operand); |
| 1664 // Value CID != Field guard CID, skip length check. | 1662 // Value CID != Field guard CID, skip length check. |
| 1665 __ j(NOT_EQUAL, &skip_length_check); | 1663 __ j(NOT_EQUAL, &skip_length_check); |
| 1666 if (field_has_length) { | 1664 if (field_has_length) { |
| 1667 // Field guard may have remembered list length, check it. | 1665 // Field guard may have remembered list length, check it. |
| 1668 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1666 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
| 1669 __ pushl(value_cid_reg); | 1667 __ pushl(value_cid_reg); |
| 1670 __ movl(value_cid_reg, | 1668 __ movl(value_cid_reg, |
| 1671 FieldAddress(value_reg, Array::length_offset())); | 1669 FieldAddress(value_reg, Array::length_offset())); |
| 1672 __ cmpl(value_cid_reg, Immediate(field_length)); | 1670 __ cmpl(value_cid_reg, Immediate(field_length)); |
| 1673 __ popl(value_cid_reg); | 1671 __ popl(value_cid_reg); |
| 1674 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1672 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| 1675 __ pushl(value_cid_reg); | 1673 __ pushl(value_cid_reg); |
| 1676 __ movl(value_cid_reg, | 1674 __ movl(value_cid_reg, |
| 1677 FieldAddress(value_reg, TypedData::length_offset())); | 1675 FieldAddress(value_reg, TypedData::length_offset())); |
| 1678 __ cmpl(value_cid_reg, Immediate(field_length)); | 1676 __ cmpl(value_cid_reg, Immediate(field_length)); |
| 1679 __ popl(value_cid_reg); | 1677 __ popl(value_cid_reg); |
| 1680 } else { | 1678 } else { |
| 1681 ASSERT(field_cid == kIllegalCid); | 1679 ASSERT(field_cid == kIllegalCid); |
| 1682 // Following jump cannot not occur, fall through. | 1680 Label check_array, local_exit, local_fail; |
| 1681 // Check field guard. |
| 1682 __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| 1683 __ j(EQUAL, &local_fail); |
| 1684 // Check for typed data array. |
| 1685 __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid)); |
| 1686 __ j(GREATER, &local_fail); // Not a typed array or a regular array. |
| 1687 __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| 1688 __ j(LESS, &check_array); // Could still be a regular array. |
| 1689 __ pushl(value_cid_reg); |
| 1690 __ movl(value_cid_reg, |
| 1691 FieldAddress(value_reg, TypedData::length_offset())); |
| 1692 __ cmpl(field_length_operand, value_cid_reg); |
| 1693 __ popl(value_cid_reg); |
| 1694 __ jmp(&local_exit); |
| 1695 // Check for regular array. |
| 1696 __ Bind(&check_array); |
| 1697 __ cmpl(value_cid_reg, Immediate(kImmutableArrayCid)); |
| 1698 __ j(GREATER, &local_fail); |
| 1699 __ cmpl(value_cid_reg, Immediate(kArrayCid)); |
| 1700 __ j(LESS, &local_fail); |
| 1701 __ pushl(value_cid_reg); |
| 1702 __ movl(value_cid_reg, |
| 1703 FieldAddress(value_reg, Array::length_offset())); |
| 1704 __ cmpl(field_length_operand, value_cid_reg); |
| 1705 __ popl(value_cid_reg); |
| 1706 __ jmp(&local_exit); |
| 1707 |
| 1708 __ Bind(&local_fail); |
| 1709 __ movl(field_length_operand, Immediate(Field::kNoFixedLength)); |
| 1710 |
| 1711 __ Bind(&local_exit); |
| 1683 } | 1712 } |
| 1684 __ j(NOT_EQUAL, fail); | 1713 __ j(NOT_EQUAL, fail); |
| 1685 } | 1714 } |
| 1686 __ Bind(&skip_length_check); | 1715 __ Bind(&skip_length_check); |
| 1687 __ cmpl(value_cid_reg, field_nullability_operand); | 1716 __ cmpl(value_cid_reg, field_nullability_operand); |
| 1688 } else if (value_cid == kNullCid) { | 1717 } else if (value_cid == kNullCid) { |
| 1689 // Value in graph known to be null. | 1718 // Value in graph known to be null. |
| 1690 // Compare with null. | 1719 // Compare with null. |
| 1691 __ cmpl(field_nullability_operand, Immediate(value_cid)); | 1720 __ cmpl(field_nullability_operand, Immediate(value_cid)); |
| 1692 } else { | 1721 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1713 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1742 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| 1714 __ pushl(value_cid_reg); | 1743 __ pushl(value_cid_reg); |
| 1715 __ movl(value_cid_reg, | 1744 __ movl(value_cid_reg, |
| 1716 FieldAddress(value_reg, TypedData::length_offset())); | 1745 FieldAddress(value_reg, TypedData::length_offset())); |
| 1717 __ cmpl(value_cid_reg, Immediate(field_length)); | 1746 __ cmpl(value_cid_reg, Immediate(field_length)); |
| 1718 __ popl(value_cid_reg); | 1747 __ popl(value_cid_reg); |
| 1719 } else { | 1748 } else { |
| 1720 ASSERT(field_cid == kIllegalCid); | 1749 ASSERT(field_cid == kIllegalCid); |
| 1721 // Following jump cannot not occur, fall through. | 1750 // Following jump cannot not occur, fall through. |
| 1722 } | 1751 } |
| 1752 __ j(NOT_EQUAL, fail); |
| 1723 } | 1753 } |
| 1724 // Not identical, possibly null. | 1754 // Not identical, possibly null. |
| 1725 __ Bind(&skip_length_check); | 1755 __ Bind(&skip_length_check); |
| 1726 } | 1756 } |
| 1727 // Jump when class id guard and list length guard are okay. | 1757 // Jump when class id guard and list length guard are okay. |
| 1728 __ j(EQUAL, &ok); | 1758 __ j(EQUAL, &ok); |
| 1729 | 1759 |
| 1730 | |
| 1731 // Check if guard field is uninitialized. | 1760 // Check if guard field is uninitialized. |
| 1732 __ cmpl(field_cid_operand, Immediate(kIllegalCid)); | 1761 __ cmpl(field_cid_operand, Immediate(kIllegalCid)); |
| 1733 // Jump to failure path when guard field has been initialized and | 1762 // Jump to failure path when guard field has been initialized and |
| 1734 // the field and value class ids do not not match. | 1763 // the field and value class ids do not not match. |
| 1735 __ j(NOT_EQUAL, fail); | 1764 __ j(NOT_EQUAL, fail); |
| 1736 | 1765 |
| 1737 // At this point the field guard is being initialized for the first time. | 1766 // At this point the field guard is being initialized for the first time. |
| 1738 if (value_cid == kDynamicCid) { | 1767 if (value_cid == kDynamicCid) { |
| 1739 // Do not know value's class id. | 1768 // Do not know value's class id. |
| 1740 __ movl(field_cid_operand, value_cid_reg); | 1769 __ movl(field_cid_operand, value_cid_reg); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 } else { | 1802 } else { |
| 1774 if (value_cid_reg == kNoRegister) { | 1803 if (value_cid_reg == kNoRegister) { |
| 1775 ASSERT(!compiler->is_optimizing()); | 1804 ASSERT(!compiler->is_optimizing()); |
| 1776 value_cid_reg = EDX; | 1805 value_cid_reg = EDX; |
| 1777 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | 1806 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); |
| 1778 } | 1807 } |
| 1779 ASSERT(value_cid_reg != kNoRegister); | 1808 ASSERT(value_cid_reg != kNoRegister); |
| 1780 ASSERT(field_reg != kNoRegister); | 1809 ASSERT(field_reg != kNoRegister); |
| 1781 __ movl(field_cid_operand, Immediate(value_cid)); | 1810 __ movl(field_cid_operand, Immediate(value_cid)); |
| 1782 __ movl(field_nullability_operand, Immediate(value_cid)); | 1811 __ movl(field_nullability_operand, Immediate(value_cid)); |
| 1783 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { | 1812 if (field_has_length) { |
| 1784 // Destroy value_cid_reg (safe because we are finished with it). | 1813 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| 1785 __ movl(value_cid_reg, | 1814 // Destroy value_cid_reg (safe because we are finished with it). |
| 1786 FieldAddress(value_reg, Array::length_offset())); | 1815 __ movl(value_cid_reg, |
| 1787 __ movl(field_length_operand, value_cid_reg); | 1816 FieldAddress(value_reg, Array::length_offset())); |
| 1788 } else if (RawObject::IsTypedDataClassId(value_cid)) { | 1817 __ movl(field_length_operand, value_cid_reg); |
| 1789 // Destroy value_cid_reg (safe because we are finished with it). | 1818 } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| 1790 __ movl(value_cid_reg, | 1819 // Destroy value_cid_reg (safe because we are finished with it). |
| 1791 FieldAddress(value_reg, TypedData::length_offset())); | 1820 __ movl(value_cid_reg, |
| 1792 __ movl(field_length_operand, value_cid_reg); | 1821 FieldAddress(value_reg, TypedData::length_offset())); |
| 1793 } else { | 1822 __ movl(field_length_operand, value_cid_reg); |
| 1794 __ movl(field_length_operand, Immediate(Field::kNoFixedLength)); | 1823 } else { |
| 1824 __ movl(field_length_operand, Immediate(Field::kNoFixedLength)); |
| 1825 } |
| 1795 } | 1826 } |
| 1796 } | 1827 } |
| 1797 | 1828 |
| 1798 if (!ok_is_fall_through) { | 1829 if (!ok_is_fall_through) { |
| 1799 __ jmp(&ok); | 1830 __ jmp(&ok); |
| 1800 } | 1831 } |
| 1801 } else { | 1832 } else { |
| 1802 // Field guard class has been initialized and is known. | 1833 // Field guard class has been initialized and is known. |
| 1803 | |
| 1804 if (field_reg != kNoRegister) { | 1834 if (field_reg != kNoRegister) { |
| 1805 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1835 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
| 1806 } | 1836 } |
| 1807 | 1837 |
| 1808 if (value_cid == kDynamicCid) { | 1838 if (value_cid == kDynamicCid) { |
| 1809 // Value's class id is not known. | 1839 // Value's class id is not known. |
| 1810 __ testl(value_reg, Immediate(kSmiTagMask)); | 1840 __ testl(value_reg, Immediate(kSmiTagMask)); |
| 1811 | 1841 |
| 1812 if (field_cid != kSmiCid) { | 1842 if (field_cid != kSmiCid) { |
| 1813 __ j(ZERO, fail); | 1843 __ j(ZERO, fail); |
| (...skipping 3365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5179 PcDescriptors::kOther, | 5209 PcDescriptors::kOther, |
| 5180 locs()); | 5210 locs()); |
| 5181 __ Drop(2); // Discard type arguments and receiver. | 5211 __ Drop(2); // Discard type arguments and receiver. |
| 5182 } | 5212 } |
| 5183 | 5213 |
| 5184 } // namespace dart | 5214 } // namespace dart |
| 5185 | 5215 |
| 5186 #undef __ | 5216 #undef __ |
| 5187 | 5217 |
| 5188 #endif // defined TARGET_ARCH_IA32 | 5218 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |