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 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 intptr_t var_desc_len = var_descriptors_.Length(); | 651 intptr_t var_desc_len = var_descriptors_.Length(); |
652 for (intptr_t i = 0; i < var_desc_len; i++) { | 652 for (intptr_t i = 0; i < var_desc_len; i++) { |
653 RawLocalVarDescriptors::VarInfo var_info; | 653 RawLocalVarDescriptors::VarInfo var_info; |
654 var_descriptors_.GetInfo(i, &var_info); | 654 var_descriptors_.GetInfo(i, &var_info); |
655 const int8_t kind = var_info.kind(); | 655 const int8_t kind = var_info.kind(); |
656 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 656 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
657 if (FLAG_trace_debugger_stacktrace) { | 657 if (FLAG_trace_debugger_stacktrace) { |
658 OS::PrintErr("\tFound saved current ctx at index %d\n", | 658 OS::PrintErr("\tFound saved current ctx at index %d\n", |
659 var_info.index()); | 659 var_info.index()); |
660 } | 660 } |
661 ctx_ ^= GetLocalVar(var_info.index()); | 661 ctx_ ^= GetStackVar(var_info.index()); |
662 return ctx_; | 662 return ctx_; |
663 } | 663 } |
664 } | 664 } |
665 UNREACHABLE(); | 665 UNREACHABLE(); |
666 return Context::ZoneHandle(Context::null()); | 666 return Context::ZoneHandle(Context::null()); |
667 } | 667 } |
668 | 668 |
669 | 669 |
| 670 RawObject* ActivationFrame::GetAsyncOperation() { |
| 671 GetVarDescriptors(); |
| 672 intptr_t var_desc_len = var_descriptors_.Length(); |
| 673 for (intptr_t i = 0; i < var_desc_len; i++) { |
| 674 RawLocalVarDescriptors::VarInfo var_info; |
| 675 var_descriptors_.GetInfo(i, &var_info); |
| 676 const int8_t kind = var_info.kind(); |
| 677 if (kind == RawLocalVarDescriptors::kAsyncOperation) { |
| 678 return GetContextVar(var_info.scope_id, var_info.index()); |
| 679 } |
| 680 } |
| 681 return Object::null(); |
| 682 } |
| 683 |
| 684 |
670 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 685 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
671 const Instance& exc_obj) const { | 686 const Instance& exc_obj) const { |
672 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 687 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
673 Array& handled_types = Array::Handle(); | 688 Array& handled_types = Array::Handle(); |
674 AbstractType& type = Type::Handle(); | 689 AbstractType& type = Type::Handle(); |
675 const TypeArguments& no_instantiator = TypeArguments::Handle(); | 690 const TypeArguments& no_instantiator = TypeArguments::Handle(); |
676 for (intptr_t frame_index = 0; | 691 for (intptr_t frame_index = 0; |
677 frame_index < Length(); | 692 frame_index < Length(); |
678 frame_index++) { | 693 frame_index++) { |
679 ActivationFrame* frame = FrameAt(frame_index); | 694 ActivationFrame* frame = FrameAt(frame_index); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 } | 824 } |
810 } | 825 } |
811 | 826 |
812 | 827 |
813 RawObject* ActivationFrame::GetClosure() { | 828 RawObject* ActivationFrame::GetClosure() { |
814 ASSERT(function().IsClosureFunction()); | 829 ASSERT(function().IsClosureFunction()); |
815 return GetParameter(0); | 830 return GetParameter(0); |
816 } | 831 } |
817 | 832 |
818 | 833 |
819 RawObject* ActivationFrame::GetLocalVar(intptr_t slot_index) { | 834 RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) { |
820 if (deopt_frame_.IsNull()) { | 835 if (deopt_frame_.IsNull()) { |
821 uword var_address = fp() + slot_index * kWordSize; | 836 uword var_address = fp() + slot_index * kWordSize; |
822 return reinterpret_cast<RawObject*>( | 837 return reinterpret_cast<RawObject*>( |
823 *reinterpret_cast<uword*>(var_address)); | 838 *reinterpret_cast<uword*>(var_address)); |
824 } else { | 839 } else { |
825 return deopt_frame_.At(deopt_frame_offset_ + slot_index); | 840 return deopt_frame_.At(deopt_frame_offset_ + slot_index); |
826 } | 841 } |
827 } | 842 } |
828 | 843 |
829 | 844 |
830 RawInstance* ActivationFrame::GetLocalInstanceVar(intptr_t slot_index) { | |
831 Instance& instance = Instance::Handle(); | |
832 instance ^= GetLocalVar(slot_index); | |
833 return instance.raw(); | |
834 } | |
835 | |
836 | |
837 void ActivationFrame::PrintContextMismatchError( | 845 void ActivationFrame::PrintContextMismatchError( |
838 const String& var_name, | |
839 intptr_t ctx_slot, | 846 intptr_t ctx_slot, |
840 intptr_t frame_ctx_level, | 847 intptr_t frame_ctx_level, |
841 intptr_t var_ctx_level) { | 848 intptr_t var_ctx_level) { |
842 OS::PrintErr("-------------------------\n" | 849 OS::PrintErr("-------------------------\n" |
843 "Encountered context mismatch\n" | 850 "Encountered context mismatch\n" |
844 "\tvar name: %s\n" | |
845 "\tctx_slot: %" Pd "\n" | 851 "\tctx_slot: %" Pd "\n" |
846 "\tframe_ctx_level: %" Pd "\n" | 852 "\tframe_ctx_level: %" Pd "\n" |
847 "\tvar_ctx_level: %" Pd "\n\n", | 853 "\tvar_ctx_level: %" Pd "\n\n", |
848 var_name.ToCString(), | |
849 ctx_slot, | 854 ctx_slot, |
850 frame_ctx_level, | 855 frame_ctx_level, |
851 var_ctx_level); | 856 var_ctx_level); |
852 | 857 |
853 OS::PrintErr("-------------------------\n" | 858 OS::PrintErr("-------------------------\n" |
854 "Current frame:\n%s\n", | 859 "Current frame:\n%s\n", |
855 this->ToCString()); | 860 this->ToCString()); |
856 | 861 |
857 OS::PrintErr("-------------------------\n" | 862 OS::PrintErr("-------------------------\n" |
858 "Context contents:\n"); | 863 "Context contents:\n"); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 | 901 |
897 RawLocalVarDescriptors::VarInfo var_info; | 902 RawLocalVarDescriptors::VarInfo var_info; |
898 var_descriptors_.GetInfo(desc_index, &var_info); | 903 var_descriptors_.GetInfo(desc_index, &var_info); |
899 ASSERT(token_pos != NULL); | 904 ASSERT(token_pos != NULL); |
900 *token_pos = var_info.begin_pos; | 905 *token_pos = var_info.begin_pos; |
901 ASSERT(end_pos != NULL); | 906 ASSERT(end_pos != NULL); |
902 *end_pos = var_info.end_pos; | 907 *end_pos = var_info.end_pos; |
903 ASSERT(value != NULL); | 908 ASSERT(value != NULL); |
904 const int8_t kind = var_info.kind(); | 909 const int8_t kind = var_info.kind(); |
905 if (kind == RawLocalVarDescriptors::kStackVar) { | 910 if (kind == RawLocalVarDescriptors::kStackVar) { |
906 *value = GetLocalInstanceVar(var_info.index()); | 911 *value = GetStackVar(var_info.index()); |
907 } else { | 912 } else { |
908 ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 913 ASSERT(kind == RawLocalVarDescriptors::kContextVar); |
909 const Context& ctx = GetSavedCurrentContext(); | 914 *value = GetContextVar(var_info.scope_id, var_info.index()); |
910 ASSERT(!ctx.IsNull()); | |
911 | |
912 // The context level at the PC/token index of this activation frame. | |
913 intptr_t frame_ctx_level = ContextLevel(); | |
914 | |
915 // The context level of the variable. | |
916 intptr_t var_ctx_level = var_info.scope_id; | |
917 intptr_t level_diff = frame_ctx_level - var_ctx_level; | |
918 intptr_t ctx_slot = var_info.index(); | |
919 if (level_diff == 0) { | |
920 if ((ctx_slot < 0) || | |
921 (ctx_slot >= ctx.num_variables())) { | |
922 PrintContextMismatchError(*name, ctx_slot, | |
923 frame_ctx_level, var_ctx_level); | |
924 } | |
925 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables())); | |
926 *value = ctx.At(ctx_slot); | |
927 } else { | |
928 ASSERT(level_diff > 0); | |
929 Context& var_ctx = Context::Handle(ctx.raw()); | |
930 while (level_diff > 0 && !var_ctx.IsNull()) { | |
931 level_diff--; | |
932 var_ctx = var_ctx.parent(); | |
933 } | |
934 if (var_ctx.IsNull() || | |
935 (ctx_slot < 0) || | |
936 (ctx_slot >= var_ctx.num_variables())) { | |
937 PrintContextMismatchError(*name, ctx_slot, | |
938 frame_ctx_level, var_ctx_level); | |
939 } | |
940 ASSERT(!var_ctx.IsNull()); | |
941 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); | |
942 *value = var_ctx.At(ctx_slot); | |
943 } | |
944 } | 915 } |
945 } | 916 } |
946 | 917 |
| 918 |
| 919 RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level, |
| 920 intptr_t ctx_slot) { |
| 921 const Context& ctx = GetSavedCurrentContext(); |
| 922 ASSERT(!ctx.IsNull()); |
| 923 |
| 924 // The context level at the PC/token index of this activation frame. |
| 925 intptr_t frame_ctx_level = ContextLevel(); |
| 926 |
| 927 intptr_t level_diff = frame_ctx_level - var_ctx_level; |
| 928 if (level_diff == 0) { |
| 929 if ((ctx_slot < 0) || |
| 930 (ctx_slot >= ctx.num_variables())) { |
| 931 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level); |
| 932 } |
| 933 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables())); |
| 934 return ctx.At(ctx_slot); |
| 935 } else { |
| 936 ASSERT(level_diff > 0); |
| 937 Context& var_ctx = Context::Handle(ctx.raw()); |
| 938 while (level_diff > 0 && !var_ctx.IsNull()) { |
| 939 level_diff--; |
| 940 var_ctx = var_ctx.parent(); |
| 941 } |
| 942 if (var_ctx.IsNull() || |
| 943 (ctx_slot < 0) || |
| 944 (ctx_slot >= var_ctx.num_variables())) { |
| 945 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level); |
| 946 } |
| 947 ASSERT(!var_ctx.IsNull()); |
| 948 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); |
| 949 return var_ctx.At(ctx_slot); |
| 950 } |
| 951 } |
| 952 |
947 | 953 |
948 RawArray* ActivationFrame::GetLocalVariables() { | 954 RawArray* ActivationFrame::GetLocalVariables() { |
949 GetDescIndices(); | 955 GetDescIndices(); |
950 intptr_t num_variables = desc_indices_.length(); | 956 intptr_t num_variables = desc_indices_.length(); |
951 String& var_name = String::Handle(); | 957 String& var_name = String::Handle(); |
952 Object& value = Instance::Handle(); | 958 Object& value = Instance::Handle(); |
953 const Array& list = Array::Handle(Array::New(2 * num_variables)); | 959 const Array& list = Array::Handle(Array::New(2 * num_variables)); |
954 for (intptr_t i = 0; i < num_variables; i++) { | 960 for (intptr_t i = 0; i < num_variables; i++) { |
955 intptr_t ignore; | 961 intptr_t ignore; |
956 VariableAt(i, &var_name, &ignore, &ignore, &value); | 962 VariableAt(i, &var_name, &ignore, &ignore, &value); |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 } | 1843 } |
1838 } | 1844 } |
1839 } | 1845 } |
1840 } | 1846 } |
1841 } | 1847 } |
1842 return best_fit.raw(); | 1848 return best_fit.raw(); |
1843 } | 1849 } |
1844 | 1850 |
1845 | 1851 |
1846 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 1852 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
1847 intptr_t token_pos, | 1853 intptr_t token_pos, |
1848 intptr_t last_token_pos) { | 1854 intptr_t last_token_pos) { |
1849 Function& func = Function::Handle(isolate_); | 1855 Function& func = Function::Handle(isolate_); |
1850 func = FindBestFit(script, token_pos); | 1856 func = FindBestFit(script, token_pos); |
1851 if (func.IsNull()) { | 1857 if (func.IsNull()) { |
1852 return NULL; | 1858 return NULL; |
1853 } | 1859 } |
1854 // There may be more than one function object for a given function | 1860 // There may be more than one function object for a given function |
1855 // in source code. There may be implicit closure functions, and | 1861 // in source code. There may be implicit closure functions, and |
1856 // there may be copies of mixin functions. Collect all compiled | 1862 // there may be copies of mixin functions. Collect all compiled |
1857 // functions whose source code range matches exactly the best fit | 1863 // functions whose source code range matches exactly the best fit |
1858 // function we found. | 1864 // function we found. |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2369 Breakpoint* bpt) { | 2375 Breakpoint* bpt) { |
2370 resume_action_ = kContinue; | 2376 resume_action_ = kContinue; |
2371 stepping_fp_ = 0; | 2377 stepping_fp_ = 0; |
2372 isolate_->set_single_step(false); | 2378 isolate_->set_single_step(false); |
2373 ASSERT(!IsPaused()); | 2379 ASSERT(!IsPaused()); |
2374 ASSERT(obj_cache_ == NULL); | 2380 ASSERT(obj_cache_ == NULL); |
2375 if ((bpt != NULL) && bpt->IsSingleShot()) { | 2381 if ((bpt != NULL) && bpt->IsSingleShot()) { |
2376 RemoveBreakpoint(bpt->id()); | 2382 RemoveBreakpoint(bpt->id()); |
2377 bpt = NULL; | 2383 bpt = NULL; |
2378 } | 2384 } |
| 2385 |
2379 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached); | 2386 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached); |
2380 event.set_top_frame(top_frame); | 2387 event.set_top_frame(top_frame); |
2381 event.set_breakpoint(bpt); | 2388 event.set_breakpoint(bpt); |
| 2389 Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation()); |
| 2390 event.set_async_continuation(&closure_or_null); |
2382 Pause(&event); | 2391 Pause(&event); |
2383 } | 2392 } |
2384 | 2393 |
2385 | 2394 |
2386 void Debugger::DebuggerStepCallback() { | 2395 void Debugger::DebuggerStepCallback() { |
2387 ASSERT(isolate_->single_step()); | 2396 ASSERT(isolate_->single_step()); |
2388 // We can't get here unless the debugger event handler enabled | 2397 // We can't get here unless the debugger event handler enabled |
2389 // single stepping. | 2398 // single stepping. |
2390 ASSERT(HasEventHandler()); | 2399 ASSERT(HasEventHandler()); |
2391 // Don't pause recursively. | 2400 // Don't pause recursively. |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2991 } | 3000 } |
2992 | 3001 |
2993 | 3002 |
2994 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3003 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
2995 ASSERT(bpt->next() == NULL); | 3004 ASSERT(bpt->next() == NULL); |
2996 bpt->set_next(code_breakpoints_); | 3005 bpt->set_next(code_breakpoints_); |
2997 code_breakpoints_ = bpt; | 3006 code_breakpoints_ = bpt; |
2998 } | 3007 } |
2999 | 3008 |
3000 } // namespace dart | 3009 } // namespace dart |
OLD | NEW |