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

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

Issue 1234833003: Debugger: use debug break slots to break at function exit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix for arm Created 5 years, 5 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
« no previous file with comments | « src/arm64/assembler-arm64.cc ('k') | src/arm64/debug-arm64.cc » ('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 "src/arm64/assembler-arm64.h" 8 #include "src/arm64/assembler-arm64.h"
9 #include "src/assembler.h" 9 #include "src/assembler.h"
10 #include "src/debug.h" 10 #include "src/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, ICacheFlushMode icache_flush_mode) { 20 void RelocInfo::apply(intptr_t delta) {
21 // On arm64 only internal references need extra work. 21 // On arm64 only internal references need extra work.
22 DCHECK(RelocInfo::IsInternalReference(rmode_)); 22 DCHECK(RelocInfo::IsInternalReference(rmode_));
23 23
24 // Absolute code pointer inside code object moves with the code object. 24 // Absolute code pointer inside code object moves with the code object.
25 intptr_t* p = reinterpret_cast<intptr_t*>(pc_); 25 intptr_t* p = reinterpret_cast<intptr_t*>(pc_);
26 *p += delta; // Relocate entry. 26 *p += delta; // Relocate entry.
27 } 27 }
28 28
29 29
30 void RelocInfo::set_target_address(Address target, 30 void RelocInfo::set_target_address(Address target,
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 // ldr ip0, #... @ load from literal pool 604 // ldr ip0, #... @ load from literal pool
605 // blr ip0 605 // blr ip0
606 Address candidate = pc - 2 * kInstructionSize; 606 Address candidate = pc - 2 * kInstructionSize;
607 Instruction* instr = reinterpret_cast<Instruction*>(candidate); 607 Instruction* instr = reinterpret_cast<Instruction*>(candidate);
608 USE(instr); 608 USE(instr);
609 DCHECK(instr->IsLdrLiteralX()); 609 DCHECK(instr->IsLdrLiteralX());
610 return candidate; 610 return candidate;
611 } 611 }
612 612
613 613
614 Address Assembler::break_address_from_return_address(Address pc) {
615 return pc - Assembler::kPatchDebugBreakSlotReturnOffset;
616 }
617
618
619 Address Assembler::return_address_from_call_start(Address pc) { 614 Address Assembler::return_address_from_call_start(Address pc) {
620 // The call, generated by MacroAssembler::Call, is one of two possible 615 // The call, generated by MacroAssembler::Call, is one of two possible
621 // sequences: 616 // sequences:
622 // 617 //
623 // Without relocation: 618 // Without relocation:
624 // movz temp, #(target & 0x000000000000ffff) 619 // movz temp, #(target & 0x000000000000ffff)
625 // movk temp, #(target & 0x00000000ffff0000) 620 // movk temp, #(target & 0x00000000ffff0000)
626 // movk temp, #(target & 0x0000ffff00000000) 621 // movk temp, #(target & 0x0000ffff00000000)
627 // blr temp 622 // blr temp
628 // 623 //
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 ICacheFlushMode icache_flush_mode) { 813 ICacheFlushMode icache_flush_mode) {
819 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 814 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
820 DCHECK(!Code::IsYoungSequence(stub->GetIsolate(), pc_)); 815 DCHECK(!Code::IsYoungSequence(stub->GetIsolate(), pc_));
821 // Overwrite the stub entry point in the code age sequence. This is loaded as 816 // Overwrite the stub entry point in the code age sequence. This is loaded as
822 // a literal so there is no need to call FlushICache here. 817 // a literal so there is no need to call FlushICache here.
823 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset; 818 Address stub_entry_address = pc_ + kCodeAgeStubEntryOffset;
824 Memory::Address_at(stub_entry_address) = stub->instruction_start(); 819 Memory::Address_at(stub_entry_address) = stub->instruction_start();
825 } 820 }
826 821
827 822
828 Address RelocInfo::call_address() { 823 Address RelocInfo::debug_call_address() {
829 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 824 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
830 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
831 // For the above sequences the Relocinfo points to the load literal loading 825 // For the above sequences the Relocinfo points to the load literal loading
832 // the call address. 826 // the call address.
827 STATIC_ASSERT(Assembler::kPatchDebugBreakSlotAddressOffset == 0);
833 return Assembler::target_address_at(pc_, host_); 828 return Assembler::target_address_at(pc_, host_);
834 } 829 }
835 830
836 831
837 void RelocInfo::set_call_address(Address target) { 832 void RelocInfo::set_debug_call_address(Address target) {
838 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 833 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
839 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 834 STATIC_ASSERT(Assembler::kPatchDebugBreakSlotAddressOffset == 0);
840 Assembler::set_target_address_at(pc_, host_, target); 835 Assembler::set_target_address_at(pc_, host_, target);
841 if (host() != NULL) { 836 if (host() != NULL) {
842 Object* target_code = Code::GetCodeFromTargetAddress(target); 837 Object* target_code = Code::GetCodeFromTargetAddress(target);
843 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 838 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
844 host(), this, HeapObject::cast(target_code)); 839 host(), this, HeapObject::cast(target_code));
845 } 840 }
846 } 841 }
847 842
848 843
849 void RelocInfo::WipeOut() { 844 void RelocInfo::WipeOut() {
850 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) || 845 DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
851 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) || 846 IsRuntimeEntry(rmode_) || IsExternalReference(rmode_) ||
852 IsInternalReference(rmode_)); 847 IsInternalReference(rmode_));
853 if (IsInternalReference(rmode_)) { 848 if (IsInternalReference(rmode_)) {
854 Memory::Address_at(pc_) = NULL; 849 Memory::Address_at(pc_) = NULL;
855 } else { 850 } else {
856 Assembler::set_target_address_at(pc_, host_, NULL); 851 Assembler::set_target_address_at(pc_, host_, NULL);
857 } 852 }
858 } 853 }
859 854
860 855
861 bool RelocInfo::IsPatchedReturnSequence() { 856 bool RelocInfo::IsPatchedReturnSequence() {
862 // The sequence must be: 857 // The sequence must be:
863 // ldr ip0, [pc, #offset] 858 // ldr ip0, [pc, #offset]
864 // blr ip0 859 // blr ip0
865 // See arm64/debug-arm64.cc BreakLocation::SetDebugBreakAtReturn(). 860 // See arm64/debug-arm64.cc DebugCodegen::PatchDebugBreakSlot
866 Instruction* i1 = reinterpret_cast<Instruction*>(pc_); 861 Instruction* i1 = reinterpret_cast<Instruction*>(pc_);
867 Instruction* i2 = i1->following(); 862 Instruction* i2 = i1->following();
868 return i1->IsLdrLiteralX() && (i1->Rt() == kIp0Code) && 863 return i1->IsLdrLiteralX() && (i1->Rt() == kIp0Code) &&
869 i2->IsBranchAndLinkToRegister() && (i2->Rn() == kIp0Code); 864 i2->IsBranchAndLinkToRegister() && (i2->Rn() == kIp0Code);
870 } 865 }
871 866
872 867
873 bool RelocInfo::IsPatchedDebugBreakSlotSequence() { 868 bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
874 Instruction* current_instr = reinterpret_cast<Instruction*>(pc_); 869 Instruction* current_instr = reinterpret_cast<Instruction*>(pc_);
875 return !current_instr->IsNop(Assembler::DEBUG_BREAK_NOP); 870 return !current_instr->IsNop(Assembler::DEBUG_BREAK_NOP);
876 } 871 }
877 872
878 873
879 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { 874 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
880 RelocInfo::Mode mode = rmode(); 875 RelocInfo::Mode mode = rmode();
881 if (mode == RelocInfo::EMBEDDED_OBJECT) { 876 if (mode == RelocInfo::EMBEDDED_OBJECT) {
882 visitor->VisitEmbeddedPointer(this); 877 visitor->VisitEmbeddedPointer(this);
883 } else if (RelocInfo::IsCodeTarget(mode)) { 878 } else if (RelocInfo::IsCodeTarget(mode)) {
884 visitor->VisitCodeTarget(this); 879 visitor->VisitCodeTarget(this);
885 } else if (mode == RelocInfo::CELL) { 880 } else if (mode == RelocInfo::CELL) {
886 visitor->VisitCell(this); 881 visitor->VisitCell(this);
887 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 882 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
888 visitor->VisitExternalReference(this); 883 visitor->VisitExternalReference(this);
889 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 884 } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
890 visitor->VisitInternalReference(this); 885 visitor->VisitInternalReference(this);
891 } else if (((RelocInfo::IsJSReturn(mode) && 886 } else if (RelocInfo::IsDebugBreakSlot(mode) &&
892 IsPatchedReturnSequence()) || 887 IsPatchedDebugBreakSlotSequence() &&
893 (RelocInfo::IsDebugBreakSlot(mode) &&
894 IsPatchedDebugBreakSlotSequence())) &&
895 isolate->debug()->has_break_points()) { 888 isolate->debug()->has_break_points()) {
896 visitor->VisitDebugTarget(this); 889 visitor->VisitDebugTarget(this);
897 } else if (RelocInfo::IsRuntimeEntry(mode)) { 890 } else if (RelocInfo::IsRuntimeEntry(mode)) {
898 visitor->VisitRuntimeEntry(this); 891 visitor->VisitRuntimeEntry(this);
899 } 892 }
900 } 893 }
901 894
902 895
903 template<typename StaticVisitor> 896 template<typename StaticVisitor>
904 void RelocInfo::Visit(Heap* heap) { 897 void RelocInfo::Visit(Heap* heap) {
905 RelocInfo::Mode mode = rmode(); 898 RelocInfo::Mode mode = rmode();
906 if (mode == RelocInfo::EMBEDDED_OBJECT) { 899 if (mode == RelocInfo::EMBEDDED_OBJECT) {
907 StaticVisitor::VisitEmbeddedPointer(heap, this); 900 StaticVisitor::VisitEmbeddedPointer(heap, this);
908 } else if (RelocInfo::IsCodeTarget(mode)) { 901 } else if (RelocInfo::IsCodeTarget(mode)) {
909 StaticVisitor::VisitCodeTarget(heap, this); 902 StaticVisitor::VisitCodeTarget(heap, this);
910 } else if (mode == RelocInfo::CELL) { 903 } else if (mode == RelocInfo::CELL) {
911 StaticVisitor::VisitCell(heap, this); 904 StaticVisitor::VisitCell(heap, this);
912 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 905 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
913 StaticVisitor::VisitExternalReference(this); 906 StaticVisitor::VisitExternalReference(this);
914 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 907 } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
915 StaticVisitor::VisitInternalReference(this); 908 StaticVisitor::VisitInternalReference(this);
916 } else if (heap->isolate()->debug()->has_break_points() && 909 } else if (heap->isolate()->debug()->has_break_points() &&
917 ((RelocInfo::IsJSReturn(mode) && 910 RelocInfo::IsDebugBreakSlot(mode) &&
918 IsPatchedReturnSequence()) || 911 IsPatchedDebugBreakSlotSequence()) {
919 (RelocInfo::IsDebugBreakSlot(mode) &&
920 IsPatchedDebugBreakSlotSequence()))) {
921 StaticVisitor::VisitDebugTarget(heap, this); 912 StaticVisitor::VisitDebugTarget(heap, this);
922 } else if (RelocInfo::IsRuntimeEntry(mode)) { 913 } else if (RelocInfo::IsRuntimeEntry(mode)) {
923 StaticVisitor::VisitRuntimeEntry(this); 914 StaticVisitor::VisitRuntimeEntry(this);
924 } 915 }
925 } 916 }
926 917
927 918
928 LoadStoreOp Assembler::LoadOpFor(const CPURegister& rt) { 919 LoadStoreOp Assembler::LoadOpFor(const CPURegister& rt) {
929 DCHECK(rt.IsValid()); 920 DCHECK(rt.IsValid());
930 if (rt.IsRegister()) { 921 if (rt.IsRegister()) {
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 1283
1293 1284
1294 void Assembler::ClearRecordedAstId() { 1285 void Assembler::ClearRecordedAstId() {
1295 recorded_ast_id_ = TypeFeedbackId::None(); 1286 recorded_ast_id_ = TypeFeedbackId::None();
1296 } 1287 }
1297 1288
1298 1289
1299 } } // namespace v8::internal 1290 } } // namespace v8::internal
1300 1291
1301 #endif // V8_ARM64_ASSEMBLER_ARM64_INL_H_ 1292 #endif // V8_ARM64_ASSEMBLER_ARM64_INL_H_
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.cc ('k') | src/arm64/debug-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698