| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); | 24 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
| 25 DECLARE_FLAG(bool, inline_alloc); | 25 DECLARE_FLAG(bool, inline_alloc); |
| 26 | 26 |
| 27 | 27 |
| 28 Assembler::Assembler(bool use_far_branches) | 28 Assembler::Assembler(bool use_far_branches) |
| 29 : buffer_(), | 29 : buffer_(), |
| 30 object_pool_(GrowableObjectArray::Handle()), | 30 object_pool_(GrowableObjectArray::Handle()), |
| 31 patchable_pool_entries_(), | 31 patchable_pool_entries_(), |
| 32 prologue_offset_(-1), | 32 prologue_offset_(-1), |
| 33 use_far_branches_(use_far_branches), | 33 use_far_branches_(use_far_branches), |
| 34 comments_() { | 34 comments_(), |
| 35 allow_constant_pool_(true) { |
| 35 if (Isolate::Current() != Dart::vm_isolate()) { | 36 if (Isolate::Current() != Dart::vm_isolate()) { |
| 36 object_pool_ = GrowableObjectArray::New(Heap::kOld); | 37 object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| 37 | 38 |
| 38 // These objects and labels need to be accessible through every pool-pointer | 39 // These objects and labels need to be accessible through every pool-pointer |
| 39 // at the same index. | 40 // at the same index. |
| 40 object_pool_.Add(Object::null_object(), Heap::kOld); | 41 object_pool_.Add(Object::null_object(), Heap::kOld); |
| 41 patchable_pool_entries_.Add(kNotPatchable); | 42 patchable_pool_entries_.Add(kNotPatchable); |
| 42 // Not adding Object::null() to the index table. It is at index 0 in the | 43 // Not adding Object::null() to the index table. It is at index 0 in the |
| 43 // object pool, but the HashMap uses 0 to indicate not found. | 44 // object pool, but the HashMap uses 0 to indicate not found. |
| 44 | 45 |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 | 481 |
| 481 | 482 |
| 482 intptr_t Assembler::FindImmediate(int64_t imm) { | 483 intptr_t Assembler::FindImmediate(int64_t imm) { |
| 483 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 484 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| 484 ASSERT(!object_pool_.IsNull()); | 485 ASSERT(!object_pool_.IsNull()); |
| 485 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); | 486 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); |
| 486 return FindObject(smi, kNotPatchable); | 487 return FindObject(smi, kNotPatchable); |
| 487 } | 488 } |
| 488 | 489 |
| 489 | 490 |
| 491 // A set of VM objects that are present in every constant pool. |
| 492 static bool IsAlwaysInConstantPool(const Object& object) { |
| 493 // TODO(zra): Evaluate putting all VM heap objects into the pool. |
| 494 return (object.raw() == Object::null()) |
| 495 || (object.raw() == Bool::True().raw()) |
| 496 || (object.raw() == Bool::False().raw()); |
| 497 } |
| 498 |
| 499 |
| 490 bool Assembler::CanLoadObjectFromPool(const Object& object) { | 500 bool Assembler::CanLoadObjectFromPool(const Object& object) { |
| 501 if (!allow_constant_pool()) { |
| 502 return IsAlwaysInConstantPool(object); |
| 503 } |
| 504 |
| 491 // TODO(zra, kmillikin): Also load other large immediates from the object | 505 // TODO(zra, kmillikin): Also load other large immediates from the object |
| 492 // pool | 506 // pool |
| 493 if (object.IsSmi()) { | 507 if (object.IsSmi()) { |
| 494 // If the raw smi does not fit into a 32-bit signed int, then we'll keep | 508 // If the raw smi does not fit into a 32-bit signed int, then we'll keep |
| 495 // the raw value in the object pool. | 509 // the raw value in the object pool. |
| 496 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); | 510 return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw())); |
| 497 } | 511 } |
| 498 ASSERT(object.IsNotTemporaryScopedHandle()); | 512 ASSERT(object.IsNotTemporaryScopedHandle()); |
| 499 ASSERT(object.IsOld()); | 513 ASSERT(object.IsOld()); |
| 500 return (Isolate::Current() != Dart::vm_isolate()) && | 514 return (Isolate::Current() != Dart::vm_isolate()) && |
| 501 // Not in the VMHeap, OR is one of the VMHeap objects we put in every | 515 // Not in the VMHeap, OR is one of the VMHeap objects we put in every |
| 502 // object pool. | 516 // object pool. |
| 503 // TODO(zra): Evaluate putting all VM heap objects into the pool. | 517 (!object.InVMHeap() || IsAlwaysInConstantPool(object)); |
| 504 (!object.InVMHeap() || (object.raw() == Object::null()) || | |
| 505 (object.raw() == Bool::True().raw()) || | |
| 506 (object.raw() == Bool::False().raw())); | |
| 507 } | 518 } |
| 508 | 519 |
| 509 | 520 |
| 510 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { | 521 bool Assembler::CanLoadImmediateFromPool(int64_t imm, Register pp) { |
| 522 if (!allow_constant_pool()) { |
| 523 return false; |
| 524 } |
| 511 return !Utils::IsInt(32, imm) && | 525 return !Utils::IsInt(32, imm) && |
| 512 (pp != kNoPP) && | 526 (pp != kNoPP) && |
| 513 // We *could* put constants in the pool in a VM isolate, but it is | 527 // We *could* put constants in the pool in a VM isolate, but it is |
| 514 // simpler to maintain the invariant that the object pool is not used | 528 // simpler to maintain the invariant that the object pool is not used |
| 515 // in the VM isolate. | 529 // in the VM isolate. |
| 516 (Isolate::Current() != Dart::vm_isolate()); | 530 (Isolate::Current() != Dart::vm_isolate()); |
| 517 } | 531 } |
| 518 | 532 |
| 519 | 533 |
| 520 void Assembler::LoadExternalLabel(Register dst, | 534 void Assembler::LoadExternalLabel(Register dst, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 if (CanLoadObjectFromPool(object)) { | 574 if (CanLoadObjectFromPool(object)) { |
| 561 LoadObject(TMP, object, pp); | 575 LoadObject(TMP, object, pp); |
| 562 CompareRegisters(reg, TMP); | 576 CompareRegisters(reg, TMP); |
| 563 } else { | 577 } else { |
| 564 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); | 578 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); |
| 565 } | 579 } |
| 566 } | 580 } |
| 567 | 581 |
| 568 | 582 |
| 569 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { | 583 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { |
| 570 if ((pp != kNoPP) && (Isolate::Current() != Dart::vm_isolate())) { | 584 if ((pp != kNoPP) && |
| 585 (Isolate::Current() != Dart::vm_isolate()) && |
| 586 allow_constant_pool()) { |
| 571 int64_t val_smi_tag = imm & kSmiTagMask; | 587 int64_t val_smi_tag = imm & kSmiTagMask; |
| 572 imm &= ~kSmiTagMask; // Mask off the tag bits. | 588 imm &= ~kSmiTagMask; // Mask off the tag bits. |
| 573 const int32_t offset = Array::element_offset(FindImmediate(imm)); | 589 const int32_t offset = Array::element_offset(FindImmediate(imm)); |
| 574 LoadWordFromPoolOffset(reg, pp, offset); | 590 LoadWordFromPoolOffset(reg, pp, offset); |
| 575 if (val_smi_tag != 0) { | 591 if (val_smi_tag != 0) { |
| 576 // Add back the tag bits. | 592 // Add back the tag bits. |
| 577 orri(reg, reg, val_smi_tag); | 593 orri(reg, reg, val_smi_tag); |
| 578 } | 594 } |
| 579 } else { | 595 } else { |
| 580 // TODO(zra): Since this sequence only needs to be decodable, it can be | 596 // TODO(zra): Since this sequence only needs to be decodable, it can be |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 add(base, array, Operand(index, LSL, shift)); | 1508 add(base, array, Operand(index, LSL, shift)); |
| 1493 } | 1509 } |
| 1494 const OperandSize size = Address::OperandSizeFor(cid); | 1510 const OperandSize size = Address::OperandSizeFor(cid); |
| 1495 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1511 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
| 1496 return Address(base, offset, Address::Offset, size); | 1512 return Address(base, offset, Address::Offset, size); |
| 1497 } | 1513 } |
| 1498 | 1514 |
| 1499 } // namespace dart | 1515 } // namespace dart |
| 1500 | 1516 |
| 1501 #endif // defined TARGET_ARCH_ARM64 | 1517 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |