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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 __ movq(field_length_operand, value_cid_reg); | 1383 __ movq(field_length_operand, value_cid_reg); |
1384 } else { | 1384 } else { |
1385 __ LoadImmediate(field_length_operand, | 1385 __ LoadImmediate(field_length_operand, |
1386 Immediate(Smi::RawValue(Field::kNoFixedLength)), PP); | 1386 Immediate(Smi::RawValue(Field::kNoFixedLength)), PP); |
1387 } | 1387 } |
1388 } | 1388 } |
1389 } | 1389 } |
1390 if (!ok_is_fall_through) { | 1390 if (!ok_is_fall_through) { |
1391 __ jmp(&ok); | 1391 __ jmp(&ok); |
1392 } | 1392 } |
| 1393 |
| 1394 if (deopt == NULL) { |
| 1395 ASSERT(!compiler->is_optimizing()); |
| 1396 __ Bind(fail); |
| 1397 |
| 1398 __ CompareImmediate(FieldAddress(field_reg, Field::guarded_cid_offset()), |
| 1399 Immediate(kDynamicCid), PP); |
| 1400 __ j(EQUAL, &ok); |
| 1401 |
| 1402 __ pushq(field_reg); |
| 1403 __ pushq(value_reg); |
| 1404 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); |
| 1405 __ Drop(2); // Drop the field and the value. |
| 1406 } |
1393 } else { | 1407 } else { |
| 1408 ASSERT(compiler->is_optimizing()); |
| 1409 ASSERT(deopt != NULL); |
| 1410 ASSERT(ok_is_fall_through); |
| 1411 // Field guard class has been initialized and is known. |
1394 if (field_reg != kNoRegister) { | 1412 if (field_reg != kNoRegister) { |
1395 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); | 1413 __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); |
1396 } | 1414 } |
1397 | 1415 |
1398 if (value_cid == kDynamicCid) { | 1416 if (value_cid == kDynamicCid) { |
1399 // Field's guarded class id is fixed but value's class id is not known. | 1417 // Field's guarded class id is fixed but value's class id is not known. |
1400 __ testq(value_reg, Immediate(kSmiTagMask)); | 1418 __ testq(value_reg, Immediate(kSmiTagMask)); |
1401 | 1419 |
1402 if (field_cid != kSmiCid) { | 1420 if (field_cid != kSmiCid) { |
1403 __ j(ZERO, fail); | 1421 __ j(ZERO, fail); |
(...skipping 19 matching lines...) Expand all Loading... |
1423 __ movq(value_cid_reg, | 1441 __ movq(value_cid_reg, |
1424 FieldAddress(value_reg, TypedData::length_offset())); | 1442 FieldAddress(value_reg, TypedData::length_offset())); |
1425 } | 1443 } |
1426 __ cmpq(value_cid_reg, field_length_operand); | 1444 __ cmpq(value_cid_reg, field_length_operand); |
1427 } | 1445 } |
1428 | 1446 |
1429 if (field().is_nullable() && (field_cid != kNullCid)) { | 1447 if (field().is_nullable() && (field_cid != kNullCid)) { |
1430 __ j(EQUAL, &ok); | 1448 __ j(EQUAL, &ok); |
1431 __ CompareObject(value_reg, Object::null_object(), PP); | 1449 __ CompareObject(value_reg, Object::null_object(), PP); |
1432 } | 1450 } |
1433 | 1451 __ j(NOT_EQUAL, fail); |
1434 if (ok_is_fall_through) { | |
1435 __ j(NOT_EQUAL, fail); | |
1436 } else { | |
1437 __ j(EQUAL, &ok); | |
1438 } | |
1439 } else { | 1452 } else { |
1440 // Both value's and field's class id is known. | 1453 // Both value's and field's class id is known. |
1441 if ((value_cid != field_cid) && (value_cid != nullability)) { | 1454 if ((value_cid != field_cid) && (value_cid != nullability)) { |
1442 if (ok_is_fall_through) { | 1455 __ jmp(fail); |
1443 __ jmp(fail); | |
1444 } | |
1445 } else if (field_has_length && (value_cid == field_cid)) { | 1456 } else if (field_has_length && (value_cid == field_cid)) { |
1446 ASSERT(value_cid_reg != kNoRegister); | 1457 ASSERT(value_cid_reg != kNoRegister); |
1447 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { | 1458 if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) { |
1448 // Destroy value_cid_reg (safe because we are finished with it). | 1459 // Destroy value_cid_reg (safe because we are finished with it). |
1449 __ movq(value_cid_reg, | 1460 __ movq(value_cid_reg, |
1450 FieldAddress(value_reg, Array::length_offset())); | 1461 FieldAddress(value_reg, Array::length_offset())); |
1451 } else if (RawObject::IsTypedDataClassId(field_cid)) { | 1462 } else if (RawObject::IsTypedDataClassId(field_cid)) { |
1452 // Destroy value_cid_reg (safe because we are finished with it). | 1463 // Destroy value_cid_reg (safe because we are finished with it). |
1453 __ movq(value_cid_reg, | 1464 __ movq(value_cid_reg, |
1454 FieldAddress(value_reg, TypedData::length_offset())); | 1465 FieldAddress(value_reg, TypedData::length_offset())); |
1455 } | 1466 } |
1456 __ CompareImmediate( | 1467 __ CompareImmediate( |
1457 value_cid_reg, Immediate(Smi::RawValue(field_length)), PP); | 1468 value_cid_reg, Immediate(Smi::RawValue(field_length)), PP); |
1458 if (ok_is_fall_through) { | 1469 __ j(NOT_EQUAL, fail); |
1459 __ j(NOT_EQUAL, fail); | |
1460 } | |
1461 } else { | 1470 } else { |
1462 // Nothing to emit. | 1471 UNREACHABLE(); |
1463 ASSERT(!compiler->is_optimizing()); | |
1464 return; | |
1465 } | 1472 } |
1466 } | 1473 } |
1467 } | 1474 } |
1468 | |
1469 if (deopt == NULL) { | |
1470 ASSERT(!compiler->is_optimizing()); | |
1471 __ Bind(fail); | |
1472 | |
1473 __ CompareImmediate(FieldAddress(field_reg, Field::guarded_cid_offset()), | |
1474 Immediate(kDynamicCid), PP); | |
1475 __ j(EQUAL, &ok); | |
1476 | |
1477 __ pushq(field_reg); | |
1478 __ pushq(value_reg); | |
1479 __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2); | |
1480 __ Drop(2); // Drop the field and the value. | |
1481 } | |
1482 | |
1483 __ Bind(&ok); | 1475 __ Bind(&ok); |
1484 } | 1476 } |
1485 | 1477 |
1486 | 1478 |
1487 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { | 1479 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const { |
1488 const intptr_t kNumInputs = 2; | 1480 const intptr_t kNumInputs = 2; |
1489 const intptr_t kNumTemps = 0; | 1481 const intptr_t kNumTemps = 0; |
1490 LocationSummary* summary = | 1482 LocationSummary* summary = |
1491 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1483 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
1492 summary->set_in(0, Location::RequiresRegister()); | 1484 summary->set_in(0, Location::RequiresRegister()); |
(...skipping 3259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4752 PcDescriptors::kOther, | 4744 PcDescriptors::kOther, |
4753 locs()); | 4745 locs()); |
4754 __ Drop(2); // Discard type arguments and receiver. | 4746 __ Drop(2); // Discard type arguments and receiver. |
4755 } | 4747 } |
4756 | 4748 |
4757 } // namespace dart | 4749 } // namespace dart |
4758 | 4750 |
4759 #undef __ | 4751 #undef __ |
4760 | 4752 |
4761 #endif // defined TARGET_ARCH_X64 | 4753 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |