| 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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 } | 683 } |
| 684 | 684 |
| 685 | 685 |
| 686 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { | 686 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { |
| 687 if (frame->function().is_visible()) { | 687 if (frame->function().is_visible()) { |
| 688 trace_.Add(frame); | 688 trace_.Add(frame); |
| 689 } | 689 } |
| 690 } | 690 } |
| 691 | 691 |
| 692 | 692 |
| 693 static bool IsSafePoint(PcDescriptors::Kind kind) { | 693 static bool IsSafeDescKind(PcDescriptors::Kind kind) { |
| 694 return ((kind == PcDescriptors::kIcCall) || | 694 return ((kind == PcDescriptors::kIcCall) || |
| 695 (kind == PcDescriptors::kOptStaticCall) || | 695 (kind == PcDescriptors::kOptStaticCall) || |
| 696 (kind == PcDescriptors::kUnoptStaticCall) || | 696 (kind == PcDescriptors::kUnoptStaticCall) || |
| 697 (kind == PcDescriptors::kClosureCall) || | 697 (kind == PcDescriptors::kClosureCall) || |
| 698 (kind == PcDescriptors::kReturn) || | 698 (kind == PcDescriptors::kReturn) || |
| 699 (kind == PcDescriptors::kRuntimeCall)); | 699 (kind == PcDescriptors::kRuntimeCall)); |
| 700 } | 700 } |
| 701 | 701 |
| 702 | 702 |
| 703 static bool IsSafePoint(const PcDescriptors& desc, intptr_t i) { |
| 704 return IsSafeDescKind(desc.DescriptorKind(i)) && |
| 705 (desc.TokenPos(i) != Scanner::kDummyTokenIndex); |
| 706 } |
| 707 |
| 708 |
| 703 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) | 709 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) |
| 704 : function_(func.raw()), | 710 : function_(func.raw()), |
| 705 pc_desc_index_(pc_desc_index), | 711 pc_desc_index_(pc_desc_index), |
| 706 pc_(0), | 712 pc_(0), |
| 707 line_number_(-1), | 713 line_number_(-1), |
| 708 is_enabled_(false), | 714 is_enabled_(false), |
| 709 src_bpt_(NULL), | 715 src_bpt_(NULL), |
| 710 next_(NULL) { | 716 next_(NULL) { |
| 711 saved_value_ = 0; | 717 saved_value_ = 0; |
| 712 ASSERT(!func.HasOptimizedCode()); | 718 ASSERT(!func.HasOptimizedCode()); |
| 713 Code& code = Code::Handle(func.unoptimized_code()); | 719 Code& code = Code::Handle(func.unoptimized_code()); |
| 714 ASSERT(!code.IsNull()); // Function must be compiled. | 720 ASSERT(!code.IsNull()); // Function must be compiled. |
| 715 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 721 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 716 ASSERT(pc_desc_index < desc.Length()); | 722 ASSERT(pc_desc_index < desc.Length()); |
| 717 token_pos_ = desc.TokenPos(pc_desc_index); | 723 token_pos_ = desc.TokenPos(pc_desc_index); |
| 718 ASSERT(token_pos_ >= 0); | 724 ASSERT(token_pos_ > 0); |
| 719 pc_ = desc.PC(pc_desc_index); | 725 pc_ = desc.PC(pc_desc_index); |
| 720 ASSERT(pc_ != 0); | 726 ASSERT(pc_ != 0); |
| 721 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 727 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
| 722 ASSERT(IsSafePoint(breakpoint_kind_)); | 728 ASSERT(IsSafeDescKind(breakpoint_kind_)); |
| 723 } | 729 } |
| 724 | 730 |
| 725 | 731 |
| 726 CodeBreakpoint::~CodeBreakpoint() { | 732 CodeBreakpoint::~CodeBreakpoint() { |
| 727 // Make sure we don't leave patched code behind. | 733 // Make sure we don't leave patched code behind. |
| 728 ASSERT(!IsEnabled()); | 734 ASSERT(!IsEnabled()); |
| 729 // Poison the data so we catch use after free errors. | 735 // Poison the data so we catch use after free errors. |
| 730 #ifdef DEBUG | 736 #ifdef DEBUG |
| 731 function_ = Function::null(); | 737 function_ = Function::null(); |
| 732 pc_ = 0ul; | 738 pc_ = 0ul; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 if (!target_function.HasCode()) { | 963 if (!target_function.HasCode()) { |
| 958 return; | 964 return; |
| 959 } | 965 } |
| 960 } | 966 } |
| 961 DeoptimizeWorld(); | 967 DeoptimizeWorld(); |
| 962 ASSERT(!target_function.HasOptimizedCode()); | 968 ASSERT(!target_function.HasOptimizedCode()); |
| 963 Code& code = Code::Handle(target_function.unoptimized_code()); | 969 Code& code = Code::Handle(target_function.unoptimized_code()); |
| 964 ASSERT(!code.IsNull()); | 970 ASSERT(!code.IsNull()); |
| 965 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 971 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 966 for (intptr_t i = 0; i < desc.Length(); i++) { | 972 for (intptr_t i = 0; i < desc.Length(); i++) { |
| 967 if (IsSafePoint(desc.DescriptorKind(i))) { | 973 if (IsSafePoint(desc, i)) { |
| 968 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); | 974 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); |
| 969 if (bpt != NULL) { | 975 if (bpt != NULL) { |
| 970 // There is already a breakpoint for this address. Make sure | 976 // There is already a breakpoint for this address. Make sure |
| 971 // it is enabled. | 977 // it is enabled. |
| 972 bpt->Enable(); | 978 bpt->Enable(); |
| 973 continue; | 979 continue; |
| 974 } | 980 } |
| 975 bpt = new CodeBreakpoint(target_function, i); | 981 bpt = new CodeBreakpoint(target_function, i); |
| 976 RegisterCodeBreakpoint(bpt); | 982 RegisterCodeBreakpoint(bpt); |
| 977 bpt->Enable(); | 983 bpt->Enable(); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 intptr_t best_fit_pos = INT_MAX; | 1258 intptr_t best_fit_pos = INT_MAX; |
| 1253 uword lowest_pc = kUwordMax; | 1259 uword lowest_pc = kUwordMax; |
| 1254 intptr_t lowest_pc_index = -1; | 1260 intptr_t lowest_pc_index = -1; |
| 1255 for (intptr_t i = 0; i < desc.Length(); i++) { | 1261 for (intptr_t i = 0; i < desc.Length(); i++) { |
| 1256 intptr_t desc_token_pos = desc.TokenPos(i); | 1262 intptr_t desc_token_pos = desc.TokenPos(i); |
| 1257 ASSERT(desc_token_pos >= 0); | 1263 ASSERT(desc_token_pos >= 0); |
| 1258 if (desc_token_pos < requested_token_pos) { | 1264 if (desc_token_pos < requested_token_pos) { |
| 1259 // This descriptor is before the first acceptable token position. | 1265 // This descriptor is before the first acceptable token position. |
| 1260 continue; | 1266 continue; |
| 1261 } | 1267 } |
| 1262 if (IsSafePoint(desc.DescriptorKind(i))) { | 1268 if (IsSafePoint(desc, i)) { |
| 1263 if (desc_token_pos < best_fit_pos) { | 1269 if (desc_token_pos < best_fit_pos) { |
| 1264 // So far, this descriptor has the lowest token position after | 1270 // So far, this descriptor has the lowest token position after |
| 1265 // the first acceptable token position. | 1271 // the first acceptable token position. |
| 1266 best_fit_pos = desc_token_pos; | 1272 best_fit_pos = desc_token_pos; |
| 1267 best_fit_index = i; | 1273 best_fit_index = i; |
| 1268 } | 1274 } |
| 1269 if (desc.PC(i) < lowest_pc) { | 1275 if (desc.PC(i) < lowest_pc) { |
| 1270 // This descriptor so far has the lowest code address. | 1276 // This descriptor so far has the lowest code address. |
| 1271 lowest_pc = desc.PC(i); | 1277 lowest_pc = desc.PC(i); |
| 1272 lowest_pc_index = i; | 1278 lowest_pc_index = i; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1289 | 1295 |
| 1290 void Debugger::MakeCodeBreakpointsAt(const Function& func, | 1296 void Debugger::MakeCodeBreakpointsAt(const Function& func, |
| 1291 SourceBreakpoint* bpt) { | 1297 SourceBreakpoint* bpt) { |
| 1292 ASSERT((bpt != NULL) && bpt->IsResolved()); | 1298 ASSERT((bpt != NULL) && bpt->IsResolved()); |
| 1293 ASSERT(!func.HasOptimizedCode()); | 1299 ASSERT(!func.HasOptimizedCode()); |
| 1294 Code& code = Code::Handle(func.unoptimized_code()); | 1300 Code& code = Code::Handle(func.unoptimized_code()); |
| 1295 ASSERT(!code.IsNull()); | 1301 ASSERT(!code.IsNull()); |
| 1296 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1302 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 1297 for (intptr_t i = 0; i < desc.Length(); i++) { | 1303 for (intptr_t i = 0; i < desc.Length(); i++) { |
| 1298 intptr_t desc_token_pos = desc.TokenPos(i); | 1304 intptr_t desc_token_pos = desc.TokenPos(i); |
| 1299 if ((desc_token_pos == bpt->token_pos_) && | 1305 if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { |
| 1300 IsSafePoint(desc.DescriptorKind(i))) { | |
| 1301 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); | 1306 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); |
| 1302 if (code_bpt == NULL) { | 1307 if (code_bpt == NULL) { |
| 1303 // No code breakpoint for this code exists; create one. | 1308 // No code breakpoint for this code exists; create one. |
| 1304 code_bpt = new CodeBreakpoint(func, i); | 1309 code_bpt = new CodeBreakpoint(func, i); |
| 1305 RegisterCodeBreakpoint(code_bpt); | 1310 RegisterCodeBreakpoint(code_bpt); |
| 1306 } | 1311 } |
| 1307 code_bpt->set_src_bpt(bpt); | 1312 code_bpt->set_src_bpt(bpt); |
| 1308 if (bpt->IsEnabled()) { | 1313 if (bpt->IsEnabled()) { |
| 1309 code_bpt->Enable(); | 1314 code_bpt->Enable(); |
| 1310 } | 1315 } |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 } | 2240 } |
| 2236 | 2241 |
| 2237 | 2242 |
| 2238 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2243 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2239 ASSERT(bpt->next() == NULL); | 2244 ASSERT(bpt->next() == NULL); |
| 2240 bpt->set_next(code_breakpoints_); | 2245 bpt->set_next(code_breakpoints_); |
| 2241 code_breakpoints_ = bpt; | 2246 code_breakpoints_ = bpt; |
| 2242 } | 2247 } |
| 2243 | 2248 |
| 2244 } // namespace dart | 2249 } // namespace dart |
| OLD | NEW |