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 |