| 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 ASSERT(!code_.is_optimized()); | 385 ASSERT(!code_.is_optimized()); |
| 386 context_level_ = 0; | 386 context_level_ = 0; |
| 387 intptr_t pc_desc_idx = PcDescIndex(); | 387 intptr_t pc_desc_idx = PcDescIndex(); |
| 388 // TODO(hausner): What to do if there is no descriptor entry | 388 // TODO(hausner): What to do if there is no descriptor entry |
| 389 // for the code position of the frame? For now say we are at context | 389 // for the code position of the frame? For now say we are at context |
| 390 // level 0. | 390 // level 0. |
| 391 if (pc_desc_idx < 0) { | 391 if (pc_desc_idx < 0) { |
| 392 return context_level_; | 392 return context_level_; |
| 393 } | 393 } |
| 394 ASSERT(!pc_desc_.IsNull()); | 394 ASSERT(!pc_desc_.IsNull()); |
| 395 if (pc_desc_.DescriptorKind(pc_desc_idx) == PcDescriptors::kReturn) { | |
| 396 // Special case: the context chain has already been deallocated. | |
| 397 // The context level is 0. | |
| 398 return context_level_; | |
| 399 } | |
| 400 intptr_t innermost_begin_pos = 0; | 395 intptr_t innermost_begin_pos = 0; |
| 401 intptr_t activation_token_pos = TokenPos(); | 396 intptr_t activation_token_pos = TokenPos(); |
| 402 ASSERT(activation_token_pos >= 0); | 397 ASSERT(activation_token_pos >= 0); |
| 403 GetVarDescriptors(); | 398 GetVarDescriptors(); |
| 404 intptr_t var_desc_len = var_descriptors_.Length(); | 399 intptr_t var_desc_len = var_descriptors_.Length(); |
| 405 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 400 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 406 RawLocalVarDescriptors::VarInfo var_info; | 401 RawLocalVarDescriptors::VarInfo var_info; |
| 407 var_descriptors_.GetInfo(cur_idx, &var_info); | 402 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 408 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && | 403 if ((var_info.kind == RawLocalVarDescriptors::kContextLevel) && |
| 409 (var_info.begin_pos <= activation_token_pos) && | 404 (var_info.begin_pos <= activation_token_pos) && |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 case PcDescriptors::kUnoptStaticCall: { | 773 case PcDescriptors::kUnoptStaticCall: { |
| 779 const Code& code = | 774 const Code& code = |
| 780 Code::Handle(Function::Handle(function_).unoptimized_code()); | 775 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 781 saved_bytes_.target_address_ = | 776 saved_bytes_.target_address_ = |
| 782 CodePatcher::GetStaticCallTargetAt(pc_, code); | 777 CodePatcher::GetStaticCallTargetAt(pc_, code); |
| 783 CodePatcher::PatchStaticCallAt(pc_, code, | 778 CodePatcher::PatchStaticCallAt(pc_, code, |
| 784 StubCode::BreakpointStaticEntryPoint()); | 779 StubCode::BreakpointStaticEntryPoint()); |
| 785 break; | 780 break; |
| 786 } | 781 } |
| 787 case PcDescriptors::kRuntimeCall: | 782 case PcDescriptors::kRuntimeCall: |
| 788 case PcDescriptors::kClosureCall: { | 783 case PcDescriptors::kClosureCall: |
| 784 case PcDescriptors::kReturn: { |
| 789 const Code& code = | 785 const Code& code = |
| 790 Code::Handle(Function::Handle(function_).unoptimized_code()); | 786 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 791 saved_bytes_.target_address_ = | 787 saved_bytes_.target_address_ = |
| 792 CodePatcher::GetStaticCallTargetAt(pc_, code); | 788 CodePatcher::GetStaticCallTargetAt(pc_, code); |
| 793 CodePatcher::PatchStaticCallAt(pc_, code, | 789 CodePatcher::PatchStaticCallAt(pc_, code, |
| 794 StubCode::BreakpointRuntimeEntryPoint()); | 790 StubCode::BreakpointRuntimeEntryPoint()); |
| 795 break; | 791 break; |
| 796 } | 792 } |
| 797 case PcDescriptors::kReturn: | |
| 798 PatchFunctionReturn(); | |
| 799 break; | |
| 800 default: | 793 default: |
| 801 UNREACHABLE(); | 794 UNREACHABLE(); |
| 802 } | 795 } |
| 803 is_enabled_ = true; | 796 is_enabled_ = true; |
| 804 } | 797 } |
| 805 | 798 |
| 806 | 799 |
| 807 void CodeBreakpoint::RestoreCode() { | 800 void CodeBreakpoint::RestoreCode() { |
| 808 ASSERT(is_enabled_); | 801 ASSERT(is_enabled_); |
| 809 switch (breakpoint_kind_) { | 802 switch (breakpoint_kind_) { |
| 810 case PcDescriptors::kIcCall: { | 803 case PcDescriptors::kIcCall: { |
| 811 const Code& code = | 804 const Code& code = |
| 812 Code::Handle(Function::Handle(function_).unoptimized_code()); | 805 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 813 CodePatcher::PatchInstanceCallAt(pc_, code, | 806 CodePatcher::PatchInstanceCallAt(pc_, code, |
| 814 saved_bytes_.target_address_); | 807 saved_bytes_.target_address_); |
| 815 break; | 808 break; |
| 816 } | 809 } |
| 817 case PcDescriptors::kUnoptStaticCall: | 810 case PcDescriptors::kUnoptStaticCall: |
| 818 case PcDescriptors::kClosureCall: | 811 case PcDescriptors::kClosureCall: |
| 819 case PcDescriptors::kRuntimeCall: { | 812 case PcDescriptors::kRuntimeCall: |
| 813 case PcDescriptors::kReturn: { |
| 820 const Code& code = | 814 const Code& code = |
| 821 Code::Handle(Function::Handle(function_).unoptimized_code()); | 815 Code::Handle(Function::Handle(function_).unoptimized_code()); |
| 822 CodePatcher::PatchStaticCallAt(pc_, code, | 816 CodePatcher::PatchStaticCallAt(pc_, code, |
| 823 saved_bytes_.target_address_); | 817 saved_bytes_.target_address_); |
| 824 break; | 818 break; |
| 825 } | 819 } |
| 826 case PcDescriptors::kReturn: | |
| 827 RestoreFunctionReturn(); | |
| 828 break; | |
| 829 default: | 820 default: |
| 830 UNREACHABLE(); | 821 UNREACHABLE(); |
| 831 } | 822 } |
| 832 is_enabled_ = false; | 823 is_enabled_ = false; |
| 833 } | 824 } |
| 834 | 825 |
| 835 | 826 |
| 836 void CodeBreakpoint::Enable() { | 827 void CodeBreakpoint::Enable() { |
| 837 if (!is_enabled_) { | 828 if (!is_enabled_) { |
| 838 PatchCode(); | 829 PatchCode(); |
| (...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 } | 1997 } |
| 2007 | 1998 |
| 2008 if (report_bp && (event_handler_ != NULL)) { | 1999 if (report_bp && (event_handler_ != NULL)) { |
| 2009 ASSERT(stack_trace_ == NULL); | 2000 ASSERT(stack_trace_ == NULL); |
| 2010 stack_trace_ = stack_trace; | 2001 stack_trace_ = stack_trace; |
| 2011 SignalPausedEvent(top_frame, bpt->src_bpt_); | 2002 SignalPausedEvent(top_frame, bpt->src_bpt_); |
| 2012 stack_trace_ = NULL; | 2003 stack_trace_ = NULL; |
| 2013 } | 2004 } |
| 2014 | 2005 |
| 2015 Function& func_to_instrument = Function::Handle(); | 2006 Function& func_to_instrument = Function::Handle(); |
| 2007 if ((resume_action_ == kStepOver) && |
| 2008 (bpt->breakpoint_kind_ == PcDescriptors::kReturn)) { |
| 2009 resume_action_ = kStepOut; |
| 2010 } |
| 2016 if (resume_action_ == kStepOver) { | 2011 if (resume_action_ == kStepOver) { |
| 2017 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) { | 2012 ASSERT(bpt->breakpoint_kind_ != PcDescriptors::kReturn); |
| 2018 // Step over return is converted into a single step so we break at | 2013 func_to_instrument = bpt->function(); |
| 2019 // the caller. | |
| 2020 SetSingleStep(); | |
| 2021 } else { | |
| 2022 func_to_instrument = bpt->function(); | |
| 2023 } | |
| 2024 } else if (resume_action_ == kStepOut) { | 2014 } else if (resume_action_ == kStepOut) { |
| 2025 if (stack_trace->Length() > 1) { | 2015 if (stack_trace->Length() > 1) { |
| 2026 ActivationFrame* caller_frame = stack_trace->FrameAt(1); | 2016 ActivationFrame* caller_frame = stack_trace->FrameAt(1); |
| 2027 func_to_instrument = caller_frame->function().raw(); | 2017 func_to_instrument = caller_frame->function().raw(); |
| 2028 } | 2018 } |
| 2029 } else { | 2019 } else { |
| 2030 ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep)); | 2020 ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep)); |
| 2031 // Nothing to do here. Any potential instrumentation will be removed | 2021 // Nothing to do here. Any potential instrumentation will be removed |
| 2032 // below. Single stepping is handled by the single step callback. | 2022 // below. Single stepping is handled by the single step callback. |
| 2033 } | 2023 } |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 } | 2271 } |
| 2282 | 2272 |
| 2283 | 2273 |
| 2284 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2274 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2285 ASSERT(bpt->next() == NULL); | 2275 ASSERT(bpt->next() == NULL); |
| 2286 bpt->set_next(code_breakpoints_); | 2276 bpt->set_next(code_breakpoints_); |
| 2287 code_breakpoints_ = bpt; | 2277 code_breakpoints_ = bpt; |
| 2288 } | 2278 } |
| 2289 | 2279 |
| 2290 } // namespace dart | 2280 } // namespace dart |
| OLD | NEW |