Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(508)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 22915008: Tests for GuardField length check along with bug fixes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698