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" |
11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/deopt_instructions.h" | 13 #include "vm/deopt_instructions.h" |
14 #include "vm/flags.h" | 14 #include "vm/flags.h" |
15 #include "vm/globals.h" | 15 #include "vm/globals.h" |
16 #include "vm/longjump.h" | 16 #include "vm/longjump.h" |
17 #include "vm/json_stream.h" | 17 #include "vm/json_stream.h" |
18 #include "vm/message_handler.h" | 18 #include "vm/message_handler.h" |
19 #include "vm/object.h" | 19 #include "vm/object.h" |
20 #include "vm/object_store.h" | 20 #include "vm/object_store.h" |
21 #include "vm/os.h" | 21 #include "vm/os.h" |
22 #include "vm/port.h" | 22 #include "vm/port.h" |
23 #include "vm/service_event.h" | 23 #include "vm/service_event.h" |
24 #include "vm/service_isolate.h" | 24 #include "vm/service_isolate.h" |
25 #include "vm/service.h" | 25 #include "vm/service.h" |
26 #include "vm/stack_frame.h" | 26 #include "vm/stack_frame.h" |
27 #include "vm/stub_code.h" | 27 #include "vm/stub_code.h" |
28 #include "vm/symbols.h" | 28 #include "vm/symbols.h" |
29 #include "vm/thread_interrupter.h" | 29 #include "vm/thread_interrupter.h" |
| 30 #include "vm/token_position.h" |
30 #include "vm/visitor.h" | 31 #include "vm/visitor.h" |
31 | 32 |
32 | 33 |
33 namespace dart { | 34 namespace dart { |
34 | 35 |
35 DEFINE_FLAG(bool, show_invisible_frames, false, | 36 DEFINE_FLAG(bool, show_invisible_frames, false, |
36 "Show invisible frames in debugger stack traces"); | 37 "Show invisible frames in debugger stack traces"); |
37 DEFINE_FLAG(bool, trace_debugger_stacktrace, false, | 38 DEFINE_FLAG(bool, trace_debugger_stacktrace, false, |
38 "Trace debugger stacktrace collection"); | 39 "Trace debugger stacktrace collection"); |
39 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); | 40 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); |
(...skipping 22 matching lines...) Expand all Loading... |
62 | 63 |
63 private: | 64 private: |
64 GrowableObjectArray* objs_; | 65 GrowableObjectArray* objs_; |
65 | 66 |
66 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); | 67 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); |
67 }; | 68 }; |
68 | 69 |
69 | 70 |
70 // Create an unresolved breakpoint in given token range and script. | 71 // Create an unresolved breakpoint in given token range and script. |
71 BreakpointLocation::BreakpointLocation(const Script& script, | 72 BreakpointLocation::BreakpointLocation(const Script& script, |
72 intptr_t token_pos, | 73 TokenPosition token_pos, |
73 intptr_t end_token_pos, | 74 TokenPosition end_token_pos, |
74 intptr_t requested_line_number, | 75 intptr_t requested_line_number, |
75 intptr_t requested_column_number) | 76 intptr_t requested_column_number) |
76 : script_(script.raw()), | 77 : script_(script.raw()), |
77 url_(script.url()), | 78 url_(script.url()), |
78 token_pos_(token_pos), | 79 token_pos_(token_pos), |
79 end_token_pos_(end_token_pos), | 80 end_token_pos_(end_token_pos), |
80 is_resolved_(false), | 81 is_resolved_(false), |
81 next_(NULL), | 82 next_(NULL), |
82 conditions_(NULL), | 83 conditions_(NULL), |
83 requested_line_number_(requested_line_number), | 84 requested_line_number_(requested_line_number), |
84 requested_column_number_(requested_column_number), | 85 requested_column_number_(requested_column_number), |
85 function_(Function::null()), | 86 function_(Function::null()), |
86 line_number_(-1), | 87 line_number_(-1), |
87 column_number_(-1) { | 88 column_number_(-1) { |
88 ASSERT(!script.IsNull()); | 89 ASSERT(!script.IsNull()); |
89 ASSERT(Token::IsReal(token_pos_)); | 90 ASSERT(token_pos_.IsReal()); |
90 } | 91 } |
91 | 92 |
92 // Create a latent breakpoint at given url and line number. | 93 // Create a latent breakpoint at given url and line number. |
93 BreakpointLocation::BreakpointLocation(const String& url, | 94 BreakpointLocation::BreakpointLocation(const String& url, |
94 intptr_t requested_line_number, | 95 intptr_t requested_line_number, |
95 intptr_t requested_column_number) | 96 intptr_t requested_column_number) |
96 : script_(Script::null()), | 97 : script_(Script::null()), |
97 url_(url.raw()), | 98 url_(url.raw()), |
98 token_pos_(Token::kNoSourcePos), | 99 token_pos_(TokenPosition::kNoSource), |
99 end_token_pos_(Token::kNoSourcePos), | 100 end_token_pos_(TokenPosition::kNoSource), |
100 is_resolved_(false), | 101 is_resolved_(false), |
101 next_(NULL), | 102 next_(NULL), |
102 conditions_(NULL), | 103 conditions_(NULL), |
103 requested_line_number_(requested_line_number), | 104 requested_line_number_(requested_line_number), |
104 requested_column_number_(requested_column_number), | 105 requested_column_number_(requested_column_number), |
105 function_(Function::null()), | 106 function_(Function::null()), |
106 line_number_(-1), | 107 line_number_(-1), |
107 column_number_(-1) { | 108 column_number_(-1) { |
108 ASSERT(requested_line_number_ >= 0); | 109 ASSERT(requested_line_number_ >= 0); |
109 } | 110 } |
110 | 111 |
111 | 112 |
112 BreakpointLocation::~BreakpointLocation() { | 113 BreakpointLocation::~BreakpointLocation() { |
113 Breakpoint* bpt = breakpoints(); | 114 Breakpoint* bpt = breakpoints(); |
114 while (bpt != NULL) { | 115 while (bpt != NULL) { |
115 Breakpoint* temp = bpt; | 116 Breakpoint* temp = bpt; |
116 bpt = bpt->next(); | 117 bpt = bpt->next(); |
117 delete temp; | 118 delete temp; |
118 } | 119 } |
119 } | 120 } |
120 | 121 |
121 | 122 |
122 bool BreakpointLocation::AnyEnabled() const { | 123 bool BreakpointLocation::AnyEnabled() const { |
123 return breakpoints() != NULL; | 124 return breakpoints() != NULL; |
124 } | 125 } |
125 | 126 |
126 | 127 |
127 void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) { | 128 void BreakpointLocation::SetResolved(const Function& func, |
| 129 TokenPosition token_pos) { |
128 ASSERT(!IsLatent()); | 130 ASSERT(!IsLatent()); |
129 ASSERT(func.script() == script_); | 131 ASSERT(func.script() == script_); |
130 ASSERT((func.token_pos() <= token_pos) && | 132 ASSERT((func.token_pos() <= token_pos) && |
131 (token_pos <= func.end_token_pos())); | 133 (token_pos <= func.end_token_pos())); |
132 ASSERT(func.is_debuggable()); | 134 ASSERT(func.is_debuggable()); |
133 function_ = func.raw(); | 135 function_ = func.raw(); |
134 token_pos_ = token_pos; | 136 token_pos_ = token_pos; |
135 end_token_pos_ = token_pos; | 137 end_token_pos_ = token_pos; |
136 is_resolved_ = true; | 138 is_resolved_ = true; |
137 } | 139 } |
138 | 140 |
139 | 141 |
140 // TODO(hausner): Get rid of library parameter. A source breakpoint location | 142 // TODO(hausner): Get rid of library parameter. A source breakpoint location |
141 // does not imply a library, since the same source code can be included | 143 // does not imply a library, since the same source code can be included |
142 // in more than one library, e.g. the text location of mixin functions. | 144 // in more than one library, e.g. the text location of mixin functions. |
143 void BreakpointLocation::GetCodeLocation(Library* lib, | 145 void BreakpointLocation::GetCodeLocation(Library* lib, |
144 Script* script, | 146 Script* script, |
145 intptr_t* pos) const { | 147 TokenPosition* pos) const { |
146 if (IsLatent()) { | 148 if (IsLatent()) { |
147 *lib = Library::null(); | 149 *lib = Library::null(); |
148 *script = Script::null(); | 150 *script = Script::null(); |
149 *pos = -1; | 151 *pos = TokenPosition::kNoSource; |
150 } else { | 152 } else { |
151 *script = this->script(); | 153 *script = this->script(); |
152 *pos = token_pos_; | 154 *pos = token_pos_; |
153 if (IsResolved()) { | 155 if (IsResolved()) { |
154 const Function& func = Function::Handle(function_); | 156 const Function& func = Function::Handle(function_); |
155 ASSERT(!func.IsNull()); | 157 ASSERT(!func.IsNull()); |
156 const Class& cls = Class::Handle(func.origin()); | 158 const Class& cls = Class::Handle(func.origin()); |
157 *lib = cls.library(); | 159 *lib = cls.library(); |
158 } else { | 160 } else { |
159 *lib = Library::null(); | 161 *lib = Library::null(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 uword fp, | 236 uword fp, |
235 uword sp, | 237 uword sp, |
236 const Code& code, | 238 const Code& code, |
237 const Array& deopt_frame, | 239 const Array& deopt_frame, |
238 intptr_t deopt_frame_offset) | 240 intptr_t deopt_frame_offset) |
239 : pc_(pc), fp_(fp), sp_(sp), | 241 : pc_(pc), fp_(fp), sp_(sp), |
240 ctx_(Context::ZoneHandle()), | 242 ctx_(Context::ZoneHandle()), |
241 code_(Code::ZoneHandle(code.raw())), | 243 code_(Code::ZoneHandle(code.raw())), |
242 function_(Function::ZoneHandle(code.function())), | 244 function_(Function::ZoneHandle(code.function())), |
243 token_pos_initialized_(false), | 245 token_pos_initialized_(false), |
244 token_pos_(Token::kNoSourcePos), | 246 token_pos_(TokenPosition::kNoSource), |
245 try_index_(-1), | 247 try_index_(-1), |
246 line_number_(-1), | 248 line_number_(-1), |
247 column_number_(-1), | 249 column_number_(-1), |
248 context_level_(-1), | 250 context_level_(-1), |
249 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), | 251 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), |
250 deopt_frame_offset_(deopt_frame_offset), | 252 deopt_frame_offset_(deopt_frame_offset), |
251 vars_initialized_(false), | 253 vars_initialized_(false), |
252 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 254 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
253 desc_indices_(8), | 255 desc_indices_(8), |
254 pc_desc_(PcDescriptors::ZoneHandle()) { | 256 pc_desc_(PcDescriptors::ZoneHandle()) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 return OS::SCreate(Thread::Current()->zone(), | 452 return OS::SCreate(Thread::Current()->zone(), |
451 "%s%s%s", func_class.IsTopLevel() ? "" : class_name.ToCString(), | 453 "%s%s%s", func_class.IsTopLevel() ? "" : class_name.ToCString(), |
452 func_class.IsTopLevel() ? "" : ".", | 454 func_class.IsTopLevel() ? "" : ".", |
453 func_name.ToCString()); | 455 func_name.ToCString()); |
454 } | 456 } |
455 | 457 |
456 | 458 |
457 // Returns true if function contains the token position in the given script. | 459 // Returns true if function contains the token position in the given script. |
458 static bool FunctionContains(const Function& func, | 460 static bool FunctionContains(const Function& func, |
459 const Script& script, | 461 const Script& script, |
460 intptr_t token_pos) { | 462 TokenPosition token_pos) { |
461 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { | 463 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { |
462 // Check script equality second because it allocates | 464 // Check script equality second because it allocates |
463 // handles as a side effect. | 465 // handles as a side effect. |
464 return func.script() == script.raw(); | 466 return func.script() == script.raw(); |
465 } | 467 } |
466 return false; | 468 return false; |
467 } | 469 } |
468 | 470 |
469 | 471 |
470 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { | 472 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 | 564 |
563 void ActivationFrame::GetPcDescriptors() { | 565 void ActivationFrame::GetPcDescriptors() { |
564 if (pc_desc_.IsNull()) { | 566 if (pc_desc_.IsNull()) { |
565 pc_desc_ = code().pc_descriptors(); | 567 pc_desc_ = code().pc_descriptors(); |
566 ASSERT(!pc_desc_.IsNull()); | 568 ASSERT(!pc_desc_.IsNull()); |
567 } | 569 } |
568 } | 570 } |
569 | 571 |
570 | 572 |
571 // Compute token_pos_ and try_index_ and token_pos_initialized_. | 573 // Compute token_pos_ and try_index_ and token_pos_initialized_. |
572 intptr_t ActivationFrame::TokenPos() { | 574 TokenPosition ActivationFrame::TokenPos() { |
573 if (!token_pos_initialized_) { | 575 if (!token_pos_initialized_) { |
574 token_pos_initialized_ = true; | 576 token_pos_initialized_ = true; |
575 token_pos_ = Token::kNoSourcePos; | 577 token_pos_ = TokenPosition::kNoSource; |
576 GetPcDescriptors(); | 578 GetPcDescriptors(); |
577 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); | 579 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); |
578 uword pc_offset = pc_ - code().EntryPoint(); | 580 uword pc_offset = pc_ - code().EntryPoint(); |
579 while (iter.MoveNext()) { | 581 while (iter.MoveNext()) { |
580 if (iter.PcOffset() == pc_offset) { | 582 if (iter.PcOffset() == pc_offset) { |
581 try_index_ = iter.TryIndex(); | 583 try_index_ = iter.TryIndex(); |
582 token_pos_ = iter.TokenPos(); | 584 token_pos_ = iter.TokenPos(); |
583 break; | 585 break; |
584 } | 586 } |
585 } | 587 } |
586 } | 588 } |
587 return token_pos_; | 589 return token_pos_; |
588 } | 590 } |
589 | 591 |
590 | 592 |
591 intptr_t ActivationFrame::TryIndex() { | 593 intptr_t ActivationFrame::TryIndex() { |
592 if (!token_pos_initialized_) { | 594 if (!token_pos_initialized_) { |
593 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. | 595 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
594 } | 596 } |
595 return try_index_; | 597 return try_index_; |
596 } | 598 } |
597 | 599 |
598 | 600 |
599 intptr_t ActivationFrame::LineNumber() { | 601 intptr_t ActivationFrame::LineNumber() { |
600 // Compute line number lazily since it causes scanning of the script. | 602 // Compute line number lazily since it causes scanning of the script. |
601 if ((line_number_ < 0) && Token::IsReal(TokenPos())) { | 603 if ((line_number_ < 0) && TokenPos().IsReal()) { |
602 const intptr_t token_pos = TokenPos(); | 604 const TokenPosition token_pos = TokenPos(); |
603 const Script& script = Script::Handle(SourceScript()); | 605 const Script& script = Script::Handle(SourceScript()); |
604 script.GetTokenLocation(token_pos, &line_number_, NULL); | 606 script.GetTokenLocation(token_pos, &line_number_, NULL); |
605 } | 607 } |
606 return line_number_; | 608 return line_number_; |
607 } | 609 } |
608 | 610 |
609 | 611 |
610 intptr_t ActivationFrame::ColumnNumber() { | 612 intptr_t ActivationFrame::ColumnNumber() { |
611 // Compute column number lazily since it causes scanning of the script. | 613 // Compute column number lazily since it causes scanning of the script. |
612 if ((column_number_ < 0) && Token::IsReal(TokenPos())) { | 614 if ((column_number_ < 0) && TokenPos().IsReal()) { |
613 const intptr_t token_pos = TokenPos(); | 615 const TokenPosition token_pos = TokenPos(); |
614 const Script& script = Script::Handle(SourceScript()); | 616 const Script& script = Script::Handle(SourceScript()); |
615 if (script.HasSource()) { | 617 if (script.HasSource()) { |
616 script.GetTokenLocation(token_pos, &line_number_, &column_number_); | 618 script.GetTokenLocation(token_pos, &line_number_, &column_number_); |
617 } else { | 619 } else { |
618 column_number_ = -1; | 620 column_number_ = -1; |
619 } | 621 } |
620 } | 622 } |
621 return column_number_; | 623 return column_number_; |
622 } | 624 } |
623 | 625 |
(...skipping 24 matching lines...) Expand all Loading... |
648 // Calculate the context level at the current token index of the frame. | 650 // Calculate the context level at the current token index of the frame. |
649 intptr_t ActivationFrame::ContextLevel() { | 651 intptr_t ActivationFrame::ContextLevel() { |
650 const Context& ctx = GetSavedCurrentContext(); | 652 const Context& ctx = GetSavedCurrentContext(); |
651 if (context_level_ < 0 && !ctx.IsNull()) { | 653 if (context_level_ < 0 && !ctx.IsNull()) { |
652 ASSERT(!code_.is_optimized()); | 654 ASSERT(!code_.is_optimized()); |
653 context_level_ = 0; | 655 context_level_ = 0; |
654 // TODO(hausner): What to do if there is no descriptor entry | 656 // TODO(hausner): What to do if there is no descriptor entry |
655 // for the code position of the frame? For now say we are at context | 657 // for the code position of the frame? For now say we are at context |
656 // level 0. | 658 // level 0. |
657 TokenPos(); | 659 TokenPos(); |
658 if (token_pos_ == -1) { | 660 if (token_pos_ == TokenPosition::kNoSource) { |
659 // No PcDescriptor. | 661 // No PcDescriptor. |
660 return context_level_; | 662 return context_level_; |
661 } | 663 } |
662 ASSERT(!pc_desc_.IsNull()); | 664 ASSERT(!pc_desc_.IsNull()); |
663 intptr_t innermost_begin_pos = 0; | 665 TokenPosition innermost_begin_pos = TokenPosition::kMinSource; |
664 intptr_t activation_token_pos = TokenPos(); | 666 TokenPosition activation_token_pos = TokenPos(); |
665 ASSERT(Token::IsReal(activation_token_pos)); | 667 ASSERT(activation_token_pos.IsReal()); |
666 GetVarDescriptors(); | 668 GetVarDescriptors(); |
667 intptr_t var_desc_len = var_descriptors_.Length(); | 669 intptr_t var_desc_len = var_descriptors_.Length(); |
668 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 670 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
669 RawLocalVarDescriptors::VarInfo var_info; | 671 RawLocalVarDescriptors::VarInfo var_info; |
670 var_descriptors_.GetInfo(cur_idx, &var_info); | 672 var_descriptors_.GetInfo(cur_idx, &var_info); |
671 const int8_t kind = var_info.kind(); | 673 const int8_t kind = var_info.kind(); |
672 if ((kind == RawLocalVarDescriptors::kContextLevel) && | 674 if ((kind == RawLocalVarDescriptors::kContextLevel) && |
673 (var_info.begin_pos <= activation_token_pos) && | 675 (var_info.begin_pos <= activation_token_pos) && |
674 (activation_token_pos < var_info.end_pos)) { | 676 (activation_token_pos < var_info.end_pos)) { |
675 // This var_descriptors_ entry is a context scope which is in scope | 677 // This var_descriptors_ entry is a context scope which is in scope |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 return NULL; | 769 return NULL; |
768 } | 770 } |
769 | 771 |
770 | 772 |
771 void ActivationFrame::GetDescIndices() { | 773 void ActivationFrame::GetDescIndices() { |
772 if (vars_initialized_) { | 774 if (vars_initialized_) { |
773 return; | 775 return; |
774 } | 776 } |
775 GetVarDescriptors(); | 777 GetVarDescriptors(); |
776 | 778 |
777 intptr_t activation_token_pos = TokenPos(); | 779 TokenPosition activation_token_pos = TokenPos(); |
778 if (!Token::IsDebugPause(activation_token_pos)) { | 780 if (!activation_token_pos.IsDebugPause()) { |
779 // We don't have a token position for this frame, so can't determine | 781 // We don't have a token position for this frame, so can't determine |
780 // which variables are visible. | 782 // which variables are visible. |
781 vars_initialized_ = true; | 783 vars_initialized_ = true; |
782 return; | 784 return; |
783 } | 785 } |
784 | 786 |
785 GrowableArray<String*> var_names(8); | 787 GrowableArray<String*> var_names(8); |
786 intptr_t var_desc_len = var_descriptors_.Length(); | 788 intptr_t var_desc_len = var_descriptors_.Length(); |
787 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 789 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
788 ASSERT(var_names.length() == desc_indices_.length()); | 790 ASSERT(var_names.length() == desc_indices_.length()); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 intptr_t num = 0; | 930 intptr_t num = 0; |
929 while ((frame != NULL)) { | 931 while ((frame != NULL)) { |
930 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); | 932 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); |
931 frame = iterator.NextFrame(); | 933 frame = iterator.NextFrame(); |
932 } | 934 } |
933 } | 935 } |
934 | 936 |
935 | 937 |
936 void ActivationFrame::VariableAt(intptr_t i, | 938 void ActivationFrame::VariableAt(intptr_t i, |
937 String* name, | 939 String* name, |
938 intptr_t* token_pos, | 940 TokenPosition* token_pos, |
939 intptr_t* end_pos, | 941 TokenPosition* end_pos, |
940 Object* value) { | 942 Object* value) { |
941 GetDescIndices(); | 943 GetDescIndices(); |
942 ASSERT(i < desc_indices_.length()); | 944 ASSERT(i < desc_indices_.length()); |
943 intptr_t desc_index = desc_indices_[i]; | 945 intptr_t desc_index = desc_indices_[i]; |
944 ASSERT(name != NULL); | 946 ASSERT(name != NULL); |
945 | 947 |
946 *name = var_descriptors_.GetName(desc_index); | 948 *name = var_descriptors_.GetName(desc_index); |
947 | 949 |
948 RawLocalVarDescriptors::VarInfo var_info; | 950 RawLocalVarDescriptors::VarInfo var_info; |
949 var_descriptors_.GetInfo(desc_index, &var_info); | 951 var_descriptors_.GetInfo(desc_index, &var_info); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 } | 999 } |
998 | 1000 |
999 | 1001 |
1000 RawArray* ActivationFrame::GetLocalVariables() { | 1002 RawArray* ActivationFrame::GetLocalVariables() { |
1001 GetDescIndices(); | 1003 GetDescIndices(); |
1002 intptr_t num_variables = desc_indices_.length(); | 1004 intptr_t num_variables = desc_indices_.length(); |
1003 String& var_name = String::Handle(); | 1005 String& var_name = String::Handle(); |
1004 Object& value = Instance::Handle(); | 1006 Object& value = Instance::Handle(); |
1005 const Array& list = Array::Handle(Array::New(2 * num_variables)); | 1007 const Array& list = Array::Handle(Array::New(2 * num_variables)); |
1006 for (intptr_t i = 0; i < num_variables; i++) { | 1008 for (intptr_t i = 0; i < num_variables; i++) { |
1007 intptr_t ignore; | 1009 TokenPosition ignore; |
1008 VariableAt(i, &var_name, &ignore, &ignore, &value); | 1010 VariableAt(i, &var_name, &ignore, &ignore, &value); |
1009 list.SetAt(2 * i, var_name); | 1011 list.SetAt(2 * i, var_name); |
1010 list.SetAt((2 * i) + 1, value); | 1012 list.SetAt((2 * i) + 1, value); |
1011 } | 1013 } |
1012 return list.raw(); | 1014 return list.raw(); |
1013 } | 1015 } |
1014 | 1016 |
1015 | 1017 |
1016 RawObject* ActivationFrame::GetReceiver() { | 1018 RawObject* ActivationFrame::GetReceiver() { |
1017 GetDescIndices(); | 1019 GetDescIndices(); |
1018 intptr_t num_variables = desc_indices_.length(); | 1020 intptr_t num_variables = desc_indices_.length(); |
1019 String& var_name = String::Handle(); | 1021 String& var_name = String::Handle(); |
1020 Instance& value = Instance::Handle(); | 1022 Instance& value = Instance::Handle(); |
1021 for (intptr_t i = 0; i < num_variables; i++) { | 1023 for (intptr_t i = 0; i < num_variables; i++) { |
1022 intptr_t ignore; | 1024 TokenPosition ignore; |
1023 VariableAt(i, &var_name, &ignore, &ignore, &value); | 1025 VariableAt(i, &var_name, &ignore, &ignore, &value); |
1024 if (var_name.Equals(Symbols::This())) { | 1026 if (var_name.Equals(Symbols::This())) { |
1025 return value.raw(); | 1027 return value.raw(); |
1026 } | 1028 } |
1027 } | 1029 } |
1028 return Symbols::OptimizedOut().raw(); | 1030 return Symbols::OptimizedOut().raw(); |
1029 } | 1031 } |
1030 | 1032 |
1031 | 1033 |
1032 bool IsPrivateVariableName(const String& var_name) { | 1034 bool IsPrivateVariableName(const String& var_name) { |
1033 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_'); | 1035 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_'); |
1034 } | 1036 } |
1035 | 1037 |
1036 | 1038 |
1037 RawObject* ActivationFrame::Evaluate(const String& expr) { | 1039 RawObject* ActivationFrame::Evaluate(const String& expr) { |
1038 GetDescIndices(); | 1040 GetDescIndices(); |
1039 const GrowableObjectArray& param_names = | 1041 const GrowableObjectArray& param_names = |
1040 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1042 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
1041 const GrowableObjectArray& param_values = | 1043 const GrowableObjectArray& param_values = |
1042 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1044 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
1043 String& name = String::Handle(); | 1045 String& name = String::Handle(); |
1044 Object& value = Instance::Handle(); | 1046 Object& value = Instance::Handle(); |
1045 intptr_t num_variables = desc_indices_.length(); | 1047 intptr_t num_variables = desc_indices_.length(); |
1046 for (intptr_t i = 0; i < num_variables; i++) { | 1048 for (intptr_t i = 0; i < num_variables; i++) { |
1047 intptr_t ignore; | 1049 TokenPosition ignore; |
1048 VariableAt(i, &name, &ignore, &ignore, &value); | 1050 VariableAt(i, &name, &ignore, &ignore, &value); |
1049 if (!name.Equals(Symbols::This())) { | 1051 if (!name.Equals(Symbols::This())) { |
1050 if (IsPrivateVariableName(name)) { | 1052 if (IsPrivateVariableName(name)) { |
1051 name = String::IdentifierPrettyName(name); | 1053 name = String::IdentifierPrettyName(name); |
1052 } | 1054 } |
1053 param_names.Add(name); | 1055 param_names.Add(name); |
1054 param_values.Add(value); | 1056 param_values.Add(value); |
1055 } | 1057 } |
1056 } | 1058 } |
1057 | 1059 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 // in the world where we pass the script as part of the | 1110 // in the world where we pass the script as part of the |
1109 // location. | 1111 // location. |
1110 jsobj->AddProperty("script", script, !full); | 1112 jsobj->AddProperty("script", script, !full); |
1111 } | 1113 } |
1112 { | 1114 { |
1113 JSONArray jsvars(jsobj, "vars"); | 1115 JSONArray jsvars(jsobj, "vars"); |
1114 const int num_vars = NumLocalVariables(); | 1116 const int num_vars = NumLocalVariables(); |
1115 for (intptr_t v = 0; v < num_vars; v++) { | 1117 for (intptr_t v = 0; v < num_vars; v++) { |
1116 String& var_name = String::Handle(); | 1118 String& var_name = String::Handle(); |
1117 Instance& var_value = Instance::Handle(); | 1119 Instance& var_value = Instance::Handle(); |
1118 intptr_t token_pos; | 1120 TokenPosition token_pos; |
1119 intptr_t end_token_pos; | 1121 TokenPosition end_token_pos; |
1120 VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value); | 1122 VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value); |
1121 if (var_name.raw() != Symbols::AsyncOperation().raw()) { | 1123 if (var_name.raw() != Symbols::AsyncOperation().raw()) { |
1122 JSONObject jsvar(&jsvars); | 1124 JSONObject jsvar(&jsvars); |
1123 jsvar.AddProperty("type", "BoundVariable"); | 1125 jsvar.AddProperty("type", "BoundVariable"); |
1124 var_name = String::IdentifierPrettyName(var_name); | 1126 var_name = String::IdentifierPrettyName(var_name); |
1125 jsvar.AddProperty("name", var_name.ToCString()); | 1127 jsvar.AddProperty("name", var_name.ToCString()); |
1126 jsvar.AddProperty("value", var_value, !full); | 1128 jsvar.AddProperty("value", var_value, !full); |
1127 // TODO(turnidge): Do we really want to provide this on every | 1129 // TODO(turnidge): Do we really want to provide this on every |
1128 // stack dump? Should be associated with the function object, I | 1130 // stack dump? Should be associated with the function object, I |
1129 // think, and not the stack frame. | 1131 // think, and not the stack frame. |
(...skipping 12 matching lines...) Expand all Loading... |
1142 } | 1144 } |
1143 } | 1145 } |
1144 | 1146 |
1145 | 1147 |
1146 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall | 1148 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
1147 | RawPcDescriptors::kUnoptStaticCall | 1149 | RawPcDescriptors::kUnoptStaticCall |
1148 | RawPcDescriptors::kRuntimeCall; | 1150 | RawPcDescriptors::kRuntimeCall; |
1149 | 1151 |
1150 | 1152 |
1151 CodeBreakpoint::CodeBreakpoint(const Code& code, | 1153 CodeBreakpoint::CodeBreakpoint(const Code& code, |
1152 intptr_t token_pos, | 1154 TokenPosition token_pos, |
1153 uword pc, | 1155 uword pc, |
1154 RawPcDescriptors::Kind kind) | 1156 RawPcDescriptors::Kind kind) |
1155 : code_(code.raw()), | 1157 : code_(code.raw()), |
1156 token_pos_(token_pos), | 1158 token_pos_(token_pos), |
1157 pc_(pc), | 1159 pc_(pc), |
1158 line_number_(-1), | 1160 line_number_(-1), |
1159 is_enabled_(false), | 1161 is_enabled_(false), |
1160 bpt_location_(NULL), | 1162 bpt_location_(NULL), |
1161 next_(NULL), | 1163 next_(NULL), |
1162 breakpoint_kind_(kind), | 1164 breakpoint_kind_(kind), |
1163 saved_value_(Code::null()) { | 1165 saved_value_(Code::null()) { |
1164 ASSERT(!code.IsNull()); | 1166 ASSERT(!code.IsNull()); |
1165 ASSERT(token_pos_ > 0); | 1167 ASSERT(token_pos_.IsReal()); |
1166 ASSERT(pc_ != 0); | 1168 ASSERT(pc_ != 0); |
1167 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); | 1169 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); |
1168 } | 1170 } |
1169 | 1171 |
1170 | 1172 |
1171 CodeBreakpoint::~CodeBreakpoint() { | 1173 CodeBreakpoint::~CodeBreakpoint() { |
1172 // Make sure we don't leave patched code behind. | 1174 // Make sure we don't leave patched code behind. |
1173 ASSERT(!IsEnabled()); | 1175 ASSERT(!IsEnabled()); |
1174 // Poison the data so we catch use after free errors. | 1176 // Poison the data so we catch use after free errors. |
1175 #ifdef DEBUG | 1177 #ifdef DEBUG |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 event.set_exception(&exc); | 1648 event.set_exception(&exc); |
1647 ASSERT(stack_trace->Length() > 0); | 1649 ASSERT(stack_trace->Length() > 0); |
1648 event.set_top_frame(stack_trace->FrameAt(0)); | 1650 event.set_top_frame(stack_trace->FrameAt(0)); |
1649 ASSERT(stack_trace_ == NULL); | 1651 ASSERT(stack_trace_ == NULL); |
1650 stack_trace_ = stack_trace; | 1652 stack_trace_ = stack_trace; |
1651 Pause(&event); | 1653 Pause(&event); |
1652 stack_trace_ = NULL; | 1654 stack_trace_ = NULL; |
1653 } | 1655 } |
1654 | 1656 |
1655 | 1657 |
1656 static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { | 1658 static TokenPosition LastTokenOnLine(const TokenStream& tokens, |
1657 TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens); | 1659 TokenPosition pos) { |
| 1660 TokenStream::Iterator iter(tokens, |
| 1661 pos, |
| 1662 TokenStream::Iterator::kAllTokens); |
1658 ASSERT(iter.IsValid()); | 1663 ASSERT(iter.IsValid()); |
1659 intptr_t last_pos = pos; | 1664 TokenPosition last_pos = pos; |
1660 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && | 1665 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && |
1661 (iter.CurrentTokenKind() != Token::kEOS)) { | 1666 (iter.CurrentTokenKind() != Token::kEOS)) { |
1662 last_pos = iter.CurrentPosition(); | 1667 last_pos = iter.CurrentPosition(); |
1663 iter.Advance(); | 1668 iter.Advance(); |
1664 } | 1669 } |
1665 return last_pos; | 1670 return last_pos; |
1666 } | 1671 } |
1667 | 1672 |
1668 | 1673 |
1669 // Returns the best fit token position for a breakpoint. | 1674 // Returns the best fit token position for a breakpoint. |
1670 // | 1675 // |
1671 // Takes a range of tokens [requested_token_pos, last_token_pos] and | 1676 // Takes a range of tokens [requested_token_pos, last_token_pos] and |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1715 // | 1720 // |
1716 // If no best fit token can be found, the search is expanded, | 1721 // If no best fit token can be found, the search is expanded, |
1717 // searching through the rest of the current function by calling this | 1722 // searching through the rest of the current function by calling this |
1718 // function recursively. | 1723 // function recursively. |
1719 // | 1724 // |
1720 // TODO(turnidge): Given that we usually call this function with a | 1725 // TODO(turnidge): Given that we usually call this function with a |
1721 // token range restricted to a single line, this could be a one-pass | 1726 // token range restricted to a single line, this could be a one-pass |
1722 // algorithm, which would be simpler. I believe that it only needs | 1727 // algorithm, which would be simpler. I believe that it only needs |
1723 // two passes to support the recursive try-the-whole-function case. | 1728 // two passes to support the recursive try-the-whole-function case. |
1724 // Rewrite this later, once there are more tests in place. | 1729 // Rewrite this later, once there are more tests in place. |
1725 intptr_t Debugger::ResolveBreakpointPos(const Function& func, | 1730 TokenPosition Debugger::ResolveBreakpointPos( |
1726 intptr_t requested_token_pos, | 1731 const Function& func, |
1727 intptr_t last_token_pos, | 1732 TokenPosition requested_token_pos, |
1728 intptr_t requested_column) { | 1733 TokenPosition last_token_pos, |
| 1734 intptr_t requested_column) { |
1729 ASSERT(func.HasCode()); | 1735 ASSERT(func.HasCode()); |
1730 ASSERT(!func.HasOptimizedCode()); | 1736 ASSERT(!func.HasOptimizedCode()); |
1731 | 1737 |
1732 if (requested_token_pos < func.token_pos()) { | 1738 if (requested_token_pos < func.token_pos()) { |
1733 requested_token_pos = func.token_pos(); | 1739 requested_token_pos = func.token_pos(); |
1734 } | 1740 } |
1735 if (last_token_pos > func.end_token_pos()) { | 1741 if (last_token_pos > func.end_token_pos()) { |
1736 last_token_pos = func.end_token_pos(); | 1742 last_token_pos = func.end_token_pos(); |
1737 } | 1743 } |
1738 | 1744 |
1739 Script& script = Script::Handle(func.script()); | 1745 Script& script = Script::Handle(func.script()); |
1740 Code& code = Code::Handle(func.unoptimized_code()); | 1746 Code& code = Code::Handle(func.unoptimized_code()); |
1741 ASSERT(!code.IsNull()); | 1747 ASSERT(!code.IsNull()); |
1742 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1748 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1743 | 1749 |
1744 // First pass: find the safe point which is closest to the beginning | 1750 // First pass: find the safe point which is closest to the beginning |
1745 // of the given token range. | 1751 // of the given token range. |
1746 intptr_t best_fit_pos = INT_MAX; | 1752 TokenPosition best_fit_pos = TokenPosition::kMaxSource; |
1747 intptr_t best_column = INT_MAX; | 1753 intptr_t best_column = INT_MAX; |
1748 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1754 PcDescriptors::Iterator iter(desc, kSafepointKind); |
1749 while (iter.MoveNext()) { | 1755 while (iter.MoveNext()) { |
1750 const intptr_t pos = iter.TokenPos(); | 1756 const TokenPosition pos = iter.TokenPos(); |
1751 if ((!Token::IsReal(pos)) || | 1757 if ((!pos.IsReal()) || |
1752 (pos < requested_token_pos) || | 1758 (pos < requested_token_pos) || |
1753 (pos > last_token_pos)) { | 1759 (pos > last_token_pos)) { |
1754 // Token is not in the target range. | 1760 // Token is not in the target range. |
1755 continue; | 1761 continue; |
1756 } | 1762 } |
1757 | 1763 |
1758 intptr_t token_start_column = -1; | 1764 intptr_t token_start_column = -1; |
1759 if (requested_column >= 0) { | 1765 if (requested_column >= 0) { |
1760 intptr_t ignored = -1; | 1766 intptr_t ignored = -1; |
1761 intptr_t token_len = -1; | 1767 intptr_t token_len = -1; |
(...skipping 16 matching lines...) Expand all Loading... |
1778 // Prefer the lowest (first) token pos. | 1784 // Prefer the lowest (first) token pos. |
1779 if (pos < best_fit_pos) { | 1785 if (pos < best_fit_pos) { |
1780 best_fit_pos = pos; | 1786 best_fit_pos = pos; |
1781 best_column = token_start_column; | 1787 best_column = token_start_column; |
1782 } | 1788 } |
1783 } | 1789 } |
1784 | 1790 |
1785 // Second pass (if we found a safe point in the first pass). Find | 1791 // Second pass (if we found a safe point in the first pass). Find |
1786 // the token on the line which is at the best fit column (if column | 1792 // the token on the line which is at the best fit column (if column |
1787 // was specified) and has the lowest code address. | 1793 // was specified) and has the lowest code address. |
1788 if (best_fit_pos != INT_MAX) { | 1794 if (best_fit_pos != TokenPosition::kMaxSource) { |
1789 const Script& script = Script::Handle(func.script()); | 1795 const Script& script = Script::Handle(func.script()); |
1790 const TokenStream& tokens = TokenStream::Handle(script.tokens()); | 1796 const TokenStream& tokens = TokenStream::Handle(script.tokens()); |
1791 const intptr_t begin_pos = best_fit_pos; | 1797 const TokenPosition begin_pos = best_fit_pos; |
1792 const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos); | 1798 const TokenPosition end_of_line_pos = LastTokenOnLine(tokens, begin_pos); |
1793 uword lowest_pc_offset = kUwordMax; | 1799 uword lowest_pc_offset = kUwordMax; |
1794 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1800 PcDescriptors::Iterator iter(desc, kSafepointKind); |
1795 while (iter.MoveNext()) { | 1801 while (iter.MoveNext()) { |
1796 const intptr_t pos = iter.TokenPos(); | 1802 const TokenPosition pos = iter.TokenPos(); |
1797 if ((!Token::IsReal(pos)) || | 1803 if (!pos.IsReal() || |
1798 (pos < begin_pos) || | 1804 (pos < begin_pos) || |
1799 (pos > end_of_line_pos)) { | 1805 (pos > end_of_line_pos)) { |
1800 // Token is not on same line as best fit. | 1806 // Token is not on same line as best fit. |
1801 continue; | 1807 continue; |
1802 } | 1808 } |
1803 | 1809 |
1804 if (requested_column >= 0) { | 1810 if (requested_column >= 0) { |
1805 intptr_t ignored = -1; | 1811 intptr_t ignored = -1; |
1806 intptr_t token_start_column = -1; | 1812 intptr_t token_start_column = -1; |
1807 // We look for other tokens at the best column in case there | 1813 // We look for other tokens at the best column in case there |
(...skipping 14 matching lines...) Expand all Loading... |
1822 } | 1828 } |
1823 | 1829 |
1824 // We didn't find a safe point in the given token range. Try and | 1830 // We didn't find a safe point in the given token range. Try and |
1825 // find a safe point in the remaining source code of the function. | 1831 // find a safe point in the remaining source code of the function. |
1826 // Since we have moved to the next line of the function, we no | 1832 // Since we have moved to the next line of the function, we no |
1827 // longer are requesting a specific column number. | 1833 // longer are requesting a specific column number. |
1828 if (last_token_pos < func.end_token_pos()) { | 1834 if (last_token_pos < func.end_token_pos()) { |
1829 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), | 1835 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), |
1830 -1 /* no column */); | 1836 -1 /* no column */); |
1831 } | 1837 } |
1832 return Token::kNoSourcePos; | 1838 return TokenPosition::kNoSource; |
1833 } | 1839 } |
1834 | 1840 |
1835 | 1841 |
1836 void Debugger::MakeCodeBreakpointAt(const Function& func, | 1842 void Debugger::MakeCodeBreakpointAt(const Function& func, |
1837 BreakpointLocation* loc) { | 1843 BreakpointLocation* loc) { |
1838 ASSERT(Token::IsReal(loc->token_pos_)); | 1844 ASSERT(loc->token_pos_.IsReal()); |
1839 ASSERT((loc != NULL) && loc->IsResolved()); | 1845 ASSERT((loc != NULL) && loc->IsResolved()); |
1840 ASSERT(!func.HasOptimizedCode()); | 1846 ASSERT(!func.HasOptimizedCode()); |
1841 Code& code = Code::Handle(func.unoptimized_code()); | 1847 Code& code = Code::Handle(func.unoptimized_code()); |
1842 ASSERT(!code.IsNull()); | 1848 ASSERT(!code.IsNull()); |
1843 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1849 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
1844 uword lowest_pc_offset = kUwordMax; | 1850 uword lowest_pc_offset = kUwordMax; |
1845 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; | 1851 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; |
1846 // Find the safe point with the lowest compiled code address | 1852 // Find the safe point with the lowest compiled code address |
1847 // that maps to the token position of the source breakpoint. | 1853 // that maps to the token position of the source breakpoint. |
1848 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1854 PcDescriptors::Iterator iter(desc, kSafepointKind); |
(...skipping 17 matching lines...) Expand all Loading... |
1866 RegisterCodeBreakpoint(code_bpt); | 1872 RegisterCodeBreakpoint(code_bpt); |
1867 } | 1873 } |
1868 code_bpt->set_bpt_location(loc); | 1874 code_bpt->set_bpt_location(loc); |
1869 if (loc->AnyEnabled()) { | 1875 if (loc->AnyEnabled()) { |
1870 code_bpt->Enable(); | 1876 code_bpt->Enable(); |
1871 } | 1877 } |
1872 } | 1878 } |
1873 | 1879 |
1874 | 1880 |
1875 void Debugger::FindCompiledFunctions(const Script& script, | 1881 void Debugger::FindCompiledFunctions(const Script& script, |
1876 intptr_t start_pos, | 1882 TokenPosition start_pos, |
1877 intptr_t end_pos, | 1883 TokenPosition end_pos, |
1878 GrowableObjectArray* function_list) { | 1884 GrowableObjectArray* function_list) { |
1879 Zone* zone = Thread::Current()->zone(); | 1885 Zone* zone = Thread::Current()->zone(); |
1880 Class& cls = Class::Handle(zone); | 1886 Class& cls = Class::Handle(zone); |
1881 Array& functions = Array::Handle(zone); | 1887 Array& functions = Array::Handle(zone); |
1882 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1888 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
1883 Function& function = Function::Handle(zone); | 1889 Function& function = Function::Handle(zone); |
1884 | 1890 |
1885 closures = isolate_->object_store()->closure_functions(); | 1891 closures = isolate_->object_store()->closure_functions(); |
1886 const intptr_t num_closures = closures.Length(); | 1892 const intptr_t num_closures = closures.Length(); |
1887 for (intptr_t pos = 0; pos < num_closures; pos++) { | 1893 for (intptr_t pos = 0; pos < num_closures; pos++) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1951 } else { | 1957 } else { |
1952 if ((func->token_pos() > best_fit->token_pos()) && | 1958 if ((func->token_pos() > best_fit->token_pos()) && |
1953 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1959 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
1954 *best_fit = func->raw(); | 1960 *best_fit = func->raw(); |
1955 } | 1961 } |
1956 } | 1962 } |
1957 } | 1963 } |
1958 | 1964 |
1959 | 1965 |
1960 RawFunction* Debugger::FindBestFit(const Script& script, | 1966 RawFunction* Debugger::FindBestFit(const Script& script, |
1961 intptr_t token_pos) { | 1967 TokenPosition token_pos) { |
1962 Zone* zone = Thread::Current()->zone(); | 1968 Zone* zone = Thread::Current()->zone(); |
1963 Class& cls = Class::Handle(zone); | 1969 Class& cls = Class::Handle(zone); |
1964 Array& functions = Array::Handle(zone); | 1970 Array& functions = Array::Handle(zone); |
1965 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1971 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
1966 Function& function = Function::Handle(zone); | 1972 Function& function = Function::Handle(zone); |
1967 Function& best_fit = Function::Handle(zone); | 1973 Function& best_fit = Function::Handle(zone); |
1968 Error& error = Error::Handle(zone); | 1974 Error& error = Error::Handle(zone); |
1969 | 1975 |
1970 closures = isolate_->object_store()->closure_functions(); | 1976 closures = isolate_->object_store()->closure_functions(); |
1971 const intptr_t num_closures = closures.Length(); | 1977 const intptr_t num_closures = closures.Length(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2010 } | 2016 } |
2011 } | 2017 } |
2012 } | 2018 } |
2013 } | 2019 } |
2014 } | 2020 } |
2015 return best_fit.raw(); | 2021 return best_fit.raw(); |
2016 } | 2022 } |
2017 | 2023 |
2018 | 2024 |
2019 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2025 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
2020 intptr_t token_pos, | 2026 TokenPosition token_pos, |
2021 intptr_t last_token_pos, | 2027 TokenPosition last_token_pos, |
2022 intptr_t requested_line, | 2028 intptr_t requested_line, |
2023 intptr_t requested_column) { | 2029 intptr_t requested_column) { |
2024 Function& func = Function::Handle(); | 2030 Function& func = Function::Handle(); |
2025 func = FindBestFit(script, token_pos); | 2031 func = FindBestFit(script, token_pos); |
2026 if (func.IsNull()) { | 2032 if (func.IsNull()) { |
2027 return NULL; | 2033 return NULL; |
2028 } | 2034 } |
2029 // There may be more than one function object for a given function | 2035 // There may be more than one function object for a given function |
2030 // in source code. There may be implicit closure functions, and | 2036 // in source code. There may be implicit closure functions, and |
2031 // there may be copies of mixin functions. Collect all compiled | 2037 // there may be copies of mixin functions. Collect all compiled |
2032 // functions whose source code range matches exactly the best fit | 2038 // functions whose source code range matches exactly the best fit |
2033 // function we found. | 2039 // function we found. |
2034 GrowableObjectArray& functions = | 2040 GrowableObjectArray& functions = |
2035 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2041 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
2036 FindCompiledFunctions(script, | 2042 FindCompiledFunctions(script, |
2037 func.token_pos(), | 2043 func.token_pos(), |
2038 func.end_token_pos(), | 2044 func.end_token_pos(), |
2039 &functions); | 2045 &functions); |
2040 | 2046 |
2041 if (functions.Length() > 0) { | 2047 if (functions.Length() > 0) { |
2042 // One or more function object containing this breakpoint location | 2048 // One or more function object containing this breakpoint location |
2043 // have already been compiled. We can resolve the breakpoint now. | 2049 // have already been compiled. We can resolve the breakpoint now. |
2044 DeoptimizeWorld(); | 2050 DeoptimizeWorld(); |
2045 func ^= functions.At(0); | 2051 func ^= functions.At(0); |
2046 intptr_t breakpoint_pos = | 2052 TokenPosition breakpoint_pos = |
2047 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); | 2053 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); |
2048 if (breakpoint_pos >= 0) { | 2054 if (breakpoint_pos.IsReal()) { |
2049 BreakpointLocation* bpt = | 2055 BreakpointLocation* bpt = |
2050 GetBreakpointLocation(script, breakpoint_pos, requested_column); | 2056 GetBreakpointLocation(script, breakpoint_pos, requested_column); |
2051 if (bpt != NULL) { | 2057 if (bpt != NULL) { |
2052 // A source breakpoint for this location already exists. | 2058 // A source breakpoint for this location already exists. |
2053 return bpt; | 2059 return bpt; |
2054 } | 2060 } |
2055 bpt = new BreakpointLocation(script, token_pos, last_token_pos, | 2061 bpt = new BreakpointLocation(script, token_pos, last_token_pos, |
2056 requested_line, requested_column); | 2062 requested_line, requested_column); |
2057 bpt->SetResolved(func, breakpoint_pos); | 2063 bpt->SetResolved(func, breakpoint_pos); |
2058 RegisterBreakpointLocation(bpt); | 2064 RegisterBreakpointLocation(bpt); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 } | 2247 } |
2242 return latent_bpt; | 2248 return latent_bpt; |
2243 } | 2249 } |
2244 if (scripts.Length() > 1) { | 2250 if (scripts.Length() > 1) { |
2245 if (FLAG_verbose_debug) { | 2251 if (FLAG_verbose_debug) { |
2246 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); | 2252 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); |
2247 } | 2253 } |
2248 return NULL; | 2254 return NULL; |
2249 } | 2255 } |
2250 script ^= scripts.At(0); | 2256 script ^= scripts.At(0); |
2251 intptr_t first_token_idx, last_token_idx; | 2257 TokenPosition first_token_idx, last_token_idx; |
2252 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); | 2258 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); |
2253 if (!Token::IsReal(first_token_idx)) { | 2259 if (!first_token_idx.IsReal()) { |
2254 // Script does not contain the given line number. | 2260 // Script does not contain the given line number. |
2255 if (FLAG_verbose_debug) { | 2261 if (FLAG_verbose_debug) { |
2256 OS::Print("Script '%s' does not contain line number %" Pd "\n", | 2262 OS::Print("Script '%s' does not contain line number %" Pd "\n", |
2257 script_url.ToCString(), line_number); | 2263 script_url.ToCString(), line_number); |
2258 } | 2264 } |
2259 return NULL; | 2265 return NULL; |
2260 } else if (!Token::IsReal(last_token_idx)) { | 2266 } else if (!last_token_idx.IsReal()) { |
2261 // Line does not contain any tokens. | 2267 // Line does not contain any tokens. |
2262 if (FLAG_verbose_debug) { | 2268 if (FLAG_verbose_debug) { |
2263 OS::Print("No executable code at line %" Pd " in '%s'\n", | 2269 OS::Print("No executable code at line %" Pd " in '%s'\n", |
2264 line_number, script_url.ToCString()); | 2270 line_number, script_url.ToCString()); |
2265 } | 2271 } |
2266 return NULL; | 2272 return NULL; |
2267 } | 2273 } |
2268 | 2274 |
2269 BreakpointLocation* bpt = NULL; | 2275 BreakpointLocation* bpt = NULL; |
2270 ASSERT(first_token_idx <= last_token_idx); | 2276 ASSERT(first_token_idx <= last_token_idx); |
2271 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { | 2277 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { |
2272 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, | 2278 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, |
2273 line_number, column_number); | 2279 line_number, column_number); |
2274 first_token_idx++; | 2280 first_token_idx.Next(); |
2275 } | 2281 } |
2276 if ((bpt == NULL) && FLAG_verbose_debug) { | 2282 if ((bpt == NULL) && FLAG_verbose_debug) { |
2277 OS::Print("No executable code at line %" Pd " in '%s'\n", | 2283 OS::Print("No executable code at line %" Pd " in '%s'\n", |
2278 line_number, script_url.ToCString()); | 2284 line_number, script_url.ToCString()); |
2279 } | 2285 } |
2280 return bpt; | 2286 return bpt; |
2281 } | 2287 } |
2282 | 2288 |
2283 | 2289 |
2284 intptr_t Debugger::CacheObject(const Object& obj) { | 2290 intptr_t Debugger::CacheObject(const Object& obj) { |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2658 // We returned from the "interesting frame", there can be no more | 2664 // We returned from the "interesting frame", there can be no more |
2659 // stepping breaks for it. Pause at the next appropriate location | 2665 // stepping breaks for it. Pause at the next appropriate location |
2660 // and let the user set the "interesting" frame again. | 2666 // and let the user set the "interesting" frame again. |
2661 stepping_fp_ = 0; | 2667 stepping_fp_ = 0; |
2662 } | 2668 } |
2663 } | 2669 } |
2664 | 2670 |
2665 if (!frame->IsDebuggable()) { | 2671 if (!frame->IsDebuggable()) { |
2666 return Error::null(); | 2672 return Error::null(); |
2667 } | 2673 } |
2668 if (!Token::IsDebugPause(frame->TokenPos())) { | 2674 if (!frame->TokenPos().IsDebugPause()) { |
2669 return Error::null(); | 2675 return Error::null(); |
2670 } | 2676 } |
2671 | 2677 |
2672 // If there is an active breakpoint at this pc, then we should have | 2678 // If there is an active breakpoint at this pc, then we should have |
2673 // already bailed out of this function in the skip_next_step_ test | 2679 // already bailed out of this function in the skip_next_step_ test |
2674 // above. | 2680 // above. |
2675 ASSERT(!HasActiveBreakpoint(frame->pc())); | 2681 ASSERT(!HasActiveBreakpoint(frame->pc())); |
2676 | 2682 |
2677 if (FLAG_verbose_debug) { | 2683 if (FLAG_verbose_debug) { |
2678 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", | 2684 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", |
2679 String::Handle(frame->SourceUrl()).ToCString(), | 2685 String::Handle(frame->SourceUrl()).ToCString(), |
2680 frame->LineNumber(), | 2686 frame->LineNumber(), |
2681 String::Handle(frame->QualifiedFunctionName()).ToCString(), | 2687 String::Handle(frame->QualifiedFunctionName()).ToCString(), |
2682 frame->TokenPos()); | 2688 frame->TokenPos().ToCString()); |
2683 } | 2689 } |
2684 | 2690 |
2685 ASSERT(stack_trace_ == NULL); | 2691 ASSERT(stack_trace_ == NULL); |
2686 stack_trace_ = CollectStackTrace(); | 2692 stack_trace_ = CollectStackTrace(); |
2687 SignalPausedEvent(frame, NULL); | 2693 SignalPausedEvent(frame, NULL); |
2688 HandleSteppingRequest(stack_trace_); | 2694 HandleSteppingRequest(stack_trace_); |
2689 stack_trace_ = NULL; | 2695 stack_trace_ = NULL; |
2690 | 2696 |
2691 // If any error occurred while in the debug message loop, return it here. | 2697 // If any error occurred while in the debug message loop, return it here. |
2692 const Error& error = | 2698 const Error& error = |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2753 } | 2759 } |
2754 } | 2760 } |
2755 } | 2761 } |
2756 | 2762 |
2757 if (bpt_hit == NULL) { | 2763 if (bpt_hit == NULL) { |
2758 return Error::null(); | 2764 return Error::null(); |
2759 } | 2765 } |
2760 | 2766 |
2761 if (FLAG_verbose_debug) { | 2767 if (FLAG_verbose_debug) { |
2762 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " | 2768 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " |
2763 "(token %" Pd ") (address %#" Px ")\n", | 2769 "(token %s) (address %#" Px ")\n", |
2764 cbpt->IsInternal() ? "internal" : "user", | 2770 cbpt->IsInternal() ? "internal" : "user", |
2765 String::Handle(cbpt->SourceUrl()).ToCString(), | 2771 String::Handle(cbpt->SourceUrl()).ToCString(), |
2766 cbpt->LineNumber(), | 2772 cbpt->LineNumber(), |
2767 cbpt->token_pos(), | 2773 cbpt->token_pos().ToCString(), |
2768 top_frame->pc()); | 2774 top_frame->pc()); |
2769 } | 2775 } |
2770 | 2776 |
2771 ASSERT(stack_trace_ == NULL); | 2777 ASSERT(stack_trace_ == NULL); |
2772 stack_trace_ = stack_trace; | 2778 stack_trace_ = stack_trace; |
2773 SignalPausedEvent(top_frame, bpt_hit); | 2779 SignalPausedEvent(top_frame, bpt_hit); |
2774 // When we single step from a user breakpoint, our next stepping | 2780 // When we single step from a user breakpoint, our next stepping |
2775 // point will be at the exact same pc. Skip it. | 2781 // point will be at the exact same pc. Skip it. |
2776 HandleSteppingRequest(stack_trace_, true /* skip next step */); | 2782 HandleSteppingRequest(stack_trace_, true /* skip next step */); |
2777 stack_trace_ = NULL; | 2783 stack_trace_ = NULL; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { | 2842 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { |
2837 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2843 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
2838 creation_message_sent_ = true; | 2844 creation_message_sent_ = true; |
2839 } | 2845 } |
2840 } | 2846 } |
2841 | 2847 |
2842 | 2848 |
2843 // Return innermost closure contained in 'function' that contains | 2849 // Return innermost closure contained in 'function' that contains |
2844 // the given token position. | 2850 // the given token position. |
2845 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2851 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
2846 intptr_t token_pos) { | 2852 TokenPosition token_pos) { |
2847 Zone* zone = Thread::Current()->zone(); | 2853 Zone* zone = Thread::Current()->zone(); |
2848 const Script& outer_origin = Script::Handle(zone, function.script()); | 2854 const Script& outer_origin = Script::Handle(zone, function.script()); |
2849 const GrowableObjectArray& closures = | 2855 const GrowableObjectArray& closures = |
2850 GrowableObjectArray::Handle(zone, | 2856 GrowableObjectArray::Handle(zone, |
2851 Isolate::Current()->object_store()->closure_functions()); | 2857 Isolate::Current()->object_store()->closure_functions()); |
2852 const intptr_t num_closures = closures.Length(); | 2858 const intptr_t num_closures = closures.Length(); |
2853 Function& closure = Function::Handle(zone); | 2859 Function& closure = Function::Handle(zone); |
2854 Function& best_fit = Function::Handle(zone); | 2860 Function& best_fit = Function::Handle(zone); |
2855 for (intptr_t i = 0; i < num_closures; i++) { | 2861 for (intptr_t i = 0; i < num_closures; i++) { |
2856 closure ^= closures.At(i); | 2862 closure ^= closures.At(i); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2901 | 2907 |
2902 // TODO(hausner): What should we do if function is optimized? | 2908 // TODO(hausner): What should we do if function is optimized? |
2903 // Can we deoptimize the function? | 2909 // Can we deoptimize the function? |
2904 ASSERT(!func.HasOptimizedCode()); | 2910 ASSERT(!func.HasOptimizedCode()); |
2905 | 2911 |
2906 // There is no local function within func that contains the | 2912 // There is no local function within func that contains the |
2907 // breakpoint token position. Resolve the breakpoint if necessary | 2913 // breakpoint token position. Resolve the breakpoint if necessary |
2908 // and set the code breakpoints. | 2914 // and set the code breakpoints. |
2909 if (!loc->IsResolved()) { | 2915 if (!loc->IsResolved()) { |
2910 // Resolve source breakpoint in the newly compiled function. | 2916 // Resolve source breakpoint in the newly compiled function. |
2911 intptr_t bp_pos = | 2917 TokenPosition bp_pos = |
2912 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), | 2918 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), |
2913 loc->requested_column_number()); | 2919 loc->requested_column_number()); |
2914 if (!Token::IsDebugPause(bp_pos)) { | 2920 if (!bp_pos.IsDebugPause()) { |
2915 if (FLAG_verbose_debug) { | 2921 if (FLAG_verbose_debug) { |
2916 OS::Print("Failed resolving breakpoint for function '%s'\n", | 2922 OS::Print("Failed resolving breakpoint for function '%s'\n", |
2917 String::Handle(func.name()).ToCString()); | 2923 String::Handle(func.name()).ToCString()); |
2918 } | 2924 } |
2919 continue; | 2925 continue; |
2920 } | 2926 } |
2921 intptr_t requested_pos = loc->token_pos(); | 2927 TokenPosition requested_pos = loc->token_pos(); |
2922 intptr_t requested_end_pos = loc->end_token_pos(); | 2928 TokenPosition requested_end_pos = loc->end_token_pos(); |
2923 loc->SetResolved(func, bp_pos); | 2929 loc->SetResolved(func, bp_pos); |
2924 Breakpoint* bpt = loc->breakpoints(); | 2930 Breakpoint* bpt = loc->breakpoints(); |
2925 while (bpt != NULL) { | 2931 while (bpt != NULL) { |
2926 if (FLAG_verbose_debug) { | 2932 if (FLAG_verbose_debug) { |
2927 OS::Print("Resolved BP %" Pd " to pos %" Pd ", " | 2933 OS::Print("Resolved BP %" Pd " to pos %s, " |
2928 "line %" Pd " col %" Pd ", " | 2934 "line %" Pd " col %" Pd ", " |
2929 "function '%s' (requested range %" Pd "-%" Pd ", " | 2935 "function '%s' (requested range %s-%s, " |
2930 "requested col %" Pd ")\n", | 2936 "requested col %" Pd ")\n", |
2931 bpt->id(), | 2937 bpt->id(), |
2932 loc->token_pos(), | 2938 loc->token_pos().ToCString(), |
2933 loc->LineNumber(), | 2939 loc->LineNumber(), |
2934 loc->ColumnNumber(), | 2940 loc->ColumnNumber(), |
2935 func.ToFullyQualifiedCString(), | 2941 func.ToFullyQualifiedCString(), |
2936 requested_pos, | 2942 requested_pos.ToCString(), |
2937 requested_end_pos, | 2943 requested_end_pos.ToCString(), |
2938 loc->requested_column_number()); | 2944 loc->requested_column_number()); |
2939 } | 2945 } |
2940 SignalBpResolved(bpt); | 2946 SignalBpResolved(bpt); |
2941 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); | 2947 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); |
2942 bpt = bpt->next(); | 2948 bpt = bpt->next(); |
2943 } | 2949 } |
2944 } | 2950 } |
2945 ASSERT(loc->IsResolved()); | 2951 ASSERT(loc->IsResolved()); |
2946 if (FLAG_verbose_debug) { | 2952 if (FLAG_verbose_debug) { |
2947 Breakpoint* bpt = loc->breakpoints(); | 2953 Breakpoint* bpt = loc->breakpoints(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 if (prev_loc == NULL) { | 2996 if (prev_loc == NULL) { |
2991 latent_locations_ = loc; | 2997 latent_locations_ = loc; |
2992 } else { | 2998 } else { |
2993 prev_loc->set_next(loc); | 2999 prev_loc->set_next(loc); |
2994 } | 3000 } |
2995 // Now find the token range at the requested line and make a | 3001 // Now find the token range at the requested line and make a |
2996 // new unresolved source breakpoint. | 3002 // new unresolved source breakpoint. |
2997 intptr_t line_number = matched_loc->requested_line_number(); | 3003 intptr_t line_number = matched_loc->requested_line_number(); |
2998 intptr_t column_number = matched_loc->requested_column_number(); | 3004 intptr_t column_number = matched_loc->requested_column_number(); |
2999 ASSERT(line_number >= 0); | 3005 ASSERT(line_number >= 0); |
3000 intptr_t first_token_pos, last_token_pos; | 3006 TokenPosition first_token_pos, last_token_pos; |
3001 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); | 3007 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); |
3002 if (!Token::IsDebugPause(first_token_pos) || | 3008 if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) { |
3003 !Token::IsDebugPause(last_token_pos)) { | |
3004 // Script does not contain the given line number or there are no | 3009 // Script does not contain the given line number or there are no |
3005 // tokens on the line. Drop the breakpoint silently. | 3010 // tokens on the line. Drop the breakpoint silently. |
3006 Breakpoint* bpt = matched_loc->breakpoints(); | 3011 Breakpoint* bpt = matched_loc->breakpoints(); |
3007 while (bpt != NULL) { | 3012 while (bpt != NULL) { |
3008 if (FLAG_verbose_debug) { | 3013 if (FLAG_verbose_debug) { |
3009 OS::Print("No code found at line %" Pd ": " | 3014 OS::Print("No code found at line %" Pd ": " |
3010 "dropping latent breakpoint %" Pd " in '%s'\n", | 3015 "dropping latent breakpoint %" Pd " in '%s'\n", |
3011 line_number, | 3016 line_number, |
3012 bpt->id(), | 3017 bpt->id(), |
3013 url.ToCString()); | 3018 url.ToCString()); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3201 delete temp_bpt; | 3206 delete temp_bpt; |
3202 } else { | 3207 } else { |
3203 prev_bpt = curr_bpt; | 3208 prev_bpt = curr_bpt; |
3204 curr_bpt = curr_bpt->next(); | 3209 curr_bpt = curr_bpt->next(); |
3205 } | 3210 } |
3206 } | 3211 } |
3207 } | 3212 } |
3208 | 3213 |
3209 | 3214 |
3210 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, | 3215 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, |
3211 intptr_t token_pos, | 3216 TokenPosition token_pos, |
3212 intptr_t requested_column) { | 3217 intptr_t requested_column) { |
3213 BreakpointLocation* bpt = breakpoint_locations_; | 3218 BreakpointLocation* bpt = breakpoint_locations_; |
3214 while (bpt != NULL) { | 3219 while (bpt != NULL) { |
3215 if ((bpt->script_ == script.raw()) && | 3220 if ((bpt->script_ == script.raw()) && |
3216 (bpt->token_pos_ == token_pos) && | 3221 (bpt->token_pos_ == token_pos) && |
3217 (bpt->requested_column_number_ == requested_column)) { | 3222 (bpt->requested_column_number_ == requested_column)) { |
3218 return bpt; | 3223 return bpt; |
3219 } | 3224 } |
3220 bpt = bpt->next(); | 3225 bpt = bpt->next(); |
3221 } | 3226 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3268 } | 3273 } |
3269 | 3274 |
3270 | 3275 |
3271 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3276 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
3272 ASSERT(bpt->next() == NULL); | 3277 ASSERT(bpt->next() == NULL); |
3273 bpt->set_next(code_breakpoints_); | 3278 bpt->set_next(code_breakpoints_); |
3274 code_breakpoints_ = bpt; | 3279 code_breakpoints_ = bpt; |
3275 } | 3280 } |
3276 | 3281 |
3277 } // namespace dart | 3282 } // namespace dart |
OLD | NEW |