| 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 "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 private: | 35 private: |
| 36 GrowableObjectArray* objs_; | 36 GrowableObjectArray* objs_; |
| 37 | 37 |
| 38 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); | 38 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 | 41 |
| 42 SourceBreakpoint::SourceBreakpoint(intptr_t id, | 42 SourceBreakpoint::SourceBreakpoint(intptr_t id, |
| 43 const Function& func, | 43 const Function& func, |
| 44 intptr_t token_index) | 44 intptr_t token_pos) |
| 45 : id_(id), | 45 : id_(id), |
| 46 function_(func.raw()), | 46 function_(func.raw()), |
| 47 token_index_(token_index), | 47 token_pos_(token_pos), |
| 48 line_number_(-1), | 48 line_number_(-1), |
| 49 is_enabled_(false), | 49 is_enabled_(false), |
| 50 next_(NULL) { | 50 next_(NULL) { |
| 51 ASSERT(!func.IsNull()); | 51 ASSERT(!func.IsNull()); |
| 52 ASSERT((func.token_index() <= token_index_) && | 52 ASSERT((func.token_pos() <= token_pos_) && |
| 53 (token_index_ < func.end_token_index())); | 53 (token_pos_ < func.end_token_pos())); |
| 54 } | 54 } |
| 55 | 55 |
| 56 | 56 |
| 57 void SourceBreakpoint::Enable() { | 57 void SourceBreakpoint::Enable() { |
| 58 is_enabled_ = true; | 58 is_enabled_ = true; |
| 59 Isolate::Current()->debugger()->SyncBreakpoint(this); | 59 Isolate::Current()->debugger()->SyncBreakpoint(this); |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void SourceBreakpoint::Disable() { | 63 void SourceBreakpoint::Disable() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 77 const Script& script = Script::Handle(SourceCode()); | 77 const Script& script = Script::Handle(SourceCode()); |
| 78 return script.url(); | 78 return script.url(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 intptr_t SourceBreakpoint::LineNumber() { | 82 intptr_t SourceBreakpoint::LineNumber() { |
| 83 // Compute line number lazily since it causes scanning of the script. | 83 // Compute line number lazily since it causes scanning of the script. |
| 84 if (line_number_ < 0) { | 84 if (line_number_ < 0) { |
| 85 const Script& script = Script::Handle(SourceCode()); | 85 const Script& script = Script::Handle(SourceCode()); |
| 86 intptr_t ignore_column; | 86 intptr_t ignore_column; |
| 87 script.GetTokenLocation(token_index_, &line_number_, &ignore_column); | 87 script.GetTokenLocation(token_pos_, &line_number_, &ignore_column); |
| 88 } | 88 } |
| 89 return line_number_; | 89 return line_number_; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 void SourceBreakpoint::set_function(const Function& func) { | 93 void SourceBreakpoint::set_function(const Function& func) { |
| 94 function_ = func.raw(); | 94 function_ = func.raw(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 | 97 |
| 98 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 98 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 99 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 99 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
| 100 } | 100 } |
| 101 | 101 |
| 102 | 102 |
| 103 | 103 |
| 104 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 104 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 105 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 105 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, | 109 ActivationFrame::ActivationFrame(uword pc, uword fp, uword sp, |
| 110 const Context& ctx) | 110 const Context& ctx) |
| 111 : pc_(pc), fp_(fp), sp_(sp), | 111 : pc_(pc), fp_(fp), sp_(sp), |
| 112 ctx_(Context::ZoneHandle(ctx.raw())), | 112 ctx_(Context::ZoneHandle(ctx.raw())), |
| 113 function_(Function::ZoneHandle()), | 113 function_(Function::ZoneHandle()), |
| 114 token_index_(-1), | 114 token_pos_(-1), |
| 115 pc_desc_index_(-1), | 115 pc_desc_index_(-1), |
| 116 line_number_(-1), | 116 line_number_(-1), |
| 117 context_level_(-1), | 117 context_level_(-1), |
| 118 vars_initialized_(false), | 118 vars_initialized_(false), |
| 119 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 119 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
| 120 desc_indices_(8), | 120 desc_indices_(8), |
| 121 pc_desc_(PcDescriptors::ZoneHandle()) { | 121 pc_desc_(PcDescriptors::ZoneHandle()) { |
| 122 } | 122 } |
| 123 | 123 |
| 124 | 124 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 const Function& func = DartFunction(); | 178 const Function& func = DartFunction(); |
| 179 ASSERT(!func.HasOptimizedCode()); | 179 ASSERT(!func.HasOptimizedCode()); |
| 180 Code& code = Code::Handle(func.unoptimized_code()); | 180 Code& code = Code::Handle(func.unoptimized_code()); |
| 181 ASSERT(!code.IsNull()); | 181 ASSERT(!code.IsNull()); |
| 182 pc_desc_ = code.pc_descriptors(); | 182 pc_desc_ = code.pc_descriptors(); |
| 183 ASSERT(!pc_desc_.IsNull()); | 183 ASSERT(!pc_desc_.IsNull()); |
| 184 } | 184 } |
| 185 } | 185 } |
| 186 | 186 |
| 187 | 187 |
| 188 // Compute token_index_ and pc_desc_index_. | 188 // Compute token_pos_ and pc_desc_index_. |
| 189 intptr_t ActivationFrame::TokenIndex() { | 189 intptr_t ActivationFrame::TokenIndex() { |
| 190 if (token_index_ < 0) { | 190 if (token_pos_ < 0) { |
| 191 GetPcDescriptors(); | 191 GetPcDescriptors(); |
| 192 for (int i = 0; i < pc_desc_.Length(); i++) { | 192 for (int i = 0; i < pc_desc_.Length(); i++) { |
| 193 if (pc_desc_.PC(i) == pc_) { | 193 if (pc_desc_.PC(i) == pc_) { |
| 194 pc_desc_index_ = i; | 194 pc_desc_index_ = i; |
| 195 token_index_ = pc_desc_.TokenIndex(i); | 195 token_pos_ = pc_desc_.TokenIndex(i); |
| 196 break; | 196 break; |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 ASSERT(token_index_ >= 0); | 199 ASSERT(token_pos_ >= 0); |
| 200 } | 200 } |
| 201 return token_index_; | 201 return token_pos_; |
| 202 } | 202 } |
| 203 | 203 |
| 204 | 204 |
| 205 intptr_t ActivationFrame::PcDescIndex() { | 205 intptr_t ActivationFrame::PcDescIndex() { |
| 206 if (pc_desc_index_ < 0) { | 206 if (pc_desc_index_ < 0) { |
| 207 TokenIndex(); | 207 TokenIndex(); |
| 208 ASSERT(pc_desc_index_ >= 0); | 208 ASSERT(pc_desc_index_ >= 0); |
| 209 } | 209 } |
| 210 return pc_desc_index_; | 210 return pc_desc_index_; |
| 211 } | 211 } |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 pc_(0), | 448 pc_(0), |
| 449 line_number_(-1), | 449 line_number_(-1), |
| 450 is_enabled_(false), | 450 is_enabled_(false), |
| 451 src_bpt_(NULL), | 451 src_bpt_(NULL), |
| 452 next_(NULL) { | 452 next_(NULL) { |
| 453 ASSERT(!func.HasOptimizedCode()); | 453 ASSERT(!func.HasOptimizedCode()); |
| 454 Code& code = Code::Handle(func.unoptimized_code()); | 454 Code& code = Code::Handle(func.unoptimized_code()); |
| 455 ASSERT(!code.IsNull()); // Function must be compiled. | 455 ASSERT(!code.IsNull()); // Function must be compiled. |
| 456 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 456 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 457 ASSERT(pc_desc_index < desc.Length()); | 457 ASSERT(pc_desc_index < desc.Length()); |
| 458 token_index_ = desc.TokenIndex(pc_desc_index); | 458 token_pos_ = desc.TokenIndex(pc_desc_index); |
| 459 ASSERT(token_index_ >= 0); | 459 ASSERT(token_pos_ >= 0); |
| 460 pc_ = desc.PC(pc_desc_index); | 460 pc_ = desc.PC(pc_desc_index); |
| 461 ASSERT(pc_ != 0); | 461 ASSERT(pc_ != 0); |
| 462 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 462 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |
| 463 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || | 463 ASSERT((breakpoint_kind_ == PcDescriptors::kIcCall) || |
| 464 (breakpoint_kind_ == PcDescriptors::kFuncCall) || | 464 (breakpoint_kind_ == PcDescriptors::kFuncCall) || |
| 465 (breakpoint_kind_ == PcDescriptors::kReturn)); | 465 (breakpoint_kind_ == PcDescriptors::kReturn)); |
| 466 } | 466 } |
| 467 | 467 |
| 468 | 468 |
| 469 CodeBreakpoint::~CodeBreakpoint() { | 469 CodeBreakpoint::~CodeBreakpoint() { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 491 const Script& script = Script::Handle(SourceCode()); | 491 const Script& script = Script::Handle(SourceCode()); |
| 492 return script.url(); | 492 return script.url(); |
| 493 } | 493 } |
| 494 | 494 |
| 495 | 495 |
| 496 intptr_t CodeBreakpoint::LineNumber() { | 496 intptr_t CodeBreakpoint::LineNumber() { |
| 497 // Compute line number lazily since it causes scanning of the script. | 497 // Compute line number lazily since it causes scanning of the script. |
| 498 if (line_number_ < 0) { | 498 if (line_number_ < 0) { |
| 499 const Script& script = Script::Handle(SourceCode()); | 499 const Script& script = Script::Handle(SourceCode()); |
| 500 intptr_t ignore_column; | 500 intptr_t ignore_column; |
| 501 script.GetTokenLocation(token_index_, &line_number_, &ignore_column); | 501 script.GetTokenLocation(token_pos_, &line_number_, &ignore_column); |
| 502 } | 502 } |
| 503 return line_number_; | 503 return line_number_; |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 void CodeBreakpoint::PatchCode() { | 507 void CodeBreakpoint::PatchCode() { |
| 508 ASSERT(!is_enabled_); | 508 ASSERT(!is_enabled_); |
| 509 switch (breakpoint_kind_) { | 509 switch (breakpoint_kind_) { |
| 510 case PcDescriptors::kIcCall: { | 510 case PcDescriptors::kIcCall: { |
| 511 int num_args, num_named_args; | 511 int num_args, num_named_args; |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 event.type = kExceptionThrown; | 807 event.type = kExceptionThrown; |
| 808 event.exception = &exc; | 808 event.exception = &exc; |
| 809 ASSERT(event_handler_ != NULL); | 809 ASSERT(event_handler_ != NULL); |
| 810 (*event_handler_)(&event); | 810 (*event_handler_)(&event); |
| 811 stack_trace_ = NULL; | 811 stack_trace_ = NULL; |
| 812 obj_cache_ = NULL; // Remote object cache is zone allocated. | 812 obj_cache_ = NULL; // Remote object cache is zone allocated. |
| 813 } | 813 } |
| 814 | 814 |
| 815 | 815 |
| 816 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func, | 816 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func, |
| 817 intptr_t token_index) { | 817 intptr_t token_pos) { |
| 818 ASSERT(func.HasCode()); | 818 ASSERT(func.HasCode()); |
| 819 ASSERT(!func.HasOptimizedCode()); | 819 ASSERT(!func.HasOptimizedCode()); |
| 820 Code& code = Code::Handle(func.unoptimized_code()); | 820 Code& code = Code::Handle(func.unoptimized_code()); |
| 821 ASSERT(!code.IsNull()); | 821 ASSERT(!code.IsNull()); |
| 822 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 822 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 823 intptr_t best_fit_index = -1; | 823 intptr_t best_fit_index = -1; |
| 824 intptr_t best_fit = INT_MAX; | 824 intptr_t best_fit = INT_MAX; |
| 825 for (int i = 0; i < desc.Length(); i++) { | 825 for (int i = 0; i < desc.Length(); i++) { |
| 826 intptr_t desc_token_index = desc.TokenIndex(i); | 826 intptr_t desc_token_pos = desc.TokenIndex(i); |
| 827 if (desc_token_index < token_index) { | 827 if (desc_token_pos < token_pos) { |
| 828 continue; | 828 continue; |
| 829 } | 829 } |
| 830 PcDescriptors::Kind kind = desc.DescriptorKind(i); | 830 PcDescriptors::Kind kind = desc.DescriptorKind(i); |
| 831 if ((kind == PcDescriptors::kIcCall) || | 831 if ((kind == PcDescriptors::kIcCall) || |
| 832 (kind == PcDescriptors::kFuncCall) || | 832 (kind == PcDescriptors::kFuncCall) || |
| 833 (kind == PcDescriptors::kReturn)) { | 833 (kind == PcDescriptors::kReturn)) { |
| 834 if ((desc_token_index - token_index) < best_fit) { | 834 if ((desc_token_pos - token_pos) < best_fit) { |
| 835 best_fit = desc_token_index - token_index; | 835 best_fit = desc_token_pos - token_pos; |
| 836 ASSERT(best_fit >= 0); | 836 ASSERT(best_fit >= 0); |
| 837 best_fit_index = i; | 837 best_fit_index = i; |
| 838 } | 838 } |
| 839 } | 839 } |
| 840 } | 840 } |
| 841 if (best_fit_index >= 0) { | 841 if (best_fit_index >= 0) { |
| 842 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(best_fit_index)); | 842 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(best_fit_index)); |
| 843 // We should only ever have one code breakpoint at the same address. | 843 // We should only ever have one code breakpoint at the same address. |
| 844 // If we find an existing breakpoint, it must be an internal one which | 844 // If we find an existing breakpoint, it must be an internal one which |
| 845 // is used for stepping. | 845 // is used for stepping. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 857 bpt->pc()); | 857 bpt->pc()); |
| 858 } | 858 } |
| 859 RegisterCodeBreakpoint(bpt); | 859 RegisterCodeBreakpoint(bpt); |
| 860 return bpt; | 860 return bpt; |
| 861 } | 861 } |
| 862 return NULL; | 862 return NULL; |
| 863 } | 863 } |
| 864 | 864 |
| 865 | 865 |
| 866 SourceBreakpoint* Debugger::SetBreakpoint(const Function& target_function, | 866 SourceBreakpoint* Debugger::SetBreakpoint(const Function& target_function, |
| 867 intptr_t token_index) { | 867 intptr_t token_pos) { |
| 868 if ((token_index < target_function.token_index()) || | 868 if ((token_pos < target_function.token_pos()) || |
| 869 (target_function.end_token_index() <= token_index)) { | 869 (target_function.end_token_pos() <= token_pos)) { |
| 870 // The given token position is not within the target function. | 870 // The given token position is not within the target function. |
| 871 return NULL; | 871 return NULL; |
| 872 } | 872 } |
| 873 EnsureFunctionIsDeoptimized(target_function); | 873 EnsureFunctionIsDeoptimized(target_function); |
| 874 SourceBreakpoint* bpt = GetSourceBreakpoint(target_function, token_index); | 874 SourceBreakpoint* bpt = GetSourceBreakpoint(target_function, token_pos); |
| 875 if (bpt != NULL) { | 875 if (bpt != NULL) { |
| 876 // A breakpoint for this location already exists, return it. | 876 // A breakpoint for this location already exists, return it. |
| 877 return bpt; | 877 return bpt; |
| 878 } | 878 } |
| 879 bpt = new SourceBreakpoint(nextId(), target_function, token_index); | 879 bpt = new SourceBreakpoint(nextId(), target_function, token_pos); |
| 880 RegisterSourceBreakpoint(bpt); | 880 RegisterSourceBreakpoint(bpt); |
| 881 if (verbose && !target_function.HasCode()) { | 881 if (verbose && !target_function.HasCode()) { |
| 882 OS::Print("Registering breakpoint for uncompiled function '%s'" | 882 OS::Print("Registering breakpoint for uncompiled function '%s'" |
| 883 " (%s:%d)\n", | 883 " (%s:%d)\n", |
| 884 String::Handle(target_function.name()).ToCString(), | 884 String::Handle(target_function.name()).ToCString(), |
| 885 String::Handle(bpt->SourceUrl()).ToCString(), | 885 String::Handle(bpt->SourceUrl()).ToCString(), |
| 886 bpt->LineNumber()); | 886 bpt->LineNumber()); |
| 887 } | 887 } |
| 888 | 888 |
| 889 if (target_function.HasCode()) { | 889 if (target_function.HasCode()) { |
| 890 CodeBreakpoint* cbpt = MakeCodeBreakpoint(target_function, token_index); | 890 CodeBreakpoint* cbpt = MakeCodeBreakpoint(target_function, token_pos); |
| 891 if (cbpt != NULL) { | 891 if (cbpt != NULL) { |
| 892 ASSERT(cbpt->src_bpt() == NULL); | 892 ASSERT(cbpt->src_bpt() == NULL); |
| 893 cbpt->set_src_bpt(bpt); | 893 cbpt->set_src_bpt(bpt); |
| 894 SignalBpResolved(bpt); | 894 SignalBpResolved(bpt); |
| 895 } else { | 895 } else { |
| 896 if (verbose) { | 896 if (verbose) { |
| 897 OS::Print("Failed to set breakpoint at '%s' line %d\n", | 897 OS::Print("Failed to set breakpoint at '%s' line %d\n", |
| 898 String::Handle(bpt->SourceUrl()).ToCString(), | 898 String::Handle(bpt->SourceUrl()).ToCString(), |
| 899 bpt->LineNumber()); | 899 bpt->LineNumber()); |
| 900 } | 900 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 918 } | 918 } |
| 919 } | 919 } |
| 920 cbpt = cbpt->next(); | 920 cbpt = cbpt->next(); |
| 921 } | 921 } |
| 922 } | 922 } |
| 923 | 923 |
| 924 | 924 |
| 925 SourceBreakpoint* Debugger::SetBreakpointAtEntry( | 925 SourceBreakpoint* Debugger::SetBreakpointAtEntry( |
| 926 const Function& target_function) { | 926 const Function& target_function) { |
| 927 ASSERT(!target_function.IsNull()); | 927 ASSERT(!target_function.IsNull()); |
| 928 return SetBreakpoint(target_function, target_function.token_index()); | 928 return SetBreakpoint(target_function, target_function.token_pos()); |
| 929 } | 929 } |
| 930 | 930 |
| 931 | 931 |
| 932 SourceBreakpoint* Debugger::SetBreakpointAtLine(const String& script_url, | 932 SourceBreakpoint* Debugger::SetBreakpointAtLine(const String& script_url, |
| 933 intptr_t line_number) { | 933 intptr_t line_number) { |
| 934 Library& lib = Library::Handle(); | 934 Library& lib = Library::Handle(); |
| 935 Script& script = Script::Handle(); | 935 Script& script = Script::Handle(); |
| 936 const GrowableObjectArray& libs = | 936 const GrowableObjectArray& libs = |
| 937 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 937 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
| 938 for (int i = 0; i < libs.Length(); i++) { | 938 for (int i = 0; i < libs.Length(); i++) { |
| 939 lib ^= libs.At(i); | 939 lib ^= libs.At(i); |
| 940 script = lib.LookupScript(script_url); | 940 script = lib.LookupScript(script_url); |
| 941 if (!script.IsNull()) { | 941 if (!script.IsNull()) { |
| 942 break; | 942 break; |
| 943 } | 943 } |
| 944 } | 944 } |
| 945 if (script.IsNull()) { | 945 if (script.IsNull()) { |
| 946 if (verbose) { | 946 if (verbose) { |
| 947 OS::Print("Failed to find script with url '%s'\n", | 947 OS::Print("Failed to find script with url '%s'\n", |
| 948 script_url.ToCString()); | 948 script_url.ToCString()); |
| 949 } | 949 } |
| 950 return NULL; | 950 return NULL; |
| 951 } | 951 } |
| 952 intptr_t token_index_at_line = script.TokenIndexAtLine(line_number); | 952 intptr_t token_pos_at_line = script.TokenIndexAtLine(line_number); |
| 953 if (token_index_at_line < 0) { | 953 if (token_pos_at_line < 0) { |
| 954 // Script does not contain the given line number. | 954 // Script does not contain the given line number. |
| 955 if (verbose) { | 955 if (verbose) { |
| 956 OS::Print("Script '%s' does not contain line number %d\n", | 956 OS::Print("Script '%s' does not contain line number %d\n", |
| 957 script_url.ToCString(), line_number); | 957 script_url.ToCString(), line_number); |
| 958 } | 958 } |
| 959 return NULL; | 959 return NULL; |
| 960 } | 960 } |
| 961 const Function& func = | 961 const Function& func = |
| 962 Function::Handle(lib.LookupFunctionInScript(script, token_index_at_line)); | 962 Function::Handle(lib.LookupFunctionInScript(script, token_pos_at_line)); |
| 963 if (func.IsNull()) { | 963 if (func.IsNull()) { |
| 964 if (verbose) { | 964 if (verbose) { |
| 965 OS::Print("No executable code at line %d in '%s'\n", | 965 OS::Print("No executable code at line %d in '%s'\n", |
| 966 line_number, script_url.ToCString()); | 966 line_number, script_url.ToCString()); |
| 967 } | 967 } |
| 968 return NULL; | 968 return NULL; |
| 969 } | 969 } |
| 970 return SetBreakpoint(func, token_index_at_line); | 970 return SetBreakpoint(func, token_pos_at_line); |
| 971 } | 971 } |
| 972 | 972 |
| 973 | 973 |
| 974 intptr_t Debugger::CacheObject(const Object& obj) { | 974 intptr_t Debugger::CacheObject(const Object& obj) { |
| 975 ASSERT(obj_cache_ != NULL); | 975 ASSERT(obj_cache_ != NULL); |
| 976 return obj_cache_->AddObject(obj); | 976 return obj_cache_->AddObject(obj); |
| 977 } | 977 } |
| 978 | 978 |
| 979 | 979 |
| 980 bool Debugger::IsValidObjectId(intptr_t obj_id) { | 980 bool Debugger::IsValidObjectId(intptr_t obj_id) { |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 lookup_function = func.parent_function(); | 1327 lookup_function = func.parent_function(); |
| 1328 ASSERT(!lookup_function.IsNull()); | 1328 ASSERT(!lookup_function.IsNull()); |
| 1329 } | 1329 } |
| 1330 SourceBreakpoint* bpt = src_breakpoints_; | 1330 SourceBreakpoint* bpt = src_breakpoints_; |
| 1331 while (bpt != NULL) { | 1331 while (bpt != NULL) { |
| 1332 if (lookup_function.raw() == bpt->function()) { | 1332 if (lookup_function.raw() == bpt->function()) { |
| 1333 // Check if the breakpoint is inside a closure or local function | 1333 // Check if the breakpoint is inside a closure or local function |
| 1334 // within the newly compiled function. | 1334 // within the newly compiled function. |
| 1335 Class& owner = Class::Handle(lookup_function.owner()); | 1335 Class& owner = Class::Handle(lookup_function.owner()); |
| 1336 Function& closure = | 1336 Function& closure = |
| 1337 Function::Handle(owner.LookupClosureFunction(bpt->token_index())); | 1337 Function::Handle(owner.LookupClosureFunction(bpt->token_pos())); |
| 1338 if (!closure.IsNull() && (closure.raw() != lookup_function.raw())) { | 1338 if (!closure.IsNull() && (closure.raw() != lookup_function.raw())) { |
| 1339 if (verbose) { | 1339 if (verbose) { |
| 1340 OS::Print("Resetting pending breakpoint to function %s\n", | 1340 OS::Print("Resetting pending breakpoint to function %s\n", |
| 1341 String::Handle(closure.name()).ToCString()); | 1341 String::Handle(closure.name()).ToCString()); |
| 1342 } | 1342 } |
| 1343 bpt->set_function(closure); | 1343 bpt->set_function(closure); |
| 1344 } else { | 1344 } else { |
| 1345 if (verbose) { | 1345 if (verbose) { |
| 1346 OS::Print("Enable pending breakpoint for function '%s'\n", | 1346 OS::Print("Enable pending breakpoint for function '%s'\n", |
| 1347 String::Handle(lookup_function.name()).ToCString()); | 1347 String::Handle(lookup_function.name()).ToCString()); |
| 1348 } | 1348 } |
| 1349 // Set breakpoint in newly compiled code of function func. | 1349 // Set breakpoint in newly compiled code of function func. |
| 1350 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_index()); | 1350 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_pos()); |
| 1351 if (cbpt != NULL) { | 1351 if (cbpt != NULL) { |
| 1352 cbpt->set_src_bpt(bpt); | 1352 cbpt->set_src_bpt(bpt); |
| 1353 SignalBpResolved(bpt); | 1353 SignalBpResolved(bpt); |
| 1354 } | 1354 } |
| 1355 } | 1355 } |
| 1356 bpt->Enable(); // Enables the code breakpoint as well. | 1356 bpt->Enable(); // Enables the code breakpoint as well. |
| 1357 } | 1357 } |
| 1358 bpt = bpt->next(); | 1358 bpt = bpt->next(); |
| 1359 } | 1359 } |
| 1360 } | 1360 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1433 delete temp_bpt; | 1433 delete temp_bpt; |
| 1434 } else { | 1434 } else { |
| 1435 prev_bpt = curr_bpt; | 1435 prev_bpt = curr_bpt; |
| 1436 curr_bpt = curr_bpt->next(); | 1436 curr_bpt = curr_bpt->next(); |
| 1437 } | 1437 } |
| 1438 } | 1438 } |
| 1439 } | 1439 } |
| 1440 | 1440 |
| 1441 | 1441 |
| 1442 SourceBreakpoint* Debugger::GetSourceBreakpoint(const Function& func, | 1442 SourceBreakpoint* Debugger::GetSourceBreakpoint(const Function& func, |
| 1443 intptr_t token_index) { | 1443 intptr_t token_pos) { |
| 1444 SourceBreakpoint* bpt = src_breakpoints_; | 1444 SourceBreakpoint* bpt = src_breakpoints_; |
| 1445 while (bpt != NULL) { | 1445 while (bpt != NULL) { |
| 1446 if ((bpt->function() == func.raw()) && | 1446 if ((bpt->function() == func.raw()) && |
| 1447 (bpt->token_index() == token_index)) { | 1447 (bpt->token_pos() == token_pos)) { |
| 1448 return bpt; | 1448 return bpt; |
| 1449 } | 1449 } |
| 1450 bpt = bpt->next(); | 1450 bpt = bpt->next(); |
| 1451 } | 1451 } |
| 1452 return NULL; | 1452 return NULL; |
| 1453 } | 1453 } |
| 1454 | 1454 |
| 1455 | 1455 |
| 1456 SourceBreakpoint* Debugger::GetBreakpointById(intptr_t id) { | 1456 SourceBreakpoint* Debugger::GetBreakpointById(intptr_t id) { |
| 1457 SourceBreakpoint* bpt = src_breakpoints_; | 1457 SourceBreakpoint* bpt = src_breakpoints_; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 | 1474 |
| 1475 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1475 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1476 ASSERT(bpt->next() == NULL); | 1476 ASSERT(bpt->next() == NULL); |
| 1477 bpt->set_next(code_breakpoints_); | 1477 bpt->set_next(code_breakpoints_); |
| 1478 code_breakpoints_ = bpt; | 1478 code_breakpoints_ = bpt; |
| 1479 } | 1479 } |
| 1480 | 1480 |
| 1481 } // namespace dart | 1481 } // namespace dart |
| OLD | NEW |