Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1248)

Side by Side Diff: src/arm64/assembler-arm64-inl.h

Issue 284153004: Avoid flushing the icache unnecessarily when updating target addresses in code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix intenting Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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_
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.h ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698