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

Side by Side Diff: runtime/vm/debugger.cc

Issue 106053011: Make return statements single steppable (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl_test.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 (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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698