| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 Label ok, fail_label; | 1409 Label ok, fail_label; |
| 1410 | 1410 |
| 1411 Label* deopt = compiler->is_optimizing() ? | 1411 Label* deopt = compiler->is_optimizing() ? |
| 1412 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; | 1412 compiler->AddDeoptStub(deopt_id(), ICData::kDeoptGuardField) : NULL; |
| 1413 | 1413 |
| 1414 Label* fail = (deopt != NULL) ? deopt : &fail_label; | 1414 Label* fail = (deopt != NULL) ? deopt : &fail_label; |
| 1415 | 1415 |
| 1416 if (emit_full_guard) { | 1416 if (emit_full_guard) { |
| 1417 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); | 1417 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); |
| 1418 | 1418 |
| 1419 FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); | 1419 FieldAddress field_cid_operand( |
| 1420 field_reg, Field::guarded_cid_offset(), kWord); |
| 1420 FieldAddress field_nullability_operand( | 1421 FieldAddress field_nullability_operand( |
| 1421 field_reg, Field::is_nullable_offset()); | 1422 field_reg, Field::is_nullable_offset(), kWord); |
| 1422 | 1423 |
| 1423 if (value_cid == kDynamicCid) { | 1424 if (value_cid == kDynamicCid) { |
| 1424 LoadValueCid(compiler, value_cid_reg, value_reg); | 1425 LoadValueCid(compiler, value_cid_reg, value_reg); |
| 1425 Label skip_length_check; | 1426 Label skip_length_check; |
| 1426 __ ldr(TMP, field_cid_operand); | 1427 __ ldr(TMP, field_cid_operand, kWord); |
| 1427 __ CompareRegisters(value_cid_reg, TMP); | 1428 __ CompareRegisters(value_cid_reg, TMP); |
| 1428 __ b(&ok, EQ); | 1429 __ b(&ok, EQ); |
| 1429 __ ldr(TMP, field_nullability_operand); | 1430 __ ldr(TMP, field_nullability_operand, kWord); |
| 1430 __ CompareRegisters(value_cid_reg, TMP); | 1431 __ CompareRegisters(value_cid_reg, TMP); |
| 1431 } else if (value_cid == kNullCid) { | 1432 } else if (value_cid == kNullCid) { |
| 1432 __ ldr(value_cid_reg, field_nullability_operand); | 1433 __ ldr(value_cid_reg, field_nullability_operand, kWord); |
| 1433 __ CompareImmediate(value_cid_reg, value_cid, PP); | 1434 __ CompareImmediate(value_cid_reg, value_cid, PP); |
| 1434 } else { | 1435 } else { |
| 1435 Label skip_length_check; | 1436 Label skip_length_check; |
| 1436 __ ldr(value_cid_reg, field_cid_operand); | 1437 __ ldr(value_cid_reg, field_cid_operand, kWord); |
| 1437 __ CompareImmediate(value_cid_reg, value_cid, PP); | 1438 __ CompareImmediate(value_cid_reg, value_cid, PP); |
| 1438 } | 1439 } |
| 1439 __ b(&ok, EQ); | 1440 __ b(&ok, EQ); |
| 1440 | 1441 |
| 1441 // Check if the tracked state of the guarded field can be initialized | 1442 // Check if the tracked state of the guarded field can be initialized |
| 1442 // inline. If the field needs length check we fall through to runtime | 1443 // inline. If the field needs length check we fall through to runtime |
| 1443 // which is responsible for computing offset of the length field | 1444 // which is responsible for computing offset of the length field |
| 1444 // based on the class id. | 1445 // based on the class id. |
| 1445 // Length guard will be emitted separately when needed via GuardFieldLength | 1446 // Length guard will be emitted separately when needed via GuardFieldLength |
| 1446 // instruction after GuardFieldClass. | 1447 // instruction after GuardFieldClass. |
| 1447 if (!field().needs_length_check()) { | 1448 if (!field().needs_length_check()) { |
| 1448 // Uninitialized field can be handled inline. Check if the | 1449 // Uninitialized field can be handled inline. Check if the |
| 1449 // field is still unitialized. | 1450 // field is still unitialized. |
| 1450 __ ldr(TMP, field_cid_operand); | 1451 __ ldr(TMP, field_cid_operand, kWord); |
| 1451 __ CompareImmediate(TMP, kIllegalCid, PP); | 1452 __ CompareImmediate(TMP, kIllegalCid, PP); |
| 1452 __ b(fail, NE); | 1453 __ b(fail, NE); |
| 1453 | 1454 |
| 1454 if (value_cid == kDynamicCid) { | 1455 if (value_cid == kDynamicCid) { |
| 1455 __ str(value_cid_reg, field_cid_operand); | 1456 __ str(value_cid_reg, field_cid_operand, kWord); |
| 1456 __ str(value_cid_reg, field_nullability_operand); | 1457 __ str(value_cid_reg, field_nullability_operand, kWord); |
| 1457 } else { | 1458 } else { |
| 1458 __ LoadImmediate(TMP, value_cid, PP); | 1459 __ LoadImmediate(TMP, value_cid, PP); |
| 1459 __ str(TMP, field_cid_operand); | 1460 __ str(TMP, field_cid_operand, kWord); |
| 1460 __ str(TMP, field_nullability_operand); | 1461 __ str(TMP, field_nullability_operand, kWord); |
| 1461 } | 1462 } |
| 1462 | 1463 |
| 1463 if (deopt == NULL) { | 1464 if (deopt == NULL) { |
| 1464 ASSERT(!compiler->is_optimizing()); | 1465 ASSERT(!compiler->is_optimizing()); |
| 1465 __ b(&ok); | 1466 __ b(&ok); |
| 1466 } | 1467 } |
| 1467 } | 1468 } |
| 1468 | 1469 |
| 1469 if (deopt == NULL) { | 1470 if (deopt == NULL) { |
| 1470 ASSERT(!compiler->is_optimizing()); | 1471 ASSERT(!compiler->is_optimizing()); |
| 1471 __ Bind(fail); | 1472 __ Bind(fail); |
| 1472 | 1473 |
| 1473 __ LoadFieldFromOffset(TMP, field_reg, Field::guarded_cid_offset(), PP); | 1474 __ LoadFieldFromOffset( |
| 1475 TMP, field_reg, Field::guarded_cid_offset(), PP, kWord); |
| 1474 __ CompareImmediate(TMP, kDynamicCid, PP); | 1476 __ CompareImmediate(TMP, kDynamicCid, PP); |
| 1475 __ b(&ok, EQ); | 1477 __ b(&ok, EQ); |
| 1476 | 1478 |
| 1477 __ Push(field_reg); | 1479 __ Push(field_reg); |
| 1478 __ Push(value_reg); | 1480 __ Push(value_reg); |
| 1479 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); | 1481 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
| 1480 __ Drop(2); // Drop the field and the value. | 1482 __ Drop(2); // Drop the field and the value. |
| 1481 } | 1483 } |
| 1482 } else { | 1484 } else { |
| 1483 ASSERT(compiler->is_optimizing()); | 1485 ASSERT(compiler->is_optimizing()); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1730 const Register temp = locs()->temp(0).reg(); | 1732 const Register temp = locs()->temp(0).reg(); |
| 1731 const Register temp2 = locs()->temp(1).reg(); | 1733 const Register temp2 = locs()->temp(1).reg(); |
| 1732 | 1734 |
| 1733 Label store_pointer; | 1735 Label store_pointer; |
| 1734 Label store_double; | 1736 Label store_double; |
| 1735 Label store_float32x4; | 1737 Label store_float32x4; |
| 1736 Label store_float64x2; | 1738 Label store_float64x2; |
| 1737 | 1739 |
| 1738 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); | 1740 __ LoadObject(temp, Field::ZoneHandle(field().raw()), PP); |
| 1739 | 1741 |
| 1740 __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(), PP); | 1742 __ LoadFieldFromOffset(temp2, temp, Field::is_nullable_offset(), PP, kWord); |
| 1741 __ CompareImmediate(temp2, kNullCid, PP); | 1743 __ CompareImmediate(temp2, kNullCid, PP); |
| 1742 __ b(&store_pointer, EQ); | 1744 __ b(&store_pointer, EQ); |
| 1743 | 1745 |
| 1744 __ LoadFromOffset( | 1746 __ LoadFromOffset( |
| 1745 temp2, temp, Field::kind_bits_offset() - kHeapObjectTag, | 1747 temp2, temp, Field::kind_bits_offset() - kHeapObjectTag, |
| 1746 PP, kUnsignedByte); | 1748 PP, kUnsignedByte); |
| 1747 __ tsti(temp2, 1 << Field::kUnboxingCandidateBit); | 1749 __ tsti(temp2, 1 << Field::kUnboxingCandidateBit); |
| 1748 __ b(&store_pointer, EQ); | 1750 __ b(&store_pointer, EQ); |
| 1749 | 1751 |
| 1750 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP); | 1752 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, kWord); |
| 1751 __ CompareImmediate(temp2, kDoubleCid, PP); | 1753 __ CompareImmediate(temp2, kDoubleCid, PP); |
| 1752 __ b(&store_double, EQ); | 1754 __ b(&store_double, EQ); |
| 1753 | 1755 |
| 1754 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP); | 1756 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, kWord); |
| 1755 __ CompareImmediate(temp2, kFloat32x4Cid, PP); | 1757 __ CompareImmediate(temp2, kFloat32x4Cid, PP); |
| 1756 __ b(&store_float32x4, EQ); | 1758 __ b(&store_float32x4, EQ); |
| 1757 | 1759 |
| 1758 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP); | 1760 __ LoadFieldFromOffset(temp2, temp, Field::guarded_cid_offset(), PP, kWord); |
| 1759 __ CompareImmediate(temp2, kFloat64x2Cid, PP); | 1761 __ CompareImmediate(temp2, kFloat64x2Cid, PP); |
| 1760 __ b(&store_float64x2, EQ); | 1762 __ b(&store_float64x2, EQ); |
| 1761 | 1763 |
| 1762 // Fall through. | 1764 // Fall through. |
| 1763 __ b(&store_pointer); | 1765 __ b(&store_pointer); |
| 1764 | 1766 |
| 1765 if (!compiler->is_optimizing()) { | 1767 if (!compiler->is_optimizing()) { |
| 1766 locs()->live_registers()->Add(locs()->in(0)); | 1768 locs()->live_registers()->Add(locs()->in(0)); |
| 1767 locs()->live_registers()->Add(locs()->in(1)); | 1769 locs()->live_registers()->Add(locs()->in(1)); |
| 1768 } | 1770 } |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2117 if (IsPotentialUnboxedLoad()) { | 2119 if (IsPotentialUnboxedLoad()) { |
| 2118 const Register temp = locs()->temp(0).reg(); | 2120 const Register temp = locs()->temp(0).reg(); |
| 2119 | 2121 |
| 2120 Label load_pointer; | 2122 Label load_pointer; |
| 2121 Label load_double; | 2123 Label load_double; |
| 2122 Label load_float32x4; | 2124 Label load_float32x4; |
| 2123 Label load_float64x2; | 2125 Label load_float64x2; |
| 2124 | 2126 |
| 2125 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()), PP); | 2127 __ LoadObject(result_reg, Field::ZoneHandle(field()->raw()), PP); |
| 2126 | 2128 |
| 2127 FieldAddress field_cid_operand(result_reg, Field::guarded_cid_offset()); | 2129 FieldAddress field_cid_operand( |
| 2128 FieldAddress field_nullability_operand(result_reg, | 2130 result_reg, Field::guarded_cid_offset(), kWord); |
| 2129 Field::is_nullable_offset()); | 2131 FieldAddress field_nullability_operand( |
| 2132 result_reg, Field::is_nullable_offset(), kWord); |
| 2130 | 2133 |
| 2131 __ ldr(temp, field_nullability_operand); | 2134 __ ldr(temp, field_nullability_operand, kWord); |
| 2132 __ CompareImmediate(temp, kNullCid, PP); | 2135 __ CompareImmediate(temp, kNullCid, PP); |
| 2133 __ b(&load_pointer, EQ); | 2136 __ b(&load_pointer, EQ); |
| 2134 | 2137 |
| 2135 __ ldr(temp, field_cid_operand); | 2138 __ ldr(temp, field_cid_operand, kWord); |
| 2136 __ CompareImmediate(temp, kDoubleCid, PP); | 2139 __ CompareImmediate(temp, kDoubleCid, PP); |
| 2137 __ b(&load_double, EQ); | 2140 __ b(&load_double, EQ); |
| 2138 | 2141 |
| 2139 __ ldr(temp, field_cid_operand); | 2142 __ ldr(temp, field_cid_operand, kWord); |
| 2140 __ CompareImmediate(temp, kFloat32x4Cid, PP); | 2143 __ CompareImmediate(temp, kFloat32x4Cid, PP); |
| 2141 __ b(&load_float32x4, EQ); | 2144 __ b(&load_float32x4, EQ); |
| 2142 | 2145 |
| 2143 __ ldr(temp, field_cid_operand); | 2146 __ ldr(temp, field_cid_operand, kWord); |
| 2144 __ CompareImmediate(temp, kFloat64x2Cid, PP); | 2147 __ CompareImmediate(temp, kFloat64x2Cid, PP); |
| 2145 __ b(&load_float64x2, EQ); | 2148 __ b(&load_float64x2, EQ); |
| 2146 | 2149 |
| 2147 // Fall through. | 2150 // Fall through. |
| 2148 __ b(&load_pointer); | 2151 __ b(&load_pointer); |
| 2149 | 2152 |
| 2150 if (!compiler->is_optimizing()) { | 2153 if (!compiler->is_optimizing()) { |
| 2151 locs()->live_registers()->Add(locs()->in(0)); | 2154 locs()->live_registers()->Add(locs()->in(0)); |
| 2152 } | 2155 } |
| 2153 | 2156 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2468 __ CompareRegisters(SP, TMP); | 2471 __ CompareRegisters(SP, TMP); |
| 2469 __ b(slow_path->entry_label(), LS); | 2472 __ b(slow_path->entry_label(), LS); |
| 2470 if (compiler->CanOSRFunction() && in_loop()) { | 2473 if (compiler->CanOSRFunction() && in_loop()) { |
| 2471 const Register temp = locs()->temp(0).reg(); | 2474 const Register temp = locs()->temp(0).reg(); |
| 2472 // In unoptimized code check the usage counter to trigger OSR at loop | 2475 // In unoptimized code check the usage counter to trigger OSR at loop |
| 2473 // stack checks. Use progressively higher thresholds for more deeply | 2476 // stack checks. Use progressively higher thresholds for more deeply |
| 2474 // nested loops to attempt to hit outer loops with OSR when possible. | 2477 // nested loops to attempt to hit outer loops with OSR when possible. |
| 2475 __ LoadObject(temp, compiler->parsed_function().function(), PP); | 2478 __ LoadObject(temp, compiler->parsed_function().function(), PP); |
| 2476 intptr_t threshold = | 2479 intptr_t threshold = |
| 2477 FLAG_optimization_counter_threshold * (loop_depth() + 1); | 2480 FLAG_optimization_counter_threshold * (loop_depth() + 1); |
| 2478 __ LoadFieldFromOffset(temp, temp, Function::usage_counter_offset(), PP); | 2481 __ LoadFieldFromOffset( |
| 2482 temp, temp, Function::usage_counter_offset(), PP, kWord); |
| 2479 __ CompareImmediate(temp, threshold, PP); | 2483 __ CompareImmediate(temp, threshold, PP); |
| 2480 __ b(slow_path->osr_entry_label(), GE); | 2484 __ b(slow_path->osr_entry_label(), GE); |
| 2481 } | 2485 } |
| 2482 if (compiler->ForceSlowPathForStackOverflow()) { | 2486 if (compiler->ForceSlowPathForStackOverflow()) { |
| 2483 __ b(slow_path->entry_label()); | 2487 __ b(slow_path->entry_label()); |
| 2484 } | 2488 } |
| 2485 __ Bind(slow_path->exit_label()); | 2489 __ Bind(slow_path->exit_label()); |
| 2486 } | 2490 } |
| 2487 | 2491 |
| 2488 | 2492 |
| (...skipping 2839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5328 compiler->GenerateCall(token_pos(), | 5332 compiler->GenerateCall(token_pos(), |
| 5329 &label, | 5333 &label, |
| 5330 PcDescriptors::kOther, | 5334 PcDescriptors::kOther, |
| 5331 locs()); | 5335 locs()); |
| 5332 __ Drop(ArgumentCount()); // Discard arguments. | 5336 __ Drop(ArgumentCount()); // Discard arguments. |
| 5333 } | 5337 } |
| 5334 | 5338 |
| 5335 } // namespace dart | 5339 } // namespace dart |
| 5336 | 5340 |
| 5337 #endif // defined TARGET_ARCH_ARM64 | 5341 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |