| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_INL_H_ | 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_INL_H_ |
| 6 #define V8_ARM64_ASSEMBLER_ARM64_INL_H_ | 6 #define V8_ARM64_ASSEMBLER_ARM64_INL_H_ |
| 7 | 7 |
| 8 #include "arm64/assembler-arm64.h" | 8 #include "arm64/assembler-arm64.h" |
| 9 #include "cpu.h" | 9 #include "cpu.h" |
| 10 #include "debug.h" | 10 #include "debug.h" |
| 11 | 11 |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 | 16 |
| 17 bool CpuFeatures::SupportsCrankshaft() { return true; } | 17 bool CpuFeatures::SupportsCrankshaft() { return true; } |
| 18 | 18 |
| 19 | 19 |
| 20 void RelocInfo::apply(intptr_t delta) { | 20 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { |
| 21 UNIMPLEMENTED(); | 21 UNIMPLEMENTED(); |
| 22 } | 22 } |
| 23 | 23 |
| 24 | 24 |
| 25 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { | 25 void RelocInfo::set_target_address(Address target, |
| 26 WriteBarrierMode write_barrier_mode, |
| 27 ICacheFlushMode icache_flush_mode) { |
| 26 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 28 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| 27 Assembler::set_target_address_at(pc_, host_, target); | 29 Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode); |
| 28 if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { | 30 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL && |
| 31 IsCodeTarget(rmode_)) { |
| 29 Object* target_code = Code::GetCodeFromTargetAddress(target); | 32 Object* target_code = Code::GetCodeFromTargetAddress(target); |
| 30 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 33 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
| 31 host(), this, HeapObject::cast(target_code)); | 34 host(), this, HeapObject::cast(target_code)); |
| 32 } | 35 } |
| 33 } | 36 } |
| 34 | 37 |
| 35 | 38 |
| 36 inline unsigned CPURegister::code() const { | 39 inline unsigned CPURegister::code() const { |
| 37 ASSERT(IsValid()); | 40 ASSERT(IsValid()); |
| 38 return reg_code; | 41 return reg_code; |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 | 621 |
| 619 | 622 |
| 620 void Assembler::deserialization_set_special_target_at( | 623 void Assembler::deserialization_set_special_target_at( |
| 621 Address constant_pool_entry, Code* code, Address target) { | 624 Address constant_pool_entry, Code* code, Address target) { |
| 622 Memory::Address_at(constant_pool_entry) = target; | 625 Memory::Address_at(constant_pool_entry) = target; |
| 623 } | 626 } |
| 624 | 627 |
| 625 | 628 |
| 626 void Assembler::set_target_address_at(Address pc, | 629 void Assembler::set_target_address_at(Address pc, |
| 627 ConstantPoolArray* constant_pool, | 630 ConstantPoolArray* constant_pool, |
| 628 Address target) { | 631 Address target, |
| 632 ICacheFlushMode icache_flush_mode) { |
| 629 Memory::Address_at(target_pointer_address_at(pc)) = target; | 633 Memory::Address_at(target_pointer_address_at(pc)) = target; |
| 630 // Intuitively, we would think it is necessary to always flush the | 634 // Intuitively, we would think it is necessary to always flush the |
| 631 // instruction cache after patching a target address in the code as follows: | 635 // instruction cache after patching a target address in the code as follows: |
| 632 // CPU::FlushICache(pc, sizeof(target)); | 636 // CPU::FlushICache(pc, sizeof(target)); |
| 633 // However, on ARM, an instruction is actually patched in the case of | 637 // However, on ARM, an instruction is actually patched in the case of |
| 634 // embedded constants of the form: | 638 // embedded constants of the form: |
| 635 // ldr ip, [pc, #...] | 639 // ldr ip, [pc, #...] |
| 636 // since the instruction accessing this address in the constant pool remains | 640 // since the instruction accessing this address in the constant pool remains |
| 637 // unchanged, a flush is not required. | 641 // unchanged, a flush is not required. |
| 638 } | 642 } |
| 639 | 643 |
| 640 | 644 |
| 641 void Assembler::set_target_address_at(Address pc, | 645 void Assembler::set_target_address_at(Address pc, |
| 642 Code* code, | 646 Code* code, |
| 643 Address target) { | 647 Address target, |
| 648 ICacheFlushMode icache_flush_mode) { |
| 644 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; | 649 ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL; |
| 645 set_target_address_at(pc, constant_pool, target); | 650 set_target_address_at(pc, constant_pool, target, icache_flush_mode); |
| 646 } | 651 } |
| 647 | 652 |
| 648 | 653 |
| 649 int RelocInfo::target_address_size() { | 654 int RelocInfo::target_address_size() { |
| 650 return kPointerSize; | 655 return kPointerSize; |
| 651 } | 656 } |
| 652 | 657 |
| 653 | 658 |
| 654 Address RelocInfo::target_address() { | 659 Address RelocInfo::target_address() { |
| 655 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 660 ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 677 } | 682 } |
| 678 | 683 |
| 679 | 684 |
| 680 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { | 685 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { |
| 681 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 686 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 682 return Handle<Object>(reinterpret_cast<Object**>( | 687 return Handle<Object>(reinterpret_cast<Object**>( |
| 683 Assembler::target_address_at(pc_, host_))); | 688 Assembler::target_address_at(pc_, host_))); |
| 684 } | 689 } |
| 685 | 690 |
| 686 | 691 |
| 687 void RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { | 692 void RelocInfo::set_target_object(Object* target, |
| 693 WriteBarrierMode write_barrier_mode, |
| 694 ICacheFlushMode icache_flush_mode) { |
| 688 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 695 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 689 ASSERT(!target->IsConsString()); | 696 ASSERT(!target->IsConsString()); |
| 690 Assembler::set_target_address_at(pc_, host_, | 697 Assembler::set_target_address_at(pc_, host_, |
| 691 reinterpret_cast<Address>(target)); | 698 reinterpret_cast<Address>(target), |
| 692 if (mode == UPDATE_WRITE_BARRIER && | 699 icache_flush_mode); |
| 700 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
| 693 host() != NULL && | 701 host() != NULL && |
| 694 target->IsHeapObject()) { | 702 target->IsHeapObject()) { |
| 695 host()->GetHeap()->incremental_marking()->RecordWrite( | 703 host()->GetHeap()->incremental_marking()->RecordWrite( |
| 696 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); | 704 host(), &Memory::Object_at(pc_), HeapObject::cast(target)); |
| 697 } | 705 } |
| 698 } | 706 } |
| 699 | 707 |
| 700 | 708 |
| 701 Address RelocInfo::target_reference() { | 709 Address RelocInfo::target_reference() { |
| 702 ASSERT(rmode_ == EXTERNAL_REFERENCE); | 710 ASSERT(rmode_ == EXTERNAL_REFERENCE); |
| 703 return Assembler::target_address_at(pc_, host_); | 711 return Assembler::target_address_at(pc_, host_); |
| 704 } | 712 } |
| 705 | 713 |
| 706 | 714 |
| 707 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 715 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
| 708 ASSERT(IsRuntimeEntry(rmode_)); | 716 ASSERT(IsRuntimeEntry(rmode_)); |
| 709 return target_address(); | 717 return target_address(); |
| 710 } | 718 } |
| 711 | 719 |
| 712 | 720 |
| 713 void RelocInfo::set_target_runtime_entry(Address target, | 721 void RelocInfo::set_target_runtime_entry(Address target, |
| 714 WriteBarrierMode mode) { | 722 WriteBarrierMode write_barrier_mode, |
| 723 ICacheFlushMode icache_flush_mode) { |
| 715 ASSERT(IsRuntimeEntry(rmode_)); | 724 ASSERT(IsRuntimeEntry(rmode_)); |
| 716 if (target_address() != target) set_target_address(target, mode); | 725 if (target_address() != target) { |
| 726 set_target_address(target, write_barrier_mode, icache_flush_mode); |
| 727 } |
| 717 } | 728 } |
| 718 | 729 |
| 719 | 730 |
| 720 Handle<Cell> RelocInfo::target_cell_handle() { | 731 Handle<Cell> RelocInfo::target_cell_handle() { |
| 721 UNIMPLEMENTED(); | 732 UNIMPLEMENTED(); |
| 722 Cell *null_cell = NULL; | 733 Cell *null_cell = NULL; |
| 723 return Handle<Cell>(null_cell); | 734 return Handle<Cell>(null_cell); |
| 724 } | 735 } |
| 725 | 736 |
| 726 | 737 |
| 727 Cell* RelocInfo::target_cell() { | 738 Cell* RelocInfo::target_cell() { |
| 728 ASSERT(rmode_ == RelocInfo::CELL); | 739 ASSERT(rmode_ == RelocInfo::CELL); |
| 729 return Cell::FromValueAddress(Memory::Address_at(pc_)); | 740 return Cell::FromValueAddress(Memory::Address_at(pc_)); |
| 730 } | 741 } |
| 731 | 742 |
| 732 | 743 |
| 733 void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode mode) { | 744 void RelocInfo::set_target_cell(Cell* cell, |
| 745 WriteBarrierMode write_barrier_mode, |
| 746 ICacheFlushMode icache_flush_mode) { |
| 734 UNIMPLEMENTED(); | 747 UNIMPLEMENTED(); |
| 735 } | 748 } |
| 736 | 749 |
| 737 | 750 |
| 738 static const int kNoCodeAgeSequenceLength = 5 * kInstructionSize; | 751 static const int kNoCodeAgeSequenceLength = 5 * kInstructionSize; |
| 739 static const int kCodeAgeStubEntryOffset = 3 * kInstructionSize; | 752 static const int kCodeAgeStubEntryOffset = 3 * kInstructionSize; |
| 740 | 753 |
| 741 | 754 |
| 742 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { | 755 Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { |
| 743 UNREACHABLE(); // This should never be reached on ARM64. | 756 UNREACHABLE(); // This should never be reached on ARM64. |
| 744 return Handle<Object>(); | 757 return Handle<Object>(); |
| 745 } | 758 } |
| 746 | 759 |
| 747 | 760 |
| 748 Code* RelocInfo::code_age_stub() { | 761 Code* RelocInfo::code_age_stub() { |
| 749 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 762 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 750 // Read the stub entry point from the code age sequence. | 763 // Read the stub entry point from the code age sequence. |
| 751 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; | 764 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; |
| 752 return Code::GetCodeFromTargetAddress(Memory::Address_at(stub_entry_address)); | 765 return Code::GetCodeFromTargetAddress(Memory::Address_at(stub_entry_address)); |
| 753 } | 766 } |
| 754 | 767 |
| 755 | 768 |
| 756 void RelocInfo::set_code_age_stub(Code* stub) { | 769 void RelocInfo::set_code_age_stub(Code* stub, |
| 770 ICacheFlushMode icache_flush_mode) { |
| 757 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 771 ASSERT(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 758 ASSERT(!Code::IsYoungSequence(stub->GetIsolate(), pc_)); | 772 ASSERT(!Code::IsYoungSequence(stub->GetIsolate(), pc_)); |
| 759 // Overwrite the stub entry point in the code age sequence. This is loaded as | 773 // Overwrite the stub entry point in the code age sequence. This is loaded as |
| 760 // a literal so there is no need to call FlushICache here. | 774 // a literal so there is no need to call FlushICache here. |
| 761 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; | 775 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; |
| 762 Memory::Address_at(stub_entry_address) = stub->instruction_start(); | 776 Memory::Address_at(stub_entry_address) = stub->instruction_start(); |
| 763 } | 777 } |
| 764 | 778 |
| 765 | 779 |
| 766 Address RelocInfo::call_address() { | 780 Address RelocInfo::call_address() { |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1217 | 1231 |
| 1218 | 1232 |
| 1219 void Assembler::ClearRecordedAstId() { | 1233 void Assembler::ClearRecordedAstId() { |
| 1220 recorded_ast_id_ = TypeFeedbackId::None(); | 1234 recorded_ast_id_ = TypeFeedbackId::None(); |
| 1221 } | 1235 } |
| 1222 | 1236 |
| 1223 | 1237 |
| 1224 } } // namespace v8::internal | 1238 } } // namespace v8::internal |
| 1225 | 1239 |
| 1226 #endif // V8_ARM64_ASSEMBLER_ARM64_INL_H_ | 1240 #endif // V8_ARM64_ASSEMBLER_ARM64_INL_H_ |
| OLD | NEW |