| 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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 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 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 } | 1436 } |
| 1437 } | 1437 } |
| 1438 | 1438 |
| 1439 | 1439 |
| 1440 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { | 1440 LocationSummary* GuardFieldInstr::MakeLocationSummary() const { |
| 1441 const intptr_t kNumInputs = 1; | 1441 const intptr_t kNumInputs = 1; |
| 1442 LocationSummary* summary = | 1442 LocationSummary* summary = |
| 1443 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 1443 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
| 1444 summary->set_in(0, Location::RequiresRegister()); | 1444 summary->set_in(0, Location::RequiresRegister()); |
| 1445 const bool field_has_length = field().needs_length_check(); | 1445 const bool field_has_length = field().needs_length_check(); |
| 1446 const bool need_value_temp_reg = | 1446 summary->AddTemp(Location::RequiresRegister()); |
| 1447 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && | 1447 summary->AddTemp(Location::RequiresRegister()); |
| 1448 (field().guarded_cid() != kSmiCid))); | |
| 1449 if (need_value_temp_reg) { | |
| 1450 summary->AddTemp(Location::RequiresRegister()); | |
| 1451 summary->AddTemp(Location::RequiresRegister()); | |
| 1452 } | |
| 1453 const bool need_field_temp_reg = | 1448 const bool need_field_temp_reg = |
| 1454 field_has_length || (field().guarded_cid() == kIllegalCid); | 1449 field_has_length || (field().guarded_cid() == kIllegalCid); |
| 1455 if (need_field_temp_reg) { | 1450 if (need_field_temp_reg) { |
| 1456 summary->AddTemp(Location::RequiresRegister()); | 1451 summary->AddTemp(Location::RequiresRegister()); |
| 1457 } | 1452 } |
| 1458 return summary; | 1453 return summary; |
| 1459 } | 1454 } |
| 1460 | 1455 |
| 1461 | 1456 |
| 1462 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1457 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1463 const intptr_t field_cid = field().guarded_cid(); | 1458 const intptr_t field_cid = field().guarded_cid(); |
| 1464 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid; | 1459 const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid; |
| 1465 const intptr_t field_length = field().guarded_list_length(); | 1460 const intptr_t field_length = field().guarded_list_length(); |
| 1466 const bool field_has_length = field().needs_length_check(); | 1461 const bool field_has_length = field().needs_length_check(); |
| 1467 const bool needs_value_temp_reg = | |
| 1468 (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) && | |
| 1469 (field().guarded_cid() != kSmiCid))); | |
| 1470 const bool needs_field_temp_reg = | 1462 const bool needs_field_temp_reg = |
| 1471 field_has_length || (field().guarded_cid() == kIllegalCid); | 1463 field_has_length || (field().guarded_cid() == kIllegalCid); |
| 1472 if (field_has_length) { | 1464 if (field_has_length) { |
| 1473 // Currently, we should only see final fields that remember length. | 1465 // Currently, we should only see final fields that remember length. |
| 1474 ASSERT(field().is_final()); | 1466 ASSERT(field().is_final()); |
| 1475 } | 1467 } |
| 1476 | 1468 |
| 1477 if (field_cid == kDynamicCid) { | 1469 if (field_cid == kDynamicCid) { |
| 1478 ASSERT(!compiler->is_optimizing()); | 1470 ASSERT(!compiler->is_optimizing()); |
| 1479 return; // Nothing to emit. | 1471 return; // Nothing to emit. |
| 1480 } | 1472 } |
| 1481 | 1473 |
| 1482 const intptr_t value_cid = value()->Type()->ToCid(); | 1474 const intptr_t value_cid = value()->Type()->ToCid(); |
| 1483 | 1475 |
| 1484 Register value_reg = locs()->in(0).reg(); | 1476 Register value_reg = locs()->in(0).reg(); |
| 1485 | 1477 |
| 1486 Register value_cid_reg = needs_value_temp_reg ? | 1478 Register value_cid_reg = locs()->temp(0).reg(); |
| 1487 locs()->temp(0).reg() : kNoRegister; | 1479 |
| 1488 Register temp_reg = needs_value_temp_reg ? | 1480 Register temp_reg = locs()->temp(1).reg(); |
| 1489 locs()->temp(1).reg() : kNoRegister; | |
| 1490 | 1481 |
| 1491 Register field_reg = needs_field_temp_reg ? | 1482 Register field_reg = needs_field_temp_reg ? |
| 1492 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; | 1483 locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister; |
| 1493 | 1484 |
| 1494 Label ok, fail_label; | 1485 Label ok, fail_label; |
| 1495 | 1486 |
| 1496 Label* deopt = compiler->is_optimizing() ? | 1487 Label* deopt = compiler->is_optimizing() ? |
| 1497 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; | 1488 compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL; |
| 1498 | 1489 |
| 1499 Label* fail = (deopt != NULL) ? deopt : &fail_label; | 1490 Label* fail = (deopt != NULL) ? deopt : &fail_label; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1511 } | 1502 } |
| 1512 | 1503 |
| 1513 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1504 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
| 1514 | 1505 |
| 1515 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); | 1506 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); |
| 1516 FieldAddress field_nullability_operand( | 1507 FieldAddress field_nullability_operand( |
| 1517 field_reg, Field::is_nullable_offset()); | 1508 field_reg, Field::is_nullable_offset()); |
| 1518 FieldAddress field_length_operand( | 1509 FieldAddress field_length_operand( |
| 1519 field_reg, Field::guarded_list_length_offset()); | 1510 field_reg, Field::guarded_list_length_offset()); |
| 1520 | 1511 |
| 1521 if (value_cid_reg == kNoRegister) { | 1512 ASSERT(value_cid_reg != kNoRegister); |
| 1522 ASSERT(!compiler->is_optimizing()); | 1513 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); |
| 1523 value_cid_reg = R3; | |
| 1524 ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg)); | |
| 1525 } | |
| 1526 | 1514 |
| 1527 if (value_cid == kDynamicCid) { | 1515 if (value_cid == kDynamicCid) { |
| 1528 LoadValueCid(compiler, value_cid_reg, value_reg); | 1516 LoadValueCid(compiler, value_cid_reg, value_reg); |
| 1529 Label skip_length_check; | 1517 Label skip_length_check; |
| 1530 __ ldr(IP, field_cid_operand); | 1518 __ ldr(IP, field_cid_operand); |
| 1531 __ cmp(value_cid_reg, ShifterOperand(IP)); | 1519 __ cmp(value_cid_reg, ShifterOperand(IP)); |
| 1532 __ b(&skip_length_check, NE); | 1520 __ b(&skip_length_check, NE); |
| 1533 if (field_has_length) { | 1521 if (field_has_length) { |
| 1534 ASSERT(temp_reg != kNoRegister); | 1522 ASSERT(temp_reg != kNoRegister); |
| 1535 // Field guard may have remembered list length, check it. | 1523 // Field guard may have remembered list length, check it. |
| 1536 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1524 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
| 1537 __ ldr(temp_reg, | 1525 __ ldr(temp_reg, |
| 1538 FieldAddress(value_reg, Array::length_offset())); | 1526 FieldAddress(value_reg, Array::length_offset())); |
| 1539 __ CompareImmediate(temp_reg, field_length); | 1527 __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); |
| 1540 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1528 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| 1541 __ ldr(temp_reg, | 1529 __ ldr(temp_reg, |
| 1542 FieldAddress(value_reg, TypedData::length_offset())); | 1530 FieldAddress(value_reg, TypedData::length_offset())); |
| 1543 __ CompareImmediate(temp_reg, field_length); | 1531 __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); |
| 1544 } else { | 1532 } else { |
| 1545 ASSERT(field_cid == kIllegalCid); | 1533 ASSERT(field_cid == kIllegalCid); |
| 1534 ASSERT(field_length == Field::kUnknownFixedLength); |
| 1535 // At compile time we do not know the type of the field nor its |
| 1536 // length. At execution time we may have set the class id and |
| 1537 // list length so we compare the guarded length with the |
| 1538 // list length here, without this check the list length could change |
| 1539 // without triggering a deoptimization. |
| 1540 Label check_array, length_compared, no_fixed_length; |
| 1541 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1542 __ b(&no_fixed_length, EQ); |
| 1543 // Check for typed data array. |
| 1544 __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid); |
| 1545 __ b(&no_fixed_length, GT); |
| 1546 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1547 // Could still be a regular array. |
| 1548 __ b(&check_array, LT); |
| 1549 __ ldr(temp_reg, |
| 1550 FieldAddress(value_reg, TypedData::length_offset())); |
| 1551 __ ldr(IP, field_length_operand); |
| 1552 __ cmp(temp_reg, ShifterOperand(IP)); |
| 1553 __ b(&length_compared); |
| 1554 // Check for regular array. |
| 1555 __ Bind(&check_array); |
| 1556 __ CompareImmediate(value_cid_reg, kImmutableArrayCid); |
| 1557 __ b(&no_fixed_length, GT); |
| 1558 __ CompareImmediate(value_cid_reg, kArrayCid); |
| 1559 __ b(&no_fixed_length, LT); |
| 1560 __ ldr(temp_reg, |
| 1561 FieldAddress(value_reg, Array::length_offset())); |
| 1562 __ ldr(IP, field_length_operand); |
| 1563 __ cmp(temp_reg, ShifterOperand(IP)); |
| 1564 __ b(&length_compared); |
| 1565 __ Bind(&no_fixed_length); |
| 1566 __ b(fail); |
| 1567 __ Bind(&length_compared); |
| 1546 // Following branch cannot not occur, fall through. | 1568 // Following branch cannot not occur, fall through. |
| 1547 } | 1569 } |
| 1548 __ b(fail, NE); | 1570 __ b(fail, NE); |
| 1549 } | 1571 } |
| 1550 __ Bind(&skip_length_check); | 1572 __ Bind(&skip_length_check); |
| 1551 __ ldr(IP, field_nullability_operand); | 1573 __ ldr(IP, field_nullability_operand); |
| 1552 __ cmp(value_cid_reg, ShifterOperand(IP)); | 1574 __ cmp(value_cid_reg, ShifterOperand(IP)); |
| 1553 } else if (value_cid == kNullCid) { | 1575 } else if (value_cid == kNullCid) { |
| 1554 __ ldr(value_cid_reg, field_nullability_operand); | 1576 __ ldr(value_cid_reg, field_nullability_operand); |
| 1555 __ CompareImmediate(value_cid_reg, value_cid); | 1577 __ CompareImmediate(value_cid_reg, value_cid); |
| 1556 } else { | 1578 } else { |
| 1557 Label skip_length_check; | 1579 Label skip_length_check; |
| 1558 __ ldr(value_cid_reg, field_cid_operand); | 1580 __ ldr(value_cid_reg, field_cid_operand); |
| 1559 __ CompareImmediate(value_cid_reg, value_cid); | 1581 __ CompareImmediate(value_cid_reg, value_cid); |
| 1560 __ b(&skip_length_check, NE); | 1582 __ b(&skip_length_check, NE); |
| 1561 if (field_has_length) { | 1583 if (field_has_length) { |
| 1562 ASSERT(value_cid_reg != kNoRegister); | 1584 ASSERT(value_cid_reg != kNoRegister); |
| 1563 ASSERT(temp_reg != kNoRegister); | 1585 ASSERT(temp_reg != kNoRegister); |
| 1564 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1586 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| 1565 __ ldr(temp_reg, | 1587 __ ldr(temp_reg, |
| 1566 FieldAddress(value_reg, Array::length_offset())); | 1588 FieldAddress(value_reg, Array::length_offset())); |
| 1567 __ CompareImmediate(temp_reg, field_length); | 1589 __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); |
| 1568 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1590 } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| 1569 __ ldr(temp_reg, | 1591 __ ldr(temp_reg, |
| 1570 FieldAddress(value_reg, TypedData::length_offset())); | 1592 FieldAddress(value_reg, TypedData::length_offset())); |
| 1571 __ CompareImmediate(temp_reg, field_length); | 1593 __ CompareImmediate(temp_reg, Smi::RawValue(field_length)); |
| 1594 } else if (field_cid != kIllegalCid) { |
| 1595 ASSERT(field_cid != value_cid); |
| 1596 ASSERT(field_length >= 0); |
| 1597 // Field has a known class id and length. At compile time it is |
| 1598 // known that the value's class id is not a fixed length list. |
| 1599 __ b(fail); |
| 1572 } else { | 1600 } else { |
| 1573 ASSERT(field_cid == kIllegalCid); | 1601 ASSERT(field_cid == kIllegalCid); |
| 1602 ASSERT(field_length == Field::kUnknownFixedLength); |
| 1574 // Following jump cannot not occur, fall through. | 1603 // Following jump cannot not occur, fall through. |
| 1575 } | 1604 } |
| 1605 __ b(fail, NE); |
| 1576 } | 1606 } |
| 1577 // Not identical, possibly null. | 1607 // Not identical, possibly null. |
| 1578 __ Bind(&skip_length_check); | 1608 __ Bind(&skip_length_check); |
| 1579 } | 1609 } |
| 1580 __ b(&ok, EQ); | 1610 __ b(&ok, EQ); |
| 1581 | 1611 |
| 1582 __ ldr(IP, field_cid_operand); | 1612 __ ldr(IP, field_cid_operand); |
| 1583 __ CompareImmediate(IP, kIllegalCid); | 1613 __ CompareImmediate(IP, kIllegalCid); |
| 1584 __ b(fail, NE); | 1614 __ b(fail, NE); |
| 1585 | 1615 |
| 1586 if (value_cid == kDynamicCid) { | 1616 if (value_cid == kDynamicCid) { |
| 1587 __ str(value_cid_reg, field_cid_operand); | 1617 __ str(value_cid_reg, field_cid_operand); |
| 1588 __ str(value_cid_reg, field_nullability_operand); | 1618 __ str(value_cid_reg, field_nullability_operand); |
| 1589 if (field_has_length) { | 1619 if (field_has_length) { |
| 1590 Label check_array, local_exit, local_fail; | 1620 Label check_array, length_set, no_fixed_length; |
| 1591 __ CompareImmediate(value_cid_reg, kNullCid); | 1621 __ CompareImmediate(value_cid_reg, kNullCid); |
| 1592 __ b(&local_fail, EQ); | 1622 __ b(&no_fixed_length, EQ); |
| 1593 // Check for typed data array. | 1623 // Check for typed data array. |
| 1594 __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid); | 1624 __ CompareImmediate(value_cid_reg, kTypedDataFloat32x4ArrayCid); |
| 1595 __ b(&local_fail, GT); | 1625 __ b(&no_fixed_length, GT); |
| 1596 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); | 1626 __ CompareImmediate(value_cid_reg, kTypedDataInt8ArrayCid); |
| 1597 __ b(&check_array, LT); // Could still be a regular array. | 1627 // Could still be a regular array. |
| 1628 __ b(&check_array, LT); |
| 1598 // Destroy value_cid_reg (safe because we are finished with it). | 1629 // Destroy value_cid_reg (safe because we are finished with it). |
| 1599 __ ldr(value_cid_reg, | 1630 __ ldr(value_cid_reg, |
| 1600 FieldAddress(value_reg, TypedData::length_offset())); | 1631 FieldAddress(value_reg, TypedData::length_offset())); |
| 1601 __ str(value_cid_reg, field_length_operand); | 1632 __ str(value_cid_reg, field_length_operand); |
| 1602 __ b(&local_exit); // Updated field length typed data array. | 1633 __ b(&length_set); // Updated field length typed data array. |
| 1603 // Check for regular array. | 1634 // Check for regular array. |
| 1604 __ Bind(&check_array); | 1635 __ Bind(&check_array); |
| 1605 __ CompareImmediate(value_cid_reg, kImmutableArrayCid); | 1636 __ CompareImmediate(value_cid_reg, kImmutableArrayCid); |
| 1606 __ b(&local_fail, GT); | 1637 __ b(&no_fixed_length, GT); |
| 1607 __ CompareImmediate(value_cid_reg, kArrayCid); | 1638 __ CompareImmediate(value_cid_reg, kArrayCid); |
| 1608 __ b(&local_fail, LT); | 1639 __ b(&no_fixed_length, LT); |
| 1609 // Destroy value_cid_reg (safe because we are finished with it). | 1640 // Destroy value_cid_reg (safe because we are finished with it). |
| 1610 __ ldr(value_cid_reg, | 1641 __ ldr(value_cid_reg, |
| 1611 FieldAddress(value_reg, Array::length_offset())); | 1642 FieldAddress(value_reg, Array::length_offset())); |
| 1612 __ str(value_cid_reg, field_length_operand); | 1643 __ str(value_cid_reg, field_length_operand); |
| 1613 __ b(&local_exit); // Updated field length from regular array. | 1644 // Updated field length from regular array. |
| 1614 | 1645 __ b(&length_set); |
| 1615 __ Bind(&local_fail); | 1646 __ Bind(&no_fixed_length); |
| 1616 __ LoadImmediate(IP, Field::kNoFixedLength); | 1647 __ LoadImmediate(IP, Smi::RawValue(Field::kNoFixedLength)); |
| 1617 __ str(IP, field_length_operand); | 1648 __ str(IP, field_length_operand); |
| 1618 | 1649 __ Bind(&length_set); |
| 1619 __ Bind(&local_exit); | |
| 1620 } | 1650 } |
| 1621 } else { | 1651 } else { |
| 1622 __ LoadImmediate(IP, value_cid); | 1652 __ LoadImmediate(IP, value_cid); |
| 1623 __ str(IP, field_cid_operand); | 1653 __ str(IP, field_cid_operand); |
| 1624 __ str(IP, field_nullability_operand); | 1654 __ str(IP, field_nullability_operand); |
| 1625 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { | 1655 if (field_has_length) { |
| 1626 // Destroy value_cid_reg (safe because we are finished with it). | 1656 if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| 1627 __ ldr(value_cid_reg, | 1657 // Destroy value_cid_reg (safe because we are finished with it). |
| 1628 FieldAddress(value_reg, Array::length_offset())); | 1658 __ ldr(value_cid_reg, |
| 1629 __ str(value_cid_reg, field_length_operand); | 1659 FieldAddress(value_reg, Array::length_offset())); |
| 1630 } else if (RawObject::IsTypedDataClassId(value_cid)) { | 1660 __ str(value_cid_reg, field_length_operand); |
| 1631 // Destroy value_cid_reg (safe because we are finished with it). | 1661 } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| 1632 __ ldr(value_cid_reg, | 1662 // Destroy value_cid_reg (safe because we are finished with it). |
| 1633 FieldAddress(value_reg, TypedData::length_offset())); | 1663 __ ldr(value_cid_reg, |
| 1634 __ str(value_cid_reg, field_length_operand); | 1664 FieldAddress(value_reg, TypedData::length_offset())); |
| 1635 } else { | 1665 __ str(value_cid_reg, field_length_operand); |
| 1636 __ LoadImmediate(IP, Field::kNoFixedLength); | 1666 } else { |
| 1637 __ str(IP, field_length_operand); | 1667 __ LoadImmediate(IP, Smi::RawValue(Field::kNoFixedLength)); |
| 1668 __ str(IP, field_length_operand); |
| 1669 } |
| 1638 } | 1670 } |
| 1639 } | 1671 } |
| 1640 | |
| 1641 if (!ok_is_fall_through) { | 1672 if (!ok_is_fall_through) { |
| 1642 __ b(&ok); | 1673 __ b(&ok); |
| 1643 } | 1674 } |
| 1644 } else { | 1675 } else { |
| 1645 if (field_reg != kNoRegister) { | 1676 if (field_reg != kNoRegister) { |
| 1646 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); | 1677 __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
| 1647 } | 1678 } |
| 1648 if (value_cid == kDynamicCid) { | 1679 if (value_cid == kDynamicCid) { |
| 1649 // Field's guarded class id is fixed by value's class id is not known. | 1680 // Field's guarded class id is fixed by value's class id is not known. |
| 1650 __ tst(value_reg, ShifterOperand(kSmiTagMask)); | 1681 __ tst(value_reg, ShifterOperand(kSmiTagMask)); |
| (...skipping 2985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4636 compiler->GenerateCall(token_pos(), | 4667 compiler->GenerateCall(token_pos(), |
| 4637 &label, | 4668 &label, |
| 4638 PcDescriptors::kOther, | 4669 PcDescriptors::kOther, |
| 4639 locs()); | 4670 locs()); |
| 4640 __ Drop(2); // Discard type arguments and receiver. | 4671 __ Drop(2); // Discard type arguments and receiver. |
| 4641 } | 4672 } |
| 4642 | 4673 |
| 4643 } // namespace dart | 4674 } // namespace dart |
| 4644 | 4675 |
| 4645 #endif // defined TARGET_ARCH_ARM | 4676 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |