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

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
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 LoadValueCid(compiler, value_cid_reg, value_reg); 1584 LoadValueCid(compiler, value_cid_reg, value_reg);
1585 1585
1586 Label skip_length_check; 1586 Label skip_length_check;
1587 1587
1588 __ lw(CMPRES1, field_cid_operand); 1588 __ lw(CMPRES1, field_cid_operand);
1589 __ bne(value_cid_reg, CMPRES1, &skip_length_check); 1589 __ bne(value_cid_reg, CMPRES1, &skip_length_check);
1590 if (field_has_length) { 1590 if (field_has_length) {
1591 // Field guard may have remembered list length, check it. 1591 // Field guard may have remembered list length, check it.
1592 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1592 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
1593 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); 1593 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1594 __ LoadImmediate(CMPRES1, field_length); 1594 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length));
1595 __ subu(CMPRES1, TMP, CMPRES1); 1595 __ subu(CMPRES1, TMP, CMPRES1);
1596 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1596 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1597 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); 1597 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1598 __ LoadImmediate(CMPRES1, field_length); 1598 __ LoadImmediate(CMPRES1, Smi::RawValue(field_length));
1599 __ subu(CMPRES1, TMP, CMPRES1); 1599 __ subu(CMPRES1, TMP, CMPRES1);
1600 } else { 1600 } else {
1601 ASSERT(field_cid == kIllegalCid); 1601 ASSERT(field_cid == kIllegalCid);
1602 __ LoadImmediate(CMPRES1, 0x1); 1602 ASSERT(field_length == Field::kUnknownFixedLength);
1603 // At compile time we do not know the type of the field nor its
1604 // length. At execution time we may have set the class id and
1605 // list length so we compare the guarded length with the
1606 // list length here, without this check the list length could change
1607 // without triggering a deoptimization.
1608 Label check_array, length_compared, no_fixed_length;
1609 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length);
1610 // Check for typed data array.
1611 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid,
1612 &no_fixed_length);
1613 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid,
1614 &check_array);
1615 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1616 __ lw(CMPRES1, field_length_operand);
1617 __ subu(CMPRES1, TMP, CMPRES1);
1618 __ b(&length_compared);
1619 // Check for regular array.
1620 __ Bind(&check_array);
1621 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid,
1622 &no_fixed_length);
1623 __ BranchSignedLess(value_cid_reg, kArrayCid, &no_fixed_length);
1624 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1625 __ lw(CMPRES1, field_length_operand);
1626 __ subu(CMPRES1, TMP, CMPRES1);
1627 __ b(&length_compared);
1628 __ Bind(&no_fixed_length);
1629 __ b(fail);
1630 __ Bind(&length_compared);
1603 } 1631 }
1604 __ bne(CMPRES1, ZR, fail); 1632 __ bne(CMPRES1, ZR, fail);
1605 } 1633 }
1606 __ Bind(&skip_length_check); 1634 __ Bind(&skip_length_check);
1607 __ lw(TMP1, field_nullability_operand); 1635 __ lw(TMP1, field_nullability_operand);
1608 __ subu(CMPRES, value_cid_reg, TMP1); 1636 __ subu(CMPRES, value_cid_reg, TMP1);
1609 } else if (value_cid == kNullCid) { 1637 } else if (value_cid == kNullCid) {
1610 // TODO(regis): TMP1 may conflict. Revisit. 1638 // TODO(regis): TMP1 may conflict. Revisit.
1611 __ lw(TMP1, field_nullability_operand); 1639 __ lw(TMP1, field_nullability_operand);
1612 __ LoadImmediate(CMPRES, value_cid); 1640 __ LoadImmediate(CMPRES, value_cid);
1613 __ subu(CMPRES, TMP1, CMPRES); 1641 __ subu(CMPRES, TMP1, CMPRES);
1614 } else { 1642 } else {
1615 Label skip_length_check; 1643 Label skip_length_check;
1616 // TODO(regis): TMP1 may conflict. Revisit. 1644 // TODO(regis): TMP1 may conflict. Revisit.
1617 __ lw(TMP1, field_cid_operand); 1645 __ lw(TMP1, field_cid_operand);
1618 __ LoadImmediate(CMPRES, value_cid); 1646 __ LoadImmediate(CMPRES, value_cid);
1619 __ subu(CMPRES, TMP1, CMPRES); 1647 __ subu(CMPRES, TMP1, CMPRES);
1620 __ bne(CMPRES, ZR, &skip_length_check); 1648 __ bne(CMPRES, ZR, &skip_length_check);
1621 // Insert length check. 1649 // Insert length check.
1622 if (field_has_length) { 1650 if (field_has_length) {
1623 if (value_cid_reg == kNoRegister) {
1624 ASSERT(!compiler->is_optimizing());
1625 value_cid_reg = A1;
1626 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
1627 }
1628 ASSERT(value_cid_reg != kNoRegister); 1651 ASSERT(value_cid_reg != kNoRegister);
1629 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1652 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
1630 __ lw(TMP, FieldAddress(value_reg, Array::length_offset())); 1653 __ lw(TMP, FieldAddress(value_reg, Array::length_offset()));
1631 __ LoadImmediate(CMPRES, field_length); 1654 __ LoadImmediate(CMPRES, Smi::RawValue(field_length));
1632 __ subu(CMPRES, TMP, CMPRES); 1655 __ subu(CMPRES, TMP, CMPRES);
1633 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1656 } else if (RawObject::IsTypedDataClassId(value_cid)) {
1634 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset())); 1657 __ lw(TMP, FieldAddress(value_reg, TypedData::length_offset()));
1635 __ LoadImmediate(CMPRES, field_length); 1658 __ LoadImmediate(CMPRES, Smi::RawValue(field_length));
1636 __ subu(CMPRES, TMP, CMPRES); 1659 __ subu(CMPRES, TMP, CMPRES);
1660 } else if (field_cid != kIllegalCid) {
1661 ASSERT(field_cid != value_cid);
1662 ASSERT(field_length >= 0);
1663 // Field has a known class id and length. At compile time it is
1664 // known that the value's class id is not a fixed length list.
1665 __ b(fail);
1637 } else { 1666 } else {
1638 ASSERT(field_cid == kIllegalCid); 1667 ASSERT(field_cid == kIllegalCid);
1639 __ LoadImmediate(CMPRES, 0x1); 1668 ASSERT(field_length == Field::kUnknownFixedLength);
1669 // Following jump cannot not occur, fall through.
1640 } 1670 }
1671 __ bne(CMPRES, ZR, fail);
1641 } 1672 }
1642 __ Bind(&skip_length_check); 1673 __ Bind(&skip_length_check);
1643 } 1674 }
1644 __ beq(CMPRES, ZR, &ok); 1675 __ beq(CMPRES, ZR, &ok);
1645 1676
1646 __ lw(CMPRES1, field_cid_operand); 1677 __ lw(CMPRES1, field_cid_operand);
1647 __ BranchNotEqual(CMPRES1, kIllegalCid, fail); 1678 __ BranchNotEqual(CMPRES1, kIllegalCid, fail);
1648 1679
1649 if (value_cid == kDynamicCid) { 1680 if (value_cid == kDynamicCid) {
1650 __ sw(value_cid_reg, field_cid_operand); 1681 __ sw(value_cid_reg, field_cid_operand);
1651 __ sw(value_cid_reg, field_nullability_operand); 1682 __ sw(value_cid_reg, field_nullability_operand);
1652 if (field_has_length) { 1683 if (field_has_length) {
1653 Label check_array, local_exit, local_fail; 1684 Label check_array, length_set, no_fixed_length;
1654 __ BranchEqual(value_cid_reg, kNullCid, &local_fail); 1685 __ BranchEqual(value_cid_reg, kNullCid, &no_fixed_length);
1655 // Check for typed data array. 1686 // Check for typed data array.
1656 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid, 1687 __ BranchSignedGreater(value_cid_reg, kTypedDataFloat32x4ArrayCid,
1657 &local_fail); 1688 &no_fixed_length);
1658 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid, 1689 __ BranchSignedLess(value_cid_reg, kTypedDataInt8ArrayCid,
1659 &check_array); 1690 &check_array);
1660 // Destroy value_cid_reg (safe because we are finished with it). 1691 // Destroy value_cid_reg (safe because we are finished with it).
1661 __ lw(value_cid_reg, 1692 __ lw(value_cid_reg,
1662 FieldAddress(value_reg, TypedData::length_offset())); 1693 FieldAddress(value_reg, TypedData::length_offset()));
1663 __ sw(value_cid_reg, field_length_operand); 1694 __ sw(value_cid_reg, field_length_operand);
1664 __ b(&local_exit); // Updated field length typed data array. 1695 // Updated field length typed data array.
1696 __ b(&length_set);
1665 // Check for regular array. 1697 // Check for regular array.
1666 __ Bind(&check_array); 1698 __ Bind(&check_array);
1667 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid, 1699 __ BranchSignedGreater(value_cid_reg, kImmutableArrayCid,
1668 &local_fail); 1700 &no_fixed_length);
1669 __ BranchSignedLess(value_cid_reg, kArrayCid, &local_fail); 1701 __ BranchSignedLess(value_cid_reg, kArrayCid, &no_fixed_length);
1670 // Destroy value_cid_reg (safe because we are finished with it). 1702 // Destroy value_cid_reg (safe because we are finished with it).
1671 __ lw(value_cid_reg, 1703 __ lw(value_cid_reg,
1672 FieldAddress(value_reg, Array::length_offset())); 1704 FieldAddress(value_reg, Array::length_offset()));
1673 __ sw(value_cid_reg, field_length_operand); 1705 __ sw(value_cid_reg, field_length_operand);
1674 __ b(&local_exit); // Updated field length from regular array. 1706 // Updated field length from regular array.
1675 1707 __ b(&length_set);
1676 __ Bind(&local_fail); 1708 __ Bind(&no_fixed_length);
1677 // TODO(regis): TMP1 may conflict. Revisit. 1709 // TODO(regis): TMP1 may conflict. Revisit.
1678 __ LoadImmediate(TMP1, Field::kNoFixedLength); 1710 __ LoadImmediate(TMP1, Smi::RawValue(Field::kNoFixedLength));
1679 __ sw(TMP1, field_length_operand); 1711 __ sw(TMP1, field_length_operand);
1680 1712 __ Bind(&length_set);
1681 __ Bind(&local_exit);
1682 } 1713 }
1683 } else { 1714 } else {
1684 if (value_cid_reg == kNoRegister) {
1685 ASSERT(!compiler->is_optimizing());
1686 value_cid_reg = A1;
1687 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
1688 }
1689 ASSERT(value_cid_reg != kNoRegister);
1690 ASSERT(field_reg != kNoRegister); 1715 ASSERT(field_reg != kNoRegister);
1691 __ LoadImmediate(TMP1, value_cid); 1716 __ LoadImmediate(TMP1, value_cid);
1692 __ sw(TMP1, field_cid_operand); 1717 __ sw(TMP1, field_cid_operand);
1693 __ sw(TMP1, field_nullability_operand); 1718 __ sw(TMP1, field_nullability_operand);
1694 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { 1719 if (field_has_length) {
1695 // Destroy value_cid_reg (safe because we are finished with it). 1720 ASSERT(value_cid_reg != kNoRegister);
1696 __ lw(value_cid_reg, 1721 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
1697 FieldAddress(value_reg, Array::length_offset())); 1722 // Destroy value_cid_reg (safe because we are finished with it).
1698 __ sw(value_cid_reg, field_length_operand); 1723 __ lw(value_cid_reg,
1699 } else if (RawObject::IsTypedDataClassId(value_cid)) { 1724 FieldAddress(value_reg, Array::length_offset()));
1700 // Destroy value_cid_reg (safe because we are finished with it). 1725 __ sw(value_cid_reg, field_length_operand);
1701 __ lw(value_cid_reg, 1726 } else if (RawObject::IsTypedDataClassId(value_cid)) {
1702 FieldAddress(value_reg, TypedData::length_offset())); 1727 // Destroy value_cid_reg (safe because we are finished with it).
1703 __ sw(value_cid_reg, field_length_operand); 1728 __ lw(value_cid_reg,
1704 } else { 1729 FieldAddress(value_reg, TypedData::length_offset()));
1705 // Destroy value_cid_reg (safe because we are finished with it). 1730 __ sw(value_cid_reg, field_length_operand);
1706 __ LoadImmediate(value_cid_reg, Field::kNoFixedLength); 1731 } else {
1707 __ sw(value_cid_reg, field_length_operand); 1732 // Destroy value_cid_reg (safe because we are finished with it).
1733 __ LoadImmediate(value_cid_reg, Smi::RawValue(Field::kNoFixedLength));
1734 __ sw(value_cid_reg, field_length_operand);
1735 }
1708 } 1736 }
1709 } 1737 }
1710
1711 if (!ok_is_fall_through) { 1738 if (!ok_is_fall_through) {
1712 __ b(&ok); 1739 __ b(&ok);
1713 } 1740 }
1714 } else { 1741 } else {
1715 if (field_reg != kNoRegister) { 1742 if (field_reg != kNoRegister) {
1716 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); 1743 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
1717 } 1744 }
1718 if (value_cid == kDynamicCid) { 1745 if (value_cid == kDynamicCid) {
1719 // Field's guarded class id is fixed by value's class id is not known. 1746 // Field's guarded class id is fixed by value's class id is not known.
1720 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask)); 1747 __ andi(CMPRES, value_reg, Immediate(kSmiTagMask));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 ASSERT(value_cid_reg != kNoRegister); 1795 ASSERT(value_cid_reg != kNoRegister);
1769 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { 1796 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
1770 // Destroy value_cid_reg (safe because we are finished with it). 1797 // Destroy value_cid_reg (safe because we are finished with it).
1771 __ lw(value_cid_reg, 1798 __ lw(value_cid_reg,
1772 FieldAddress(value_reg, Array::length_offset())); 1799 FieldAddress(value_reg, Array::length_offset()));
1773 } else if (RawObject::IsTypedDataClassId(field_cid)) { 1800 } else if (RawObject::IsTypedDataClassId(field_cid)) {
1774 // Destroy value_cid_reg (safe because we are finished with it). 1801 // Destroy value_cid_reg (safe because we are finished with it).
1775 __ lw(value_cid_reg, 1802 __ lw(value_cid_reg,
1776 FieldAddress(value_reg, TypedData::length_offset())); 1803 FieldAddress(value_reg, TypedData::length_offset()));
1777 } 1804 }
1778 __ LoadImmediate(TMP1, field_length); 1805 __ LoadImmediate(TMP1, Smi::RawValue(field_length));
1779 __ subu(CMPRES, value_cid_reg, TMP1); 1806 __ subu(CMPRES, value_cid_reg, TMP1);
1780 if (ok_is_fall_through) { 1807 if (ok_is_fall_through) {
1781 __ bne(CMPRES, ZR, fail); 1808 __ bne(CMPRES, ZR, fail);
1782 } 1809 }
1783 } else { 1810 } else {
1784 // Nothing to emit. 1811 // Nothing to emit.
1785 ASSERT(!compiler->is_optimizing()); 1812 ASSERT(!compiler->is_optimizing());
1786 return; 1813 return;
1787 } 1814 }
1788 } 1815 }
(...skipping 2286 matching lines...) Expand 10 before | Expand all | Expand 10 after
4075 compiler->GenerateCall(token_pos(), 4102 compiler->GenerateCall(token_pos(),
4076 &label, 4103 &label,
4077 PcDescriptors::kOther, 4104 PcDescriptors::kOther,
4078 locs()); 4105 locs());
4079 __ Drop(2); // Discard type arguments and receiver. 4106 __ Drop(2); // Discard type arguments and receiver.
4080 } 4107 }
4081 4108
4082 } // namespace dart 4109 } // namespace dart
4083 4110
4084 #endif // defined TARGET_ARCH_MIPS 4111 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698