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 |