OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/debugger.h" | 5 #include "vm/debugger.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 | 701 |
702 | 702 |
703 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) | 703 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) |
704 : function_(func.raw()), | 704 : function_(func.raw()), |
705 pc_desc_index_(pc_desc_index), | 705 pc_desc_index_(pc_desc_index), |
706 pc_(0), | 706 pc_(0), |
707 line_number_(-1), | 707 line_number_(-1), |
708 is_enabled_(false), | 708 is_enabled_(false), |
709 src_bpt_(NULL), | 709 src_bpt_(NULL), |
710 next_(NULL) { | 710 next_(NULL) { |
| 711 saved_value_ = 0; |
711 ASSERT(!func.HasOptimizedCode()); | 712 ASSERT(!func.HasOptimizedCode()); |
712 Code& code = Code::Handle(func.unoptimized_code()); | 713 Code& code = Code::Handle(func.unoptimized_code()); |
713 ASSERT(!code.IsNull()); // Function must be compiled. | 714 ASSERT(!code.IsNull()); // Function must be compiled. |
714 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 715 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
715 ASSERT(pc_desc_index < desc.Length()); | 716 ASSERT(pc_desc_index < desc.Length()); |
716 token_pos_ = desc.TokenPos(pc_desc_index); | 717 token_pos_ = desc.TokenPos(pc_desc_index); |
717 ASSERT(token_pos_ >= 0); | 718 ASSERT(token_pos_ >= 0); |
718 pc_ = desc.PC(pc_desc_index); | 719 pc_ = desc.PC(pc_desc_index); |
719 ASSERT(pc_ != 0); | 720 ASSERT(pc_ != 0); |
720 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 721 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
(...skipping 30 matching lines...) Expand all Loading... |
751 intptr_t CodeBreakpoint::LineNumber() { | 752 intptr_t CodeBreakpoint::LineNumber() { |
752 // Compute line number lazily since it causes scanning of the script. | 753 // Compute line number lazily since it causes scanning of the script. |
753 if (line_number_ < 0) { | 754 if (line_number_ < 0) { |
754 const Script& script = Script::Handle(SourceCode()); | 755 const Script& script = Script::Handle(SourceCode()); |
755 script.GetTokenLocation(token_pos_, &line_number_, NULL); | 756 script.GetTokenLocation(token_pos_, &line_number_, NULL); |
756 } | 757 } |
757 return line_number_; | 758 return line_number_; |
758 } | 759 } |
759 | 760 |
760 | 761 |
761 void CodeBreakpoint::PatchCode() { | |
762 ASSERT(!is_enabled_); | |
763 switch (breakpoint_kind_) { | |
764 case PcDescriptors::kIcCall: { | |
765 const Code& code = | |
766 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
767 saved_bytes_.target_address_ = | |
768 CodePatcher::GetInstanceCallAt(pc_, code, NULL); | |
769 CodePatcher::PatchInstanceCallAt(pc_, code, | |
770 StubCode::BreakpointDynamicEntryPoint()); | |
771 break; | |
772 } | |
773 case PcDescriptors::kUnoptStaticCall: { | |
774 const Code& code = | |
775 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
776 saved_bytes_.target_address_ = | |
777 CodePatcher::GetStaticCallTargetAt(pc_, code); | |
778 CodePatcher::PatchStaticCallAt(pc_, code, | |
779 StubCode::BreakpointStaticEntryPoint()); | |
780 break; | |
781 } | |
782 case PcDescriptors::kRuntimeCall: | |
783 case PcDescriptors::kClosureCall: | |
784 case PcDescriptors::kReturn: { | |
785 const Code& code = | |
786 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
787 saved_bytes_.target_address_ = | |
788 CodePatcher::GetStaticCallTargetAt(pc_, code); | |
789 CodePatcher::PatchStaticCallAt(pc_, code, | |
790 StubCode::BreakpointRuntimeEntryPoint()); | |
791 break; | |
792 } | |
793 default: | |
794 UNREACHABLE(); | |
795 } | |
796 is_enabled_ = true; | |
797 } | |
798 | |
799 | |
800 void CodeBreakpoint::RestoreCode() { | |
801 ASSERT(is_enabled_); | |
802 switch (breakpoint_kind_) { | |
803 case PcDescriptors::kIcCall: { | |
804 const Code& code = | |
805 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
806 CodePatcher::PatchInstanceCallAt(pc_, code, | |
807 saved_bytes_.target_address_); | |
808 break; | |
809 } | |
810 case PcDescriptors::kUnoptStaticCall: | |
811 case PcDescriptors::kClosureCall: | |
812 case PcDescriptors::kRuntimeCall: | |
813 case PcDescriptors::kReturn: { | |
814 const Code& code = | |
815 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
816 CodePatcher::PatchStaticCallAt(pc_, code, | |
817 saved_bytes_.target_address_); | |
818 break; | |
819 } | |
820 default: | |
821 UNREACHABLE(); | |
822 } | |
823 is_enabled_ = false; | |
824 } | |
825 | |
826 | |
827 void CodeBreakpoint::Enable() { | 762 void CodeBreakpoint::Enable() { |
828 if (!is_enabled_) { | 763 if (!is_enabled_) { |
829 PatchCode(); | 764 PatchCode(); |
830 } | 765 } |
831 ASSERT(is_enabled_); | 766 ASSERT(is_enabled_); |
832 } | 767 } |
833 | 768 |
834 | 769 |
835 void CodeBreakpoint::Disable() { | 770 void CodeBreakpoint::Disable() { |
836 if (is_enabled_) { | 771 if (is_enabled_) { |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1022 if (!target_function.HasCode()) { | 957 if (!target_function.HasCode()) { |
1023 return; | 958 return; |
1024 } | 959 } |
1025 } | 960 } |
1026 DeoptimizeWorld(); | 961 DeoptimizeWorld(); |
1027 ASSERT(!target_function.HasOptimizedCode()); | 962 ASSERT(!target_function.HasOptimizedCode()); |
1028 Code& code = Code::Handle(target_function.unoptimized_code()); | 963 Code& code = Code::Handle(target_function.unoptimized_code()); |
1029 ASSERT(!code.IsNull()); | 964 ASSERT(!code.IsNull()); |
1030 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 965 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1031 for (intptr_t i = 0; i < desc.Length(); i++) { | 966 for (intptr_t i = 0; i < desc.Length(); i++) { |
1032 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); | |
1033 if (bpt != NULL) { | |
1034 // There is already a breakpoint for this address. Make sure | |
1035 // it is enabled. | |
1036 bpt->Enable(); | |
1037 continue; | |
1038 } | |
1039 if (IsSafePoint(desc.DescriptorKind(i))) { | 967 if (IsSafePoint(desc.DescriptorKind(i))) { |
| 968 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); |
| 969 if (bpt != NULL) { |
| 970 // There is already a breakpoint for this address. Make sure |
| 971 // it is enabled. |
| 972 bpt->Enable(); |
| 973 continue; |
| 974 } |
1040 bpt = new CodeBreakpoint(target_function, i); | 975 bpt = new CodeBreakpoint(target_function, i); |
1041 RegisterCodeBreakpoint(bpt); | 976 RegisterCodeBreakpoint(bpt); |
1042 bpt->Enable(); | 977 bpt->Enable(); |
1043 } | 978 } |
1044 } | 979 } |
1045 } | 980 } |
1046 | 981 |
1047 | 982 |
1048 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 983 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |
1049 if (event_handler_ != NULL) { | 984 if (event_handler_ != NULL) { |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2174 } | 2109 } |
2175 bpt = bpt->next(); | 2110 bpt = bpt->next(); |
2176 } | 2111 } |
2177 return NULL; | 2112 return NULL; |
2178 } | 2113 } |
2179 | 2114 |
2180 | 2115 |
2181 uword Debugger::GetPatchedStubAddress(uword breakpoint_address) { | 2116 uword Debugger::GetPatchedStubAddress(uword breakpoint_address) { |
2182 CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address); | 2117 CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address); |
2183 if (bpt != NULL) { | 2118 if (bpt != NULL) { |
2184 return bpt->saved_bytes_.target_address_; | 2119 return bpt->OrigStubAddress(); |
2185 } | 2120 } |
2186 UNREACHABLE(); | 2121 UNREACHABLE(); |
2187 return 0L; | 2122 return 0L; |
2188 } | 2123 } |
2189 | 2124 |
2190 | 2125 |
2191 // Remove and delete the source breakpoint bpt and its associated | 2126 // Remove and delete the source breakpoint bpt and its associated |
2192 // code breakpoints. | 2127 // code breakpoints. |
2193 void Debugger::RemoveBreakpoint(intptr_t bp_id) { | 2128 void Debugger::RemoveBreakpoint(intptr_t bp_id) { |
2194 SourceBreakpoint* prev_bpt = NULL; | 2129 SourceBreakpoint* prev_bpt = NULL; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2287 } | 2222 } |
2288 | 2223 |
2289 | 2224 |
2290 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2225 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
2291 ASSERT(bpt->next() == NULL); | 2226 ASSERT(bpt->next() == NULL); |
2292 bpt->set_next(code_breakpoints_); | 2227 bpt->set_next(code_breakpoints_); |
2293 code_breakpoints_ = bpt; | 2228 code_breakpoints_ = bpt; |
2294 } | 2229 } |
2295 | 2230 |
2296 } // namespace dart | 2231 } // namespace dart |
OLD | NEW |