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

Side by Side Diff: runtime/vm/intermediate_language_mips.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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 1644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 LoadValueCid(compiler, value_cid_reg, value_reg); 1655 LoadValueCid(compiler, value_cid_reg, value_reg);
1656 1656
1657 Label skip_length_check; 1657 Label skip_length_check;
1658 1658
1659 __ lw(CMPRES1, field_cid_operand); 1659 __ lw(CMPRES1, field_cid_operand);
1660 __ bne(value_cid_reg, CMPRES1, &skip_length_check); 1660 __ bne(value_cid_reg, CMPRES1, &skip_length_check);
1661 if (field_has_length) { 1661 if (field_has_length) {
1662 // Field guard may have remembered list length, check it. 1662 // Field guard may have remembered list length, check it.
1663 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1663 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
1664 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); 1664 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1665 __ LoadImmediate(CMPRES1, field_length); 1665 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length));
1666 __ subu(CMPRES1, TMP, CMPRES1); 1666 __ subu(CMPRES1, TMP, CMPRES1);
1667 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1667 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1668 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); 1668 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1669 __ LoadImmediate(CMPRES1, field_length); 1669 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length));
1670 __ subu(CMPRES1, TMP, CMPRES1); 1670 __ subu(CMPRES1, TMP, CMPRES1);
1671 } else { 1671 } else {
1672 ASSERT(field_cid == kIllegalCid); 1672 ASSERT(field_cid == kIllegalCid);
1673 __ LoadImmediate(CMPRES1, 0x1); 1673 Label check_array, local_exit, local_fail;
1674 __ BranchEqual(value_cid_reg, kNullCid, &local_fail);
1675 // Check for typed data array.
1676 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid,
1677 &local_fail);
1678 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid,
1679 &check_array);
1680 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1681 __ lw(CMPRES1, field_length_operand);
1682 __ subu(CMPRES1, TMP, CMPRES1);
1683 __ b(&local_exit);
1684 // Check for regular array.
1685 __ Bind(&check_array);
1686 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid,
1687 &local_fail);
1688 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail);
1689 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1690 __ lw(CMPRES1, field_length_operand);
1691 __ subu(CMPRES1, TMP, CMPRES1);
1692 __ b(&local_exit);
1693
1694 __ Bind(&local_fail);
1695 // TODO(regis): TMP1 may conflict. Revisit.
1696 __ LoadImmediate(TMP1, Smi::RawValue(Field::kNoFixedLength));
1697 __ sw(TMP1, field_length_operand);
1698
1699 __ Bind(&local_exit);
1674 } 1700 }
1675 __ bne(CMPRES1, ZR, fail); 1701 __ bne(CMPRES1, ZR, fail);
1676 } 1702 }
1677 __ Bind(&skip_length_check); 1703 __ Bind(&skip_length_check);
1678 __ lw(TMP1, field_nullability_operand); 1704 __ lw(TMP1, field_nullability_operand);
1679 __ subu(CMPRES, value_cid_reg, TMP1); 1705 __ subu(CMPRES, value_cid_reg, TMP1);
1680 } else if (value_cid == kNullCid) { 1706 } else if (value_cid == kNullCid) {
1681 // TODO(regis): TMP1 may conflict. Revisit. 1707 // TODO(regis): TMP1 may conflict. Revisit.
1682 __ lw(TMP1, field_nullability_operand); 1708 __ lw(TMP1, field_nullability_operand);
1683 __ LoadImmediate(CMPRES, value_cid); 1709 __ LoadImmediate(CMPRES, value_cid);
1684 __ subu(CMPRES, TMP1, CMPRES); 1710 __ subu(CMPRES, TMP1, CMPRES);
1685 } else { 1711 } else {
1686 Label skip_length_check; 1712 Label skip_length_check;
1687 // TODO(regis): TMP1 may conflict. Revisit. 1713 // TODO(regis): TMP1 may conflict. Revisit.
1688 __ lw(TMP1, field_cid_operand); 1714 __ lw(TMP1, field_cid_operand);
1689 __ LoadImmediate(CMPRES, value_cid); 1715 __ LoadImmediate(CMPRES, value_cid);
1690 __ subu(CMPRES, TMP1, CMPRES); 1716 __ subu(CMPRES, TMP1, CMPRES);
1691 __ bne(CMPRES, ZR, &skip_length_check); 1717 __ bne(CMPRES, ZR, &skip_length_check);
1692 // Insert length check. 1718 // Insert length check.
1693 if (field_has_length) { 1719 if (field_has_length) {
1694 if (value_cid_reg == kNoRegister) { 1720 if (value_cid_reg == kNoRegister) {
1695 ASSERT(!compiler->is_optimizing()); 1721 ASSERT(!compiler->is_optimizing());
1696 value_cid_reg = A1; 1722 value_cid_reg = A1;
1697 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); 1723 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
1698 } 1724 }
1699 ASSERT(value_cid_reg != kNoRegister); 1725 ASSERT(value_cid_reg != kNoRegister);
1700 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1726 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
1701 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); 1727 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1702 __ LoadImmediate(CMPRES, field_length); 1728 __ LoadImmediate(CMPRES, Smi::RawValue(field_length));
1703 __ subu(CMPRES, TMP, CMPRES); 1729 __ subu(CMPRES, TMP, CMPRES);
1704 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1730 } else if (RawObject::IsTypedDataClassId(value_cid)) {
1705 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); 1731 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1706 __ LoadImmediate(CMPRES, field_length); 1732 __ LoadImmediate(CMPRES, Smi::RawValue(field_length));
1707 __ subu(CMPRES, TMP, CMPRES); 1733 __ subu(CMPRES, TMP, CMPRES);
1708 } else { 1734 } else {
1709 ASSERT(field_cid == kIllegalCid); 1735 ASSERT(field_cid == kIllegalCid);
1710 __ LoadImmediate(CMPRES, 0x1);
1711 } 1736 }
1737 __ bne(CMPRES, ZR, fail);
1712 } 1738 }
1713 __ Bind(&skip_length_check); 1739 __ Bind(&skip_length_check);
1714 } 1740 }
1715 __ beq(CMPRES, ZR, &ok); 1741 __ beq(CMPRES, ZR, &ok);
1716 1742
1717 __ lw(CMPRES1, field_cid_operand); 1743 __ lw(CMPRES1, field_cid_operand);
1718 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); 1744 __ BranchNotEqual(CMPRES1, kIllegalCid, fail);
1719 1745
1720 if (value_cid == kDynamicCid) { 1746 if (value_cid == kDynamicCid) {
1721 __ sw(value_cid_reg, field_cid_operand); 1747 __ sw(value_cid_reg, field_cid_operand);
(...skipping 17 matching lines...) Expand all
1739 &local_fail); 1765 &local_fail);
1740 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail); 1766 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail);
1741 // Destroy value_cid_reg (safe because we are finished with it). 1767 // Destroy value_cid_reg (safe because we are finished with it).
1742 __ lw(value_cid_reg, 1768 __ lw(value_cid_reg,
1743 FieldAddress(value_reg, Array::length_offset())); 1769 FieldAddress(value_reg, Array::length_offset()));
1744 __ sw(value_cid_reg, field_length_operand); 1770 __ sw(value_cid_reg, field_length_operand);
1745 __ b(&local_exit); // Updated field length from regular array. 1771 __ b(&local_exit); // Updated field length from regular array.
1746 1772
1747 __ Bind(&local_fail); 1773 __ Bind(&local_fail);
1748 // TODO(regis): TMP1 may conflict. Revisit. 1774 // TODO(regis): TMP1 may conflict. Revisit.
1749 __ LoadImmediate(TMP1, Field::kNoFixedLength); 1775 __ LoadImmediate(TMP1, Smi::RawValue(Field::kNoFixedLength));
1750 __ sw(TMP1, field_length_operand); 1776 __ sw(TMP1, field_length_operand);
1751 1777
1752 __ Bind(&local_exit); 1778 __ Bind(&local_exit);
1753 } 1779 }
1754 } else { 1780 } else {
1755 if (value_cid_reg == kNoRegister) { 1781 if (value_cid_reg == kNoRegister) {
1756 ASSERT(!compiler->is_optimizing()); 1782 ASSERT(!compiler->is_optimizing());
1757 value_cid_reg = A1; 1783 value_cid_reg = A1;
1758 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); 1784 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
1759 } 1785 }
1760 ASSERT(value_cid_reg != kNoRegister); 1786 ASSERT(value_cid_reg != kNoRegister);
1761 ASSERT(field_reg != kNoRegister); 1787 ASSERT(field_reg != kNoRegister);
1762 __ LoadImmediate(TMP1, value_cid); 1788 __ LoadImmediate(TMP1, value_cid);
1763 __ sw(TMP1, field_cid_operand); 1789 __ sw(TMP1, field_cid_operand);
1764 __ sw(TMP1, field_nullability_operand); 1790 __ sw(TMP1, field_nullability_operand);
1765 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { 1791 if (field_has_length) {
1766 // Destroy value_cid_reg (safe because we are finished with it). 1792 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
1767 __ lw(value_cid_reg, 1793 // Destroy value_cid_reg (safe because we are finished with it).
1768 FieldAddress(value_reg, Array::length_offset())); 1794 __ lw(value_cid_reg,
1769 __ sw(value_cid_reg, field_length_operand); 1795 FieldAddress(value_reg, Array::length_offset()));
1770 } else if (RawObject::IsTypedDataClassId(value_cid)) { 1796 __ sw(value_cid_reg, field_length_operand);
1771 // Destroy value_cid_reg (safe because we are finished with it). 1797 } else if (RawObject::IsTypedDataClassId(value_cid)) {
1772 __ lw(value_cid_reg, 1798 // Destroy value_cid_reg (safe because we are finished with it).
1773 FieldAddress(value_reg, TypedData::length_offset())); 1799 __ lw(value_cid_reg,
1774 __ sw(value_cid_reg, field_length_operand); 1800 FieldAddress(value_reg, TypedData::length_offset()));
1775 } else { 1801 __ sw(value_cid_reg, field_length_operand);
1776 // Destroy value_cid_reg (safe because we are finished with it). 1802 } else {
1777 __ LoadImmediate(value_cid_reg, Field::kNoFixedLength); 1803 // Destroy value_cid_reg (safe because we are finished with it).
1778 __ sw(value_cid_reg, field_length_operand); 1804 __ LoadImmediate(value_cid_reg, Smi::RawValue(Field::kNoFixedLength));
1805 __ sw(value_cid_reg, field_length_operand);
1806 }
1779 } 1807 }
1780 } 1808 }
1781
1782 if (!ok_is_fall_through) { 1809 if (!ok_is_fall_through) {
1783 __ b(&ok); 1810 __ b(&ok);
1784 } 1811 }
1785 } else { 1812 } else {
1786 if (field_reg != kNoRegister) { 1813 if (field_reg != kNoRegister) {
1787 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); 1814 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
1788 } 1815 }
1789 if (value_cid == kDynamicCid) { 1816 if (value_cid == kDynamicCid) {
1790 // Field's guarded class id is fixed by value's class id is not known. 1817 // Field's guarded class id is fixed by value's class id is not known.
1791 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask)); 1818 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 ASSERT(value_cid_reg != kNoRegister); 1866 ASSERT(value_cid_reg != kNoRegister);
1840 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1867 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
1841 // Destroy value_cid_reg (safe because we are finished with it). 1868 // Destroy value_cid_reg (safe because we are finished with it).
1842 __ lw(value_cid_reg, 1869 __ lw(value_cid_reg,
1843 FieldAddress(value_reg, Array::length_offset())); 1870 FieldAddress(value_reg, Array::length_offset()));
1844 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1871 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1845 // Destroy value_cid_reg (safe because we are finished with it). 1872 // Destroy value_cid_reg (safe because we are finished with it).
1846 __ lw(value_cid_reg, 1873 __ lw(value_cid_reg,
1847 FieldAddress(value_reg, TypedData::length_offset())); 1874 FieldAddress(value_reg, TypedData::length_offset()));
1848 } 1875 }
1849 __ LoadImmediate(TMP1, field_length); 1876 __ LoadImmediate(TMP1, Smi::RawValue(field_length));
1850 __ subu(CMPRES, value_cid_reg, TMP1); 1877 __ subu(CMPRES, value_cid_reg, TMP1);
1851 if (ok_is_fall_through) { 1878 if (ok_is_fall_through) {
1852 __ bne(CMPRES, ZR, fail); 1879 __ bne(CMPRES, ZR, fail);
1853 } 1880 }
1854 } else { 1881 } else {
1855 // Nothing to emit. 1882 // Nothing to emit.
1856 ASSERT(!compiler->is_optimizing()); 1883 ASSERT(!compiler->is_optimizing());
1857 return; 1884 return;
1858 } 1885 }
1859 } 1886 }
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
4127 compiler->GenerateCall(token_pos(), 4154 compiler->GenerateCall(token_pos(),
4128 &label, 4155 &label,
4129 PcDescriptors::kOther, 4156 PcDescriptors::kOther,
4130 locs()); 4157 locs());
4131 __ Drop(2); // Discard type arguments and receiver. 4158 __ Drop(2); // Discard type arguments and receiver.
4132 } 4159 }
4133 4160
4134 } // namespace dart 4161 } // namespace dart
4135 4162
4136 #endif // defined TARGET_ARCH_MIPS 4163 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698