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_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 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 } else { | 1545 } else { |
1546 // Destroy value_cid_reg (safe because we are finished with it). | 1546 // Destroy value_cid_reg (safe because we are finished with it). |
1547 __ LoadImmediate(value_cid_reg, Smi::RawValue(Field::kNoFixedLength)); | 1547 __ LoadImmediate(value_cid_reg, Smi::RawValue(Field::kNoFixedLength)); |
1548 __ sw(value_cid_reg, field_length_operand); | 1548 __ sw(value_cid_reg, field_length_operand); |
1549 } | 1549 } |
1550 } | 1550 } |
1551 } | 1551 } |
1552 if (!ok_is_fall_through) { | 1552 if (!ok_is_fall_through) { |
1553 __ b(&ok); | 1553 __ b(&ok); |
1554 } | 1554 } |
| 1555 |
| 1556 if (deopt == NULL) { |
| 1557 ASSERT(!compiler->is_optimizing()); |
| 1558 __ Bind(fail); |
| 1559 |
| 1560 __ lw(CMPRES1, FieldAddress(field_reg, Field::guarded_cid_offset())); |
| 1561 __ BranchEqual(CMPRES1, kDynamicCid, &ok); |
| 1562 |
| 1563 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1564 __ sw(field_reg, Address(SP, 1 * kWordSize)); |
| 1565 __ sw(value_reg, Address(SP, 0 * kWordSize)); |
| 1566 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
| 1567 __ Drop(2); // Drop the field and the value. |
| 1568 } |
1555 } else { | 1569 } else { |
| 1570 ASSERT(compiler->is_optimizing()); |
| 1571 ASSERT(deopt != NULL); |
| 1572 ASSERT(ok_is_fall_through); |
| 1573 // Field guard class has been initialized and is known. |
1556 if (field_reg != kNoRegister) { | 1574 if (field_reg != kNoRegister) { |
1557 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1575 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
1558 } | 1576 } |
1559 if (value_cid == kDynamicCid) { | 1577 if (value_cid == kDynamicCid) { |
1560 // Field's guarded class id is fixed by value's class id is not known. | 1578 // Field's guarded class id is fixed by value's class id is not known. |
1561 __ andi(CMPRES1, value_reg, Immediate(kSmiTagMask)); | 1579 __ andi(CMPRES1, value_reg, Immediate(kSmiTagMask)); |
1562 | 1580 |
1563 if (field_cid != kSmiCid) { | 1581 if (field_cid != kSmiCid) { |
1564 __ beq(CMPRES1, ZR, fail); | 1582 __ beq(CMPRES1, ZR, fail); |
1565 __ LoadClassId(value_cid_reg, value_reg); | 1583 __ LoadClassId(value_cid_reg, value_reg); |
(...skipping 21 matching lines...) Expand all Loading... |
1587 __ lw(TMP, field_length_operand); | 1605 __ lw(TMP, field_length_operand); |
1588 __ subu(CMPRES1, value_cid_reg, TMP); | 1606 __ subu(CMPRES1, value_cid_reg, TMP); |
1589 } | 1607 } |
1590 | 1608 |
1591 if (field().is_nullable() && (field_cid != kNullCid)) { | 1609 if (field().is_nullable() && (field_cid != kNullCid)) { |
1592 __ beq(CMPRES1, ZR, &ok); | 1610 __ beq(CMPRES1, ZR, &ok); |
1593 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null())); | 1611 __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null())); |
1594 __ subu(CMPRES1, value_reg, TMP); | 1612 __ subu(CMPRES1, value_reg, TMP); |
1595 } | 1613 } |
1596 | 1614 |
1597 if (ok_is_fall_through) { | 1615 __ bne(CMPRES1, ZR, fail); |
1598 __ bne(CMPRES1, ZR, fail); | |
1599 } else { | |
1600 __ beq(CMPRES1, ZR, &ok); | |
1601 } | |
1602 } else { | 1616 } else { |
1603 // Both value's and field's class id is known. | 1617 // Both value's and field's class id is known. |
1604 if ((value_cid != field_cid) && (value_cid != nullability)) { | 1618 if ((value_cid != field_cid) && (value_cid != nullability)) { |
1605 if (ok_is_fall_through) { | 1619 __ b(fail); |
1606 __ b(fail); | |
1607 } | |
1608 } else if (field_has_length && (value_cid == field_cid)) { | 1620 } else if (field_has_length && (value_cid == field_cid)) { |
1609 ASSERT(value_cid_reg != kNoRegister); | 1621 ASSERT(value_cid_reg != kNoRegister); |
1610 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1622 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
1611 // Destroy value_cid_reg (safe because we are finished with it). | 1623 // Destroy value_cid_reg (safe because we are finished with it). |
1612 __ lw(value_cid_reg, | 1624 __ lw(value_cid_reg, |
1613 FieldAddress(value_reg, Array::length_offset())); | 1625 FieldAddress(value_reg, Array::length_offset())); |
1614 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1626 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
1615 // Destroy value_cid_reg (safe because we are finished with it). | 1627 // Destroy value_cid_reg (safe because we are finished with it). |
1616 __ lw(value_cid_reg, | 1628 __ lw(value_cid_reg, |
1617 FieldAddress(value_reg, TypedData::length_offset())); | 1629 FieldAddress(value_reg, TypedData::length_offset())); |
1618 } | 1630 } |
1619 __ LoadImmediate(TMP, Smi::RawValue(field_length)); | 1631 __ LoadImmediate(TMP, Smi::RawValue(field_length)); |
1620 __ subu(CMPRES1, value_cid_reg, TMP); | 1632 __ subu(CMPRES1, value_cid_reg, TMP); |
1621 if (ok_is_fall_through) { | 1633 __ bne(CMPRES1, ZR, fail); |
1622 __ bne(CMPRES1, ZR, fail); | |
1623 } | |
1624 } else { | 1634 } else { |
1625 // Nothing to emit. | 1635 UNREACHABLE(); |
1626 ASSERT(!compiler->is_optimizing()); | |
1627 return; | |
1628 } | 1636 } |
1629 } | 1637 } |
1630 } | 1638 } |
1631 | |
1632 if (deopt == NULL) { | |
1633 ASSERT(!compiler->is_optimizing()); | |
1634 __ Bind(fail); | |
1635 | |
1636 __ lw(CMPRES1, FieldAddress(field_reg, Field::guarded_cid_offset())); | |
1637 __ BranchEqual(CMPRES1, kDynamicCid, &ok); | |
1638 | |
1639 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
1640 __ sw(field_reg, Address(SP, 1 * kWordSize)); | |
1641 __ sw(value_reg, Address(SP, 0 * kWordSize)); | |
1642 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); | |
1643 __ Drop(2); // Drop the field and the value. | |
1644 } | |
1645 | |
1646 __ Bind(&ok); | 1639 __ Bind(&ok); |
1647 } | 1640 } |
1648 | 1641 |
1649 | 1642 |
1650 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1643 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
1651 const intptr_t kNumInputs = 2; | 1644 const intptr_t kNumInputs = 2; |
1652 const intptr_t kNumTemps = 0; | 1645 const intptr_t kNumTemps = 0; |
1653 LocationSummary* summary = | 1646 LocationSummary* summary = |
1654 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1647 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1655 summary->set_in(0, Location::RequiresRegister()); | 1648 summary->set_in(0, Location::RequiresRegister()); |
(...skipping 2338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3994 compiler->GenerateCall(token_pos(), | 3987 compiler->GenerateCall(token_pos(), |
3995 &label, | 3988 &label, |
3996 PcDescriptors::kOther, | 3989 PcDescriptors::kOther, |
3997 locs()); | 3990 locs()); |
3998 __ Drop(2); // Discard type arguments and receiver. | 3991 __ Drop(2); // Discard type arguments and receiver. |
3999 } | 3992 } |
4000 | 3993 |
4001 } // namespace dart | 3994 } // namespace dart |
4002 | 3995 |
4003 #endif // defined TARGET_ARCH_MIPS | 3996 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |