| 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_descriptor.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 20 matching lines...) Expand all Loading... |
| 60 | 61 |
| 61 private: | 62 private: |
| 62 GrowableObjectArray* objs_; | 63 GrowableObjectArray* objs_; |
| 63 | 64 |
| 64 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); | 65 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); |
| 65 }; | 66 }; |
| 66 | 67 |
| 67 | 68 |
| 68 // Create an unresolved breakpoint in given token range and script. | 69 // Create an unresolved breakpoint in given token range and script. |
| 69 BreakpointLocation::BreakpointLocation(const Script& script, | 70 BreakpointLocation::BreakpointLocation(const Script& script, |
| 70 intptr_t token_pos, | 71 TokenDescriptor token_pos, |
| 71 intptr_t end_token_pos, | 72 TokenDescriptor end_token_pos, |
| 72 intptr_t requested_line_number, | 73 intptr_t requested_line_number, |
| 73 intptr_t requested_column_number) | 74 intptr_t requested_column_number) |
| 74 : script_(script.raw()), | 75 : script_(script.raw()), |
| 75 url_(script.url()), | 76 url_(script.url()), |
| 76 token_pos_(token_pos), | 77 token_pos_(token_pos), |
| 77 end_token_pos_(end_token_pos), | 78 end_token_pos_(end_token_pos), |
| 78 is_resolved_(false), | 79 is_resolved_(false), |
| 79 next_(NULL), | 80 next_(NULL), |
| 80 conditions_(NULL), | 81 conditions_(NULL), |
| 81 requested_line_number_(requested_line_number), | 82 requested_line_number_(requested_line_number), |
| 82 requested_column_number_(requested_column_number), | 83 requested_column_number_(requested_column_number), |
| 83 function_(Function::null()), | 84 function_(Function::null()), |
| 84 line_number_(-1), | 85 line_number_(-1), |
| 85 column_number_(-1) { | 86 column_number_(-1) { |
| 86 ASSERT(!script.IsNull()); | 87 ASSERT(!script.IsNull()); |
| 87 ASSERT(Token::IsReal(token_pos_)); | 88 ASSERT(TokenDescriptor(token_pos_).IsReal()); |
| 88 } | 89 } |
| 89 | 90 |
| 90 // Create a latent breakpoint at given url and line number. | 91 // Create a latent breakpoint at given url and line number. |
| 91 BreakpointLocation::BreakpointLocation(const String& url, | 92 BreakpointLocation::BreakpointLocation(const String& url, |
| 92 intptr_t requested_line_number, | 93 intptr_t requested_line_number, |
| 93 intptr_t requested_column_number) | 94 intptr_t requested_column_number) |
| 94 : script_(Script::null()), | 95 : script_(Script::null()), |
| 95 url_(url.raw()), | 96 url_(url.raw()), |
| 96 token_pos_(Token::kNoSourcePos), | 97 token_pos_(TokenDescriptor::kNoSource), |
| 97 end_token_pos_(Token::kNoSourcePos), | 98 end_token_pos_(TokenDescriptor::kNoSource), |
| 98 is_resolved_(false), | 99 is_resolved_(false), |
| 99 next_(NULL), | 100 next_(NULL), |
| 100 conditions_(NULL), | 101 conditions_(NULL), |
| 101 requested_line_number_(requested_line_number), | 102 requested_line_number_(requested_line_number), |
| 102 requested_column_number_(requested_column_number), | 103 requested_column_number_(requested_column_number), |
| 103 function_(Function::null()), | 104 function_(Function::null()), |
| 104 line_number_(-1), | 105 line_number_(-1), |
| 105 column_number_(-1) { | 106 column_number_(-1) { |
| 106 ASSERT(requested_line_number_ >= 0); | 107 ASSERT(requested_line_number_ >= 0); |
| 107 } | 108 } |
| 108 | 109 |
| 109 | 110 |
| 110 BreakpointLocation::~BreakpointLocation() { | 111 BreakpointLocation::~BreakpointLocation() { |
| 111 Breakpoint* bpt = breakpoints(); | 112 Breakpoint* bpt = breakpoints(); |
| 112 while (bpt != NULL) { | 113 while (bpt != NULL) { |
| 113 Breakpoint* temp = bpt; | 114 Breakpoint* temp = bpt; |
| 114 bpt = bpt->next(); | 115 bpt = bpt->next(); |
| 115 delete temp; | 116 delete temp; |
| 116 } | 117 } |
| 117 } | 118 } |
| 118 | 119 |
| 119 | 120 |
| 120 bool BreakpointLocation::AnyEnabled() const { | 121 bool BreakpointLocation::AnyEnabled() const { |
| 121 return breakpoints() != NULL; | 122 return breakpoints() != NULL; |
| 122 } | 123 } |
| 123 | 124 |
| 124 | 125 |
| 125 void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) { | 126 void BreakpointLocation::SetResolved(const Function& func, |
| 127 TokenDescriptor token_pos) { |
| 126 ASSERT(!IsLatent()); | 128 ASSERT(!IsLatent()); |
| 127 ASSERT(func.script() == script_); | 129 ASSERT(func.script() == script_); |
| 128 ASSERT((func.token_pos() <= token_pos) && | 130 ASSERT((func.token_pos() <= token_pos) && |
| 129 (token_pos <= func.end_token_pos())); | 131 (token_pos <= func.end_token_pos())); |
| 130 ASSERT(func.is_debuggable()); | 132 ASSERT(func.is_debuggable()); |
| 131 function_ = func.raw(); | 133 function_ = func.raw(); |
| 132 token_pos_ = token_pos; | 134 token_pos_ = token_pos; |
| 133 end_token_pos_ = token_pos; | 135 end_token_pos_ = token_pos; |
| 134 is_resolved_ = true; | 136 is_resolved_ = true; |
| 135 } | 137 } |
| 136 | 138 |
| 137 | 139 |
| 138 // TODO(hausner): Get rid of library parameter. A source breakpoint location | 140 // TODO(hausner): Get rid of library parameter. A source breakpoint location |
| 139 // does not imply a library, since the same source code can be included | 141 // does not imply a library, since the same source code can be included |
| 140 // in more than one library, e.g. the text location of mixin functions. | 142 // in more than one library, e.g. the text location of mixin functions. |
| 141 void BreakpointLocation::GetCodeLocation(Library* lib, | 143 void BreakpointLocation::GetCodeLocation(Library* lib, |
| 142 Script* script, | 144 Script* script, |
| 143 intptr_t* pos) const { | 145 TokenDescriptor* pos) const { |
| 144 if (IsLatent()) { | 146 if (IsLatent()) { |
| 145 *lib = Library::null(); | 147 *lib = Library::null(); |
| 146 *script = Script::null(); | 148 *script = Script::null(); |
| 147 *pos = -1; | 149 *pos = TokenDescriptor::kNoSource; |
| 148 } else { | 150 } else { |
| 149 *script = this->script(); | 151 *script = this->script(); |
| 150 *pos = token_pos_; | 152 *pos = token_pos_; |
| 151 if (IsResolved()) { | 153 if (IsResolved()) { |
| 152 const Function& func = Function::Handle(function_); | 154 const Function& func = Function::Handle(function_); |
| 153 ASSERT(!func.IsNull()); | 155 ASSERT(!func.IsNull()); |
| 154 const Class& cls = Class::Handle(func.origin()); | 156 const Class& cls = Class::Handle(func.origin()); |
| 155 *lib = cls.library(); | 157 *lib = cls.library(); |
| 156 } else { | 158 } else { |
| 157 *lib = Library::null(); | 159 *lib = Library::null(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 uword fp, | 234 uword fp, |
| 233 uword sp, | 235 uword sp, |
| 234 const Code& code, | 236 const Code& code, |
| 235 const Array& deopt_frame, | 237 const Array& deopt_frame, |
| 236 intptr_t deopt_frame_offset) | 238 intptr_t deopt_frame_offset) |
| 237 : pc_(pc), fp_(fp), sp_(sp), | 239 : pc_(pc), fp_(fp), sp_(sp), |
| 238 ctx_(Context::ZoneHandle()), | 240 ctx_(Context::ZoneHandle()), |
| 239 code_(Code::ZoneHandle(code.raw())), | 241 code_(Code::ZoneHandle(code.raw())), |
| 240 function_(Function::ZoneHandle(code.function())), | 242 function_(Function::ZoneHandle(code.function())), |
| 241 token_pos_initialized_(false), | 243 token_pos_initialized_(false), |
| 242 token_pos_(Token::kNoSourcePos), | 244 token_pos_(TokenDescriptor::kNoSource), |
| 243 try_index_(-1), | 245 try_index_(-1), |
| 244 line_number_(-1), | 246 line_number_(-1), |
| 245 column_number_(-1), | 247 column_number_(-1), |
| 246 context_level_(-1), | 248 context_level_(-1), |
| 247 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), | 249 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), |
| 248 deopt_frame_offset_(deopt_frame_offset), | 250 deopt_frame_offset_(deopt_frame_offset), |
| 249 vars_initialized_(false), | 251 vars_initialized_(false), |
| 250 var_descriptors_(LocalVarDescriptors::ZoneHandle()), | 252 var_descriptors_(LocalVarDescriptors::ZoneHandle()), |
| 251 desc_indices_(8), | 253 desc_indices_(8), |
| 252 pc_desc_(PcDescriptors::ZoneHandle()) { | 254 pc_desc_(PcDescriptors::ZoneHandle()) { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 return OS::SCreate(Thread::Current()->zone(), | 446 return OS::SCreate(Thread::Current()->zone(), |
| 445 "%s%s%s", func_class.IsTopLevel() ? "" : class_name.ToCString(), | 447 "%s%s%s", func_class.IsTopLevel() ? "" : class_name.ToCString(), |
| 446 func_class.IsTopLevel() ? "" : ".", | 448 func_class.IsTopLevel() ? "" : ".", |
| 447 func_name.ToCString()); | 449 func_name.ToCString()); |
| 448 } | 450 } |
| 449 | 451 |
| 450 | 452 |
| 451 // Returns true if function contains the token position in the given script. | 453 // Returns true if function contains the token position in the given script. |
| 452 static bool FunctionContains(const Function& func, | 454 static bool FunctionContains(const Function& func, |
| 453 const Script& script, | 455 const Script& script, |
| 454 intptr_t token_pos) { | 456 TokenDescriptor token_pos) { |
| 455 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { | 457 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { |
| 456 // Check script equality second because it allocates | 458 // Check script equality second because it allocates |
| 457 // handles as a side effect. | 459 // handles as a side effect. |
| 458 return func.script() == script.raw(); | 460 return func.script() == script.raw(); |
| 459 } | 461 } |
| 460 return false; | 462 return false; |
| 461 } | 463 } |
| 462 | 464 |
| 463 | 465 |
| 464 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { | 466 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 | 558 |
| 557 void ActivationFrame::GetPcDescriptors() { | 559 void ActivationFrame::GetPcDescriptors() { |
| 558 if (pc_desc_.IsNull()) { | 560 if (pc_desc_.IsNull()) { |
| 559 pc_desc_ = code().pc_descriptors(); | 561 pc_desc_ = code().pc_descriptors(); |
| 560 ASSERT(!pc_desc_.IsNull()); | 562 ASSERT(!pc_desc_.IsNull()); |
| 561 } | 563 } |
| 562 } | 564 } |
| 563 | 565 |
| 564 | 566 |
| 565 // Compute token_pos_ and try_index_ and token_pos_initialized_. | 567 // Compute token_pos_ and try_index_ and token_pos_initialized_. |
| 566 intptr_t ActivationFrame::TokenPos() { | 568 TokenDescriptor ActivationFrame::TokenPos() { |
| 567 if (!token_pos_initialized_) { | 569 if (!token_pos_initialized_) { |
| 568 token_pos_initialized_ = true; | 570 token_pos_initialized_ = true; |
| 569 token_pos_ = Token::kNoSourcePos; | 571 token_pos_ = TokenDescriptor::kNoSource; |
| 570 GetPcDescriptors(); | 572 GetPcDescriptors(); |
| 571 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); | 573 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); |
| 572 uword pc_offset = pc_ - code().EntryPoint(); | 574 uword pc_offset = pc_ - code().EntryPoint(); |
| 573 while (iter.MoveNext()) { | 575 while (iter.MoveNext()) { |
| 574 if (iter.PcOffset() == pc_offset) { | 576 if (iter.PcOffset() == pc_offset) { |
| 575 try_index_ = iter.TryIndex(); | 577 try_index_ = iter.TryIndex(); |
| 576 token_pos_ = iter.TokenPos(); | 578 token_pos_ = iter.TokenPos(); |
| 577 break; | 579 break; |
| 578 } | 580 } |
| 579 } | 581 } |
| 580 } | 582 } |
| 581 return token_pos_; | 583 return token_pos_; |
| 582 } | 584 } |
| 583 | 585 |
| 584 | 586 |
| 585 intptr_t ActivationFrame::TryIndex() { | 587 intptr_t ActivationFrame::TryIndex() { |
| 586 if (!token_pos_initialized_) { | 588 if (!token_pos_initialized_) { |
| 587 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. | 589 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. |
| 588 } | 590 } |
| 589 return try_index_; | 591 return try_index_; |
| 590 } | 592 } |
| 591 | 593 |
| 592 | 594 |
| 593 intptr_t ActivationFrame::LineNumber() { | 595 intptr_t ActivationFrame::LineNumber() { |
| 594 // Compute line number lazily since it causes scanning of the script. | 596 // Compute line number lazily since it causes scanning of the script. |
| 595 if ((line_number_ < 0) && Token::IsReal(TokenPos())) { | 597 if ((line_number_ < 0) && TokenPos().IsReal()) { |
| 596 const intptr_t token_pos = TokenPos(); | 598 const TokenDescriptor token_pos = TokenPos(); |
| 597 const Script& script = Script::Handle(SourceScript()); | 599 const Script& script = Script::Handle(SourceScript()); |
| 598 script.GetTokenLocation(token_pos, &line_number_, NULL); | 600 script.GetTokenLocation(token_pos, &line_number_, NULL); |
| 599 } | 601 } |
| 600 return line_number_; | 602 return line_number_; |
| 601 } | 603 } |
| 602 | 604 |
| 603 | 605 |
| 604 intptr_t ActivationFrame::ColumnNumber() { | 606 intptr_t ActivationFrame::ColumnNumber() { |
| 605 // Compute column number lazily since it causes scanning of the script. | 607 // Compute column number lazily since it causes scanning of the script. |
| 606 if ((column_number_ < 0) && Token::IsReal(TokenPos())) { | 608 if ((column_number_ < 0) && TokenPos().IsReal()) { |
| 607 const intptr_t token_pos = TokenPos(); | 609 const TokenDescriptor token_pos = TokenPos(); |
| 608 const Script& script = Script::Handle(SourceScript()); | 610 const Script& script = Script::Handle(SourceScript()); |
| 609 if (script.HasSource()) { | 611 if (script.HasSource()) { |
| 610 script.GetTokenLocation(token_pos, &line_number_, &column_number_); | 612 script.GetTokenLocation(token_pos, &line_number_, &column_number_); |
| 611 } else { | 613 } else { |
| 612 column_number_ = -1; | 614 column_number_ = -1; |
| 613 } | 615 } |
| 614 } | 616 } |
| 615 return column_number_; | 617 return column_number_; |
| 616 } | 618 } |
| 617 | 619 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 642 // Calculate the context level at the current token index of the frame. | 644 // Calculate the context level at the current token index of the frame. |
| 643 intptr_t ActivationFrame::ContextLevel() { | 645 intptr_t ActivationFrame::ContextLevel() { |
| 644 const Context& ctx = GetSavedCurrentContext(); | 646 const Context& ctx = GetSavedCurrentContext(); |
| 645 if (context_level_ < 0 && !ctx.IsNull()) { | 647 if (context_level_ < 0 && !ctx.IsNull()) { |
| 646 ASSERT(!code_.is_optimized()); | 648 ASSERT(!code_.is_optimized()); |
| 647 context_level_ = 0; | 649 context_level_ = 0; |
| 648 // TODO(hausner): What to do if there is no descriptor entry | 650 // TODO(hausner): What to do if there is no descriptor entry |
| 649 // for the code position of the frame? For now say we are at context | 651 // for the code position of the frame? For now say we are at context |
| 650 // level 0. | 652 // level 0. |
| 651 TokenPos(); | 653 TokenPos(); |
| 652 if (token_pos_ == -1) { | 654 if (token_pos_ == TokenDescriptor::kNoSource) { |
| 653 // No PcDescriptor. | 655 // No PcDescriptor. |
| 654 return context_level_; | 656 return context_level_; |
| 655 } | 657 } |
| 656 ASSERT(!pc_desc_.IsNull()); | 658 ASSERT(!pc_desc_.IsNull()); |
| 657 intptr_t innermost_begin_pos = 0; | 659 TokenDescriptor innermost_begin_pos = TokenDescriptor::kMinSource; |
| 658 intptr_t activation_token_pos = TokenPos(); | 660 TokenDescriptor activation_token_pos = TokenPos(); |
| 659 ASSERT(Token::IsReal(activation_token_pos)); | 661 ASSERT(activation_token_pos.IsReal()); |
| 660 GetVarDescriptors(); | 662 GetVarDescriptors(); |
| 661 intptr_t var_desc_len = var_descriptors_.Length(); | 663 intptr_t var_desc_len = var_descriptors_.Length(); |
| 662 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 664 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 663 RawLocalVarDescriptors::VarInfo var_info; | 665 RawLocalVarDescriptors::VarInfo var_info; |
| 664 var_descriptors_.GetInfo(cur_idx, &var_info); | 666 var_descriptors_.GetInfo(cur_idx, &var_info); |
| 665 const int8_t kind = var_info.kind(); | 667 const int8_t kind = var_info.kind(); |
| 666 if ((kind == RawLocalVarDescriptors::kContextLevel) && | 668 if ((kind == RawLocalVarDescriptors::kContextLevel) && |
| 667 (var_info.begin_pos <= activation_token_pos) && | 669 (var_info.begin_pos <= activation_token_pos) && |
| 668 (activation_token_pos < var_info.end_pos)) { | 670 (activation_token_pos < var_info.end_pos)) { |
| 669 // This var_descriptors_ entry is a context scope which is in scope | 671 // 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... |
| 761 return NULL; | 763 return NULL; |
| 762 } | 764 } |
| 763 | 765 |
| 764 | 766 |
| 765 void ActivationFrame::GetDescIndices() { | 767 void ActivationFrame::GetDescIndices() { |
| 766 if (vars_initialized_) { | 768 if (vars_initialized_) { |
| 767 return; | 769 return; |
| 768 } | 770 } |
| 769 GetVarDescriptors(); | 771 GetVarDescriptors(); |
| 770 | 772 |
| 771 intptr_t activation_token_pos = TokenPos(); | 773 TokenDescriptor activation_token_pos = TokenPos(); |
| 772 if (!Token::IsDebugPause(activation_token_pos)) { | 774 if (!activation_token_pos.IsDebugPause()) { |
| 773 // We don't have a token position for this frame, so can't determine | 775 // We don't have a token position for this frame, so can't determine |
| 774 // which variables are visible. | 776 // which variables are visible. |
| 775 vars_initialized_ = true; | 777 vars_initialized_ = true; |
| 776 return; | 778 return; |
| 777 } | 779 } |
| 778 | 780 |
| 779 GrowableArray<String*> var_names(8); | 781 GrowableArray<String*> var_names(8); |
| 780 intptr_t var_desc_len = var_descriptors_.Length(); | 782 intptr_t var_desc_len = var_descriptors_.Length(); |
| 781 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { | 783 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { |
| 782 ASSERT(var_names.length() == desc_indices_.length()); | 784 ASSERT(var_names.length() == desc_indices_.length()); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 intptr_t num = 0; | 924 intptr_t num = 0; |
| 923 while ((frame != NULL)) { | 925 while ((frame != NULL)) { |
| 924 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); | 926 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); |
| 925 frame = iterator.NextFrame(); | 927 frame = iterator.NextFrame(); |
| 926 } | 928 } |
| 927 } | 929 } |
| 928 | 930 |
| 929 | 931 |
| 930 void ActivationFrame::VariableAt(intptr_t i, | 932 void ActivationFrame::VariableAt(intptr_t i, |
| 931 String* name, | 933 String* name, |
| 932 intptr_t* token_pos, | 934 TokenDescriptor* token_pos, |
| 933 intptr_t* end_pos, | 935 TokenDescriptor* end_pos, |
| 934 Object* value) { | 936 Object* value) { |
| 935 GetDescIndices(); | 937 GetDescIndices(); |
| 936 ASSERT(i < desc_indices_.length()); | 938 ASSERT(i < desc_indices_.length()); |
| 937 intptr_t desc_index = desc_indices_[i]; | 939 intptr_t desc_index = desc_indices_[i]; |
| 938 ASSERT(name != NULL); | 940 ASSERT(name != NULL); |
| 939 | 941 |
| 940 *name = var_descriptors_.GetName(desc_index); | 942 *name = var_descriptors_.GetName(desc_index); |
| 941 | 943 |
| 942 RawLocalVarDescriptors::VarInfo var_info; | 944 RawLocalVarDescriptors::VarInfo var_info; |
| 943 var_descriptors_.GetInfo(desc_index, &var_info); | 945 var_descriptors_.GetInfo(desc_index, &var_info); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 } | 993 } |
| 992 | 994 |
| 993 | 995 |
| 994 RawArray* ActivationFrame::GetLocalVariables() { | 996 RawArray* ActivationFrame::GetLocalVariables() { |
| 995 GetDescIndices(); | 997 GetDescIndices(); |
| 996 intptr_t num_variables = desc_indices_.length(); | 998 intptr_t num_variables = desc_indices_.length(); |
| 997 String& var_name = String::Handle(); | 999 String& var_name = String::Handle(); |
| 998 Object& value = Instance::Handle(); | 1000 Object& value = Instance::Handle(); |
| 999 const Array& list = Array::Handle(Array::New(2 * num_variables)); | 1001 const Array& list = Array::Handle(Array::New(2 * num_variables)); |
| 1000 for (intptr_t i = 0; i < num_variables; i++) { | 1002 for (intptr_t i = 0; i < num_variables; i++) { |
| 1001 intptr_t ignore; | 1003 TokenDescriptor ignore; |
| 1002 VariableAt(i, &var_name, &ignore, &ignore, &value); | 1004 VariableAt(i, &var_name, &ignore, &ignore, &value); |
| 1003 list.SetAt(2 * i, var_name); | 1005 list.SetAt(2 * i, var_name); |
| 1004 list.SetAt((2 * i) + 1, value); | 1006 list.SetAt((2 * i) + 1, value); |
| 1005 } | 1007 } |
| 1006 return list.raw(); | 1008 return list.raw(); |
| 1007 } | 1009 } |
| 1008 | 1010 |
| 1009 | 1011 |
| 1010 RawObject* ActivationFrame::GetReceiver() { | 1012 RawObject* ActivationFrame::GetReceiver() { |
| 1011 GetDescIndices(); | 1013 GetDescIndices(); |
| 1012 intptr_t num_variables = desc_indices_.length(); | 1014 intptr_t num_variables = desc_indices_.length(); |
| 1013 String& var_name = String::Handle(); | 1015 String& var_name = String::Handle(); |
| 1014 Instance& value = Instance::Handle(); | 1016 Instance& value = Instance::Handle(); |
| 1015 for (intptr_t i = 0; i < num_variables; i++) { | 1017 for (intptr_t i = 0; i < num_variables; i++) { |
| 1016 intptr_t ignore; | 1018 TokenDescriptor ignore; |
| 1017 VariableAt(i, &var_name, &ignore, &ignore, &value); | 1019 VariableAt(i, &var_name, &ignore, &ignore, &value); |
| 1018 if (var_name.Equals(Symbols::This())) { | 1020 if (var_name.Equals(Symbols::This())) { |
| 1019 return value.raw(); | 1021 return value.raw(); |
| 1020 } | 1022 } |
| 1021 } | 1023 } |
| 1022 return Symbols::OptimizedOut().raw(); | 1024 return Symbols::OptimizedOut().raw(); |
| 1023 } | 1025 } |
| 1024 | 1026 |
| 1025 | 1027 |
| 1026 bool IsPrivateVariableName(const String& var_name) { | 1028 bool IsPrivateVariableName(const String& var_name) { |
| 1027 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_'); | 1029 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_'); |
| 1028 } | 1030 } |
| 1029 | 1031 |
| 1030 | 1032 |
| 1031 RawObject* ActivationFrame::Evaluate(const String& expr) { | 1033 RawObject* ActivationFrame::Evaluate(const String& expr) { |
| 1032 GetDescIndices(); | 1034 GetDescIndices(); |
| 1033 const GrowableObjectArray& param_names = | 1035 const GrowableObjectArray& param_names = |
| 1034 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1036 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1035 const GrowableObjectArray& param_values = | 1037 const GrowableObjectArray& param_values = |
| 1036 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 1038 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 1037 String& name = String::Handle(); | 1039 String& name = String::Handle(); |
| 1038 Object& value = Instance::Handle(); | 1040 Object& value = Instance::Handle(); |
| 1039 intptr_t num_variables = desc_indices_.length(); | 1041 intptr_t num_variables = desc_indices_.length(); |
| 1040 for (intptr_t i = 0; i < num_variables; i++) { | 1042 for (intptr_t i = 0; i < num_variables; i++) { |
| 1041 intptr_t ignore; | 1043 TokenDescriptor ignore; |
| 1042 VariableAt(i, &name, &ignore, &ignore, &value); | 1044 VariableAt(i, &name, &ignore, &ignore, &value); |
| 1043 if (!name.Equals(Symbols::This())) { | 1045 if (!name.Equals(Symbols::This())) { |
| 1044 if (IsPrivateVariableName(name)) { | 1046 if (IsPrivateVariableName(name)) { |
| 1045 name = String::IdentifierPrettyName(name); | 1047 name = String::IdentifierPrettyName(name); |
| 1046 } | 1048 } |
| 1047 param_names.Add(name); | 1049 param_names.Add(name); |
| 1048 param_values.Add(value); | 1050 param_values.Add(value); |
| 1049 } | 1051 } |
| 1050 } | 1052 } |
| 1051 | 1053 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 // in the world where we pass the script as part of the | 1104 // in the world where we pass the script as part of the |
| 1103 // location. | 1105 // location. |
| 1104 jsobj->AddProperty("script", script, !full); | 1106 jsobj->AddProperty("script", script, !full); |
| 1105 } | 1107 } |
| 1106 { | 1108 { |
| 1107 JSONArray jsvars(jsobj, "vars"); | 1109 JSONArray jsvars(jsobj, "vars"); |
| 1108 const int num_vars = NumLocalVariables(); | 1110 const int num_vars = NumLocalVariables(); |
| 1109 for (intptr_t v = 0; v < num_vars; v++) { | 1111 for (intptr_t v = 0; v < num_vars; v++) { |
| 1110 String& var_name = String::Handle(); | 1112 String& var_name = String::Handle(); |
| 1111 Instance& var_value = Instance::Handle(); | 1113 Instance& var_value = Instance::Handle(); |
| 1112 intptr_t token_pos; | 1114 TokenDescriptor token_pos; |
| 1113 intptr_t end_token_pos; | 1115 TokenDescriptor end_token_pos; |
| 1114 VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value); | 1116 VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value); |
| 1115 if (var_name.raw() != Symbols::AsyncOperation().raw()) { | 1117 if (var_name.raw() != Symbols::AsyncOperation().raw()) { |
| 1116 JSONObject jsvar(&jsvars); | 1118 JSONObject jsvar(&jsvars); |
| 1117 jsvar.AddProperty("type", "BoundVariable"); | 1119 jsvar.AddProperty("type", "BoundVariable"); |
| 1118 var_name = String::IdentifierPrettyName(var_name); | 1120 var_name = String::IdentifierPrettyName(var_name); |
| 1119 jsvar.AddProperty("name", var_name.ToCString()); | 1121 jsvar.AddProperty("name", var_name.ToCString()); |
| 1120 jsvar.AddProperty("value", var_value, !full); | 1122 jsvar.AddProperty("value", var_value, !full); |
| 1121 // TODO(turnidge): Do we really want to provide this on every | 1123 // TODO(turnidge): Do we really want to provide this on every |
| 1122 // stack dump? Should be associated with the function object, I | 1124 // stack dump? Should be associated with the function object, I |
| 1123 // think, and not the stack frame. | 1125 // think, and not the stack frame. |
| 1124 jsvar.AddProperty("_tokenPos", token_pos); | 1126 jsvar.AddProperty("_tokenPos", token_pos.value()); |
| 1125 jsvar.AddProperty("_endTokenPos", end_token_pos); | 1127 jsvar.AddProperty("_endTokenPos", end_token_pos.value()); |
| 1126 } | 1128 } |
| 1127 } | 1129 } |
| 1128 } | 1130 } |
| 1129 } | 1131 } |
| 1130 | 1132 |
| 1131 | 1133 |
| 1132 | 1134 |
| 1133 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { | 1135 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { |
| 1134 if (FLAG_show_invisible_frames || frame->function().is_visible()) { | 1136 if (FLAG_show_invisible_frames || frame->function().is_visible()) { |
| 1135 trace_.Add(frame); | 1137 trace_.Add(frame); |
| 1136 } | 1138 } |
| 1137 } | 1139 } |
| 1138 | 1140 |
| 1139 | 1141 |
| 1140 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall | 1142 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
| 1141 | RawPcDescriptors::kUnoptStaticCall | 1143 | RawPcDescriptors::kUnoptStaticCall |
| 1142 | RawPcDescriptors::kRuntimeCall; | 1144 | RawPcDescriptors::kRuntimeCall; |
| 1143 | 1145 |
| 1144 | 1146 |
| 1145 CodeBreakpoint::CodeBreakpoint(const Code& code, | 1147 CodeBreakpoint::CodeBreakpoint(const Code& code, |
| 1146 intptr_t token_pos, | 1148 TokenDescriptor token_pos, |
| 1147 uword pc, | 1149 uword pc, |
| 1148 RawPcDescriptors::Kind kind) | 1150 RawPcDescriptors::Kind kind) |
| 1149 : code_(code.raw()), | 1151 : code_(code.raw()), |
| 1150 token_pos_(token_pos), | 1152 token_pos_(token_pos), |
| 1151 pc_(pc), | 1153 pc_(pc), |
| 1152 line_number_(-1), | 1154 line_number_(-1), |
| 1153 is_enabled_(false), | 1155 is_enabled_(false), |
| 1154 bpt_location_(NULL), | 1156 bpt_location_(NULL), |
| 1155 next_(NULL), | 1157 next_(NULL), |
| 1156 breakpoint_kind_(kind), | 1158 breakpoint_kind_(kind), |
| 1157 saved_value_(Code::null()) { | 1159 saved_value_(Code::null()) { |
| 1158 ASSERT(!code.IsNull()); | 1160 ASSERT(!code.IsNull()); |
| 1159 ASSERT(token_pos_ > 0); | 1161 ASSERT(token_pos_.IsReal()); |
| 1160 ASSERT(pc_ != 0); | 1162 ASSERT(pc_ != 0); |
| 1161 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); | 1163 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); |
| 1162 } | 1164 } |
| 1163 | 1165 |
| 1164 | 1166 |
| 1165 CodeBreakpoint::~CodeBreakpoint() { | 1167 CodeBreakpoint::~CodeBreakpoint() { |
| 1166 // Make sure we don't leave patched code behind. | 1168 // Make sure we don't leave patched code behind. |
| 1167 ASSERT(!IsEnabled()); | 1169 ASSERT(!IsEnabled()); |
| 1168 // Poison the data so we catch use after free errors. | 1170 // Poison the data so we catch use after free errors. |
| 1169 #ifdef DEBUG | 1171 #ifdef DEBUG |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 event.set_exception(&exc); | 1642 event.set_exception(&exc); |
| 1641 ASSERT(stack_trace->Length() > 0); | 1643 ASSERT(stack_trace->Length() > 0); |
| 1642 event.set_top_frame(stack_trace->FrameAt(0)); | 1644 event.set_top_frame(stack_trace->FrameAt(0)); |
| 1643 ASSERT(stack_trace_ == NULL); | 1645 ASSERT(stack_trace_ == NULL); |
| 1644 stack_trace_ = stack_trace; | 1646 stack_trace_ = stack_trace; |
| 1645 Pause(&event); | 1647 Pause(&event); |
| 1646 stack_trace_ = NULL; | 1648 stack_trace_ = NULL; |
| 1647 } | 1649 } |
| 1648 | 1650 |
| 1649 | 1651 |
| 1650 static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { | 1652 static TokenDescriptor LastTokenOnLine(const TokenStream& tokens, |
| 1651 TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens); | 1653 TokenDescriptor pos) { |
| 1654 TokenStream::Iterator iter(tokens, |
| 1655 pos.value(), |
| 1656 TokenStream::Iterator::kAllTokens); |
| 1652 ASSERT(iter.IsValid()); | 1657 ASSERT(iter.IsValid()); |
| 1653 intptr_t last_pos = pos; | 1658 TokenDescriptor last_pos = pos; |
| 1654 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && | 1659 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && |
| 1655 (iter.CurrentTokenKind() != Token::kEOS)) { | 1660 (iter.CurrentTokenKind() != Token::kEOS)) { |
| 1656 last_pos = iter.CurrentPosition(); | 1661 last_pos = TokenDescriptor(iter.CurrentPosition()); |
| 1657 iter.Advance(); | 1662 iter.Advance(); |
| 1658 } | 1663 } |
| 1659 return last_pos; | 1664 return last_pos; |
| 1660 } | 1665 } |
| 1661 | 1666 |
| 1662 | 1667 |
| 1663 // Returns the best fit token position for a breakpoint. | 1668 // Returns the best fit token position for a breakpoint. |
| 1664 // | 1669 // |
| 1665 // Takes a range of tokens [requested_token_pos, last_token_pos] and | 1670 // Takes a range of tokens [requested_token_pos, last_token_pos] and |
| 1666 // an optional column (requested_column). The range of tokens usually | 1671 // an optional column (requested_column). The range of tokens usually |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1709 // | 1714 // |
| 1710 // If no best fit token can be found, the search is expanded, | 1715 // If no best fit token can be found, the search is expanded, |
| 1711 // searching through the rest of the current function by calling this | 1716 // searching through the rest of the current function by calling this |
| 1712 // function recursively. | 1717 // function recursively. |
| 1713 // | 1718 // |
| 1714 // TODO(turnidge): Given that we usually call this function with a | 1719 // TODO(turnidge): Given that we usually call this function with a |
| 1715 // token range restricted to a single line, this could be a one-pass | 1720 // token range restricted to a single line, this could be a one-pass |
| 1716 // algorithm, which would be simpler. I believe that it only needs | 1721 // algorithm, which would be simpler. I believe that it only needs |
| 1717 // two passes to support the recursive try-the-whole-function case. | 1722 // two passes to support the recursive try-the-whole-function case. |
| 1718 // Rewrite this later, once there are more tests in place. | 1723 // Rewrite this later, once there are more tests in place. |
| 1719 intptr_t Debugger::ResolveBreakpointPos(const Function& func, | 1724 TokenDescriptor Debugger::ResolveBreakpointPos( |
| 1720 intptr_t requested_token_pos, | 1725 const Function& func, |
| 1721 intptr_t last_token_pos, | 1726 TokenDescriptor requested_token_pos, |
| 1722 intptr_t requested_column) { | 1727 TokenDescriptor last_token_pos, |
| 1728 intptr_t requested_column) { |
| 1723 ASSERT(func.HasCode()); | 1729 ASSERT(func.HasCode()); |
| 1724 ASSERT(!func.HasOptimizedCode()); | 1730 ASSERT(!func.HasOptimizedCode()); |
| 1725 | 1731 |
| 1726 if (requested_token_pos < func.token_pos()) { | 1732 if (requested_token_pos < func.token_pos()) { |
| 1727 requested_token_pos = func.token_pos(); | 1733 requested_token_pos = func.token_pos(); |
| 1728 } | 1734 } |
| 1729 if (last_token_pos > func.end_token_pos()) { | 1735 if (last_token_pos > func.end_token_pos()) { |
| 1730 last_token_pos = func.end_token_pos(); | 1736 last_token_pos = func.end_token_pos(); |
| 1731 } | 1737 } |
| 1732 | 1738 |
| 1733 Script& script = Script::Handle(func.script()); | 1739 Script& script = Script::Handle(func.script()); |
| 1734 Code& code = Code::Handle(func.unoptimized_code()); | 1740 Code& code = Code::Handle(func.unoptimized_code()); |
| 1735 ASSERT(!code.IsNull()); | 1741 ASSERT(!code.IsNull()); |
| 1736 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1742 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 1737 | 1743 |
| 1738 // First pass: find the safe point which is closest to the beginning | 1744 // First pass: find the safe point which is closest to the beginning |
| 1739 // of the given token range. | 1745 // of the given token range. |
| 1740 intptr_t best_fit_pos = INT_MAX; | 1746 TokenDescriptor best_fit_pos = TokenDescriptor::kMaxSource; |
| 1741 intptr_t best_column = INT_MAX; | 1747 intptr_t best_column = INT_MAX; |
| 1742 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1748 PcDescriptors::Iterator iter(desc, kSafepointKind); |
| 1743 while (iter.MoveNext()) { | 1749 while (iter.MoveNext()) { |
| 1744 const intptr_t pos = iter.TokenPos(); | 1750 const TokenDescriptor pos = iter.TokenPos(); |
| 1745 if ((!Token::IsReal(pos)) || | 1751 if ((!pos.IsReal()) || |
| 1746 (pos < requested_token_pos) || | 1752 (pos < requested_token_pos) || |
| 1747 (pos > last_token_pos)) { | 1753 (pos > last_token_pos)) { |
| 1748 // Token is not in the target range. | 1754 // Token is not in the target range. |
| 1749 continue; | 1755 continue; |
| 1750 } | 1756 } |
| 1751 | 1757 |
| 1752 intptr_t token_start_column = -1; | 1758 intptr_t token_start_column = -1; |
| 1753 if (requested_column >= 0) { | 1759 if (requested_column >= 0) { |
| 1754 intptr_t ignored = -1; | 1760 intptr_t ignored = -1; |
| 1755 intptr_t token_len = -1; | 1761 intptr_t token_len = -1; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1772 // Prefer the lowest (first) token pos. | 1778 // Prefer the lowest (first) token pos. |
| 1773 if (pos < best_fit_pos) { | 1779 if (pos < best_fit_pos) { |
| 1774 best_fit_pos = pos; | 1780 best_fit_pos = pos; |
| 1775 best_column = token_start_column; | 1781 best_column = token_start_column; |
| 1776 } | 1782 } |
| 1777 } | 1783 } |
| 1778 | 1784 |
| 1779 // Second pass (if we found a safe point in the first pass). Find | 1785 // Second pass (if we found a safe point in the first pass). Find |
| 1780 // the token on the line which is at the best fit column (if column | 1786 // the token on the line which is at the best fit column (if column |
| 1781 // was specified) and has the lowest code address. | 1787 // was specified) and has the lowest code address. |
| 1782 if (best_fit_pos != INT_MAX) { | 1788 if (best_fit_pos != TokenDescriptor::kMaxSource) { |
| 1783 const Script& script = Script::Handle(func.script()); | 1789 const Script& script = Script::Handle(func.script()); |
| 1784 const TokenStream& tokens = TokenStream::Handle(script.tokens()); | 1790 const TokenStream& tokens = TokenStream::Handle(script.tokens()); |
| 1785 const intptr_t begin_pos = best_fit_pos; | 1791 const TokenDescriptor begin_pos = best_fit_pos; |
| 1786 const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos); | 1792 const TokenDescriptor end_of_line_pos = LastTokenOnLine(tokens, begin_pos); |
| 1787 uword lowest_pc_offset = kUwordMax; | 1793 uword lowest_pc_offset = kUwordMax; |
| 1788 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1794 PcDescriptors::Iterator iter(desc, kSafepointKind); |
| 1789 while (iter.MoveNext()) { | 1795 while (iter.MoveNext()) { |
| 1790 const intptr_t pos = iter.TokenPos(); | 1796 const TokenDescriptor pos = iter.TokenPos(); |
| 1791 if ((!Token::IsReal(pos)) || | 1797 if ((!TokenDescriptor(pos).IsReal()) || |
| 1792 (pos < begin_pos) || | 1798 (pos < begin_pos) || |
| 1793 (pos > end_of_line_pos)) { | 1799 (pos > end_of_line_pos)) { |
| 1794 // Token is not on same line as best fit. | 1800 // Token is not on same line as best fit. |
| 1795 continue; | 1801 continue; |
| 1796 } | 1802 } |
| 1797 | 1803 |
| 1798 if (requested_column >= 0) { | 1804 if (requested_column >= 0) { |
| 1799 intptr_t ignored = -1; | 1805 intptr_t ignored = -1; |
| 1800 intptr_t token_start_column = -1; | 1806 intptr_t token_start_column = -1; |
| 1801 // We look for other tokens at the best column in case there | 1807 // We look for other tokens at the best column in case there |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1816 } | 1822 } |
| 1817 | 1823 |
| 1818 // We didn't find a safe point in the given token range. Try and | 1824 // We didn't find a safe point in the given token range. Try and |
| 1819 // find a safe point in the remaining source code of the function. | 1825 // find a safe point in the remaining source code of the function. |
| 1820 // Since we have moved to the next line of the function, we no | 1826 // Since we have moved to the next line of the function, we no |
| 1821 // longer are requesting a specific column number. | 1827 // longer are requesting a specific column number. |
| 1822 if (last_token_pos < func.end_token_pos()) { | 1828 if (last_token_pos < func.end_token_pos()) { |
| 1823 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), | 1829 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), |
| 1824 -1 /* no column */); | 1830 -1 /* no column */); |
| 1825 } | 1831 } |
| 1826 return Token::kNoSourcePos; | 1832 return TokenDescriptor::kNoSource; |
| 1827 } | 1833 } |
| 1828 | 1834 |
| 1829 | 1835 |
| 1830 void Debugger::MakeCodeBreakpointAt(const Function& func, | 1836 void Debugger::MakeCodeBreakpointAt(const Function& func, |
| 1831 BreakpointLocation* loc) { | 1837 BreakpointLocation* loc) { |
| 1832 ASSERT(Token::IsReal(loc->token_pos_)); | 1838 ASSERT(TokenDescriptor(loc->token_pos_).IsReal()); |
| 1833 ASSERT((loc != NULL) && loc->IsResolved()); | 1839 ASSERT((loc != NULL) && loc->IsResolved()); |
| 1834 ASSERT(!func.HasOptimizedCode()); | 1840 ASSERT(!func.HasOptimizedCode()); |
| 1835 Code& code = Code::Handle(func.unoptimized_code()); | 1841 Code& code = Code::Handle(func.unoptimized_code()); |
| 1836 ASSERT(!code.IsNull()); | 1842 ASSERT(!code.IsNull()); |
| 1837 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 1843 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 1838 uword lowest_pc_offset = kUwordMax; | 1844 uword lowest_pc_offset = kUwordMax; |
| 1839 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; | 1845 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; |
| 1840 // Find the safe point with the lowest compiled code address | 1846 // Find the safe point with the lowest compiled code address |
| 1841 // that maps to the token position of the source breakpoint. | 1847 // that maps to the token position of the source breakpoint. |
| 1842 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1848 PcDescriptors::Iterator iter(desc, kSafepointKind); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1860 RegisterCodeBreakpoint(code_bpt); | 1866 RegisterCodeBreakpoint(code_bpt); |
| 1861 } | 1867 } |
| 1862 code_bpt->set_bpt_location(loc); | 1868 code_bpt->set_bpt_location(loc); |
| 1863 if (loc->AnyEnabled()) { | 1869 if (loc->AnyEnabled()) { |
| 1864 code_bpt->Enable(); | 1870 code_bpt->Enable(); |
| 1865 } | 1871 } |
| 1866 } | 1872 } |
| 1867 | 1873 |
| 1868 | 1874 |
| 1869 void Debugger::FindCompiledFunctions(const Script& script, | 1875 void Debugger::FindCompiledFunctions(const Script& script, |
| 1870 intptr_t start_pos, | 1876 TokenDescriptor start_pos, |
| 1871 intptr_t end_pos, | 1877 TokenDescriptor end_pos, |
| 1872 GrowableObjectArray* function_list) { | 1878 GrowableObjectArray* function_list) { |
| 1873 Zone* zone = Thread::Current()->zone(); | 1879 Zone* zone = Thread::Current()->zone(); |
| 1874 Class& cls = Class::Handle(zone); | 1880 Class& cls = Class::Handle(zone); |
| 1875 Array& functions = Array::Handle(zone); | 1881 Array& functions = Array::Handle(zone); |
| 1876 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1882 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1877 Function& function = Function::Handle(zone); | 1883 Function& function = Function::Handle(zone); |
| 1878 | 1884 |
| 1879 closures = isolate_->object_store()->closure_functions(); | 1885 closures = isolate_->object_store()->closure_functions(); |
| 1880 const intptr_t num_closures = closures.Length(); | 1886 const intptr_t num_closures = closures.Length(); |
| 1881 for (intptr_t pos = 0; pos < num_closures; pos++) { | 1887 for (intptr_t pos = 0; pos < num_closures; pos++) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1945 } else { | 1951 } else { |
| 1946 if ((func->token_pos() > best_fit->token_pos()) && | 1952 if ((func->token_pos() > best_fit->token_pos()) && |
| 1947 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1953 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
| 1948 *best_fit = func->raw(); | 1954 *best_fit = func->raw(); |
| 1949 } | 1955 } |
| 1950 } | 1956 } |
| 1951 } | 1957 } |
| 1952 | 1958 |
| 1953 | 1959 |
| 1954 RawFunction* Debugger::FindBestFit(const Script& script, | 1960 RawFunction* Debugger::FindBestFit(const Script& script, |
| 1955 intptr_t token_pos) { | 1961 TokenDescriptor token_pos) { |
| 1956 Zone* zone = Thread::Current()->zone(); | 1962 Zone* zone = Thread::Current()->zone(); |
| 1957 Class& cls = Class::Handle(zone); | 1963 Class& cls = Class::Handle(zone); |
| 1958 Array& functions = Array::Handle(zone); | 1964 Array& functions = Array::Handle(zone); |
| 1959 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); | 1965 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1960 Function& function = Function::Handle(zone); | 1966 Function& function = Function::Handle(zone); |
| 1961 Function& best_fit = Function::Handle(zone); | 1967 Function& best_fit = Function::Handle(zone); |
| 1962 Error& error = Error::Handle(zone); | 1968 Error& error = Error::Handle(zone); |
| 1963 | 1969 |
| 1964 closures = isolate_->object_store()->closure_functions(); | 1970 closures = isolate_->object_store()->closure_functions(); |
| 1965 const intptr_t num_closures = closures.Length(); | 1971 const intptr_t num_closures = closures.Length(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2004 } | 2010 } |
| 2005 } | 2011 } |
| 2006 } | 2012 } |
| 2007 } | 2013 } |
| 2008 } | 2014 } |
| 2009 return best_fit.raw(); | 2015 return best_fit.raw(); |
| 2010 } | 2016 } |
| 2011 | 2017 |
| 2012 | 2018 |
| 2013 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2019 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
| 2014 intptr_t token_pos, | 2020 TokenDescriptor token_pos, |
| 2015 intptr_t last_token_pos, | 2021 TokenDescriptor last_token_pos, |
| 2016 intptr_t requested_line, | 2022 intptr_t requested_line, |
| 2017 intptr_t requested_column) { | 2023 intptr_t requested_column) { |
| 2018 Function& func = Function::Handle(); | 2024 Function& func = Function::Handle(); |
| 2019 func = FindBestFit(script, token_pos); | 2025 func = FindBestFit(script, token_pos); |
| 2020 if (func.IsNull()) { | 2026 if (func.IsNull()) { |
| 2021 return NULL; | 2027 return NULL; |
| 2022 } | 2028 } |
| 2023 // There may be more than one function object for a given function | 2029 // There may be more than one function object for a given function |
| 2024 // in source code. There may be implicit closure functions, and | 2030 // in source code. There may be implicit closure functions, and |
| 2025 // there may be copies of mixin functions. Collect all compiled | 2031 // there may be copies of mixin functions. Collect all compiled |
| 2026 // functions whose source code range matches exactly the best fit | 2032 // functions whose source code range matches exactly the best fit |
| 2027 // function we found. | 2033 // function we found. |
| 2028 GrowableObjectArray& functions = | 2034 GrowableObjectArray& functions = |
| 2029 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2035 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2030 FindCompiledFunctions(script, | 2036 FindCompiledFunctions(script, |
| 2031 func.token_pos(), | 2037 func.token_pos(), |
| 2032 func.end_token_pos(), | 2038 func.end_token_pos(), |
| 2033 &functions); | 2039 &functions); |
| 2034 | 2040 |
| 2035 if (functions.Length() > 0) { | 2041 if (functions.Length() > 0) { |
| 2036 // One or more function object containing this breakpoint location | 2042 // One or more function object containing this breakpoint location |
| 2037 // have already been compiled. We can resolve the breakpoint now. | 2043 // have already been compiled. We can resolve the breakpoint now. |
| 2038 DeoptimizeWorld(); | 2044 DeoptimizeWorld(); |
| 2039 func ^= functions.At(0); | 2045 func ^= functions.At(0); |
| 2040 intptr_t breakpoint_pos = | 2046 TokenDescriptor breakpoint_pos = |
| 2041 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); | 2047 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); |
| 2042 if (breakpoint_pos >= 0) { | 2048 if (breakpoint_pos >= TokenDescriptor::kMinSource) { |
| 2043 BreakpointLocation* bpt = | 2049 BreakpointLocation* bpt = |
| 2044 GetBreakpointLocation(script, breakpoint_pos, requested_column); | 2050 GetBreakpointLocation(script, breakpoint_pos, requested_column); |
| 2045 if (bpt != NULL) { | 2051 if (bpt != NULL) { |
| 2046 // A source breakpoint for this location already exists. | 2052 // A source breakpoint for this location already exists. |
| 2047 return bpt; | 2053 return bpt; |
| 2048 } | 2054 } |
| 2049 bpt = new BreakpointLocation(script, token_pos, last_token_pos, | 2055 bpt = new BreakpointLocation(script, token_pos, last_token_pos, |
| 2050 requested_line, requested_column); | 2056 requested_line, requested_column); |
| 2051 bpt->SetResolved(func, breakpoint_pos); | 2057 bpt->SetResolved(func, breakpoint_pos); |
| 2052 RegisterBreakpointLocation(bpt); | 2058 RegisterBreakpointLocation(bpt); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 } | 2241 } |
| 2236 return latent_bpt; | 2242 return latent_bpt; |
| 2237 } | 2243 } |
| 2238 if (scripts.Length() > 1) { | 2244 if (scripts.Length() > 1) { |
| 2239 if (FLAG_verbose_debug) { | 2245 if (FLAG_verbose_debug) { |
| 2240 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); | 2246 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); |
| 2241 } | 2247 } |
| 2242 return NULL; | 2248 return NULL; |
| 2243 } | 2249 } |
| 2244 script ^= scripts.At(0); | 2250 script ^= scripts.At(0); |
| 2245 intptr_t first_token_idx, last_token_idx; | 2251 TokenDescriptor first_token_idx, last_token_idx; |
| 2246 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); | 2252 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); |
| 2247 if (!Token::IsReal(first_token_idx)) { | 2253 if (!TokenDescriptor(first_token_idx).IsReal()) { |
| 2248 // Script does not contain the given line number. | 2254 // Script does not contain the given line number. |
| 2249 if (FLAG_verbose_debug) { | 2255 if (FLAG_verbose_debug) { |
| 2250 OS::Print("Script '%s' does not contain line number %" Pd "\n", | 2256 OS::Print("Script '%s' does not contain line number %" Pd "\n", |
| 2251 script_url.ToCString(), line_number); | 2257 script_url.ToCString(), line_number); |
| 2252 } | 2258 } |
| 2253 return NULL; | 2259 return NULL; |
| 2254 } else if (!Token::IsReal(last_token_idx)) { | 2260 } else if (!TokenDescriptor(last_token_idx).IsReal()) { |
| 2255 // Line does not contain any tokens. | 2261 // Line does not contain any tokens. |
| 2256 if (FLAG_verbose_debug) { | 2262 if (FLAG_verbose_debug) { |
| 2257 OS::Print("No executable code at line %" Pd " in '%s'\n", | 2263 OS::Print("No executable code at line %" Pd " in '%s'\n", |
| 2258 line_number, script_url.ToCString()); | 2264 line_number, script_url.ToCString()); |
| 2259 } | 2265 } |
| 2260 return NULL; | 2266 return NULL; |
| 2261 } | 2267 } |
| 2262 | 2268 |
| 2263 BreakpointLocation* bpt = NULL; | 2269 BreakpointLocation* bpt = NULL; |
| 2264 ASSERT(first_token_idx <= last_token_idx); | 2270 ASSERT(first_token_idx <= last_token_idx); |
| 2265 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { | 2271 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { |
| 2266 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, | 2272 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, |
| 2267 line_number, column_number); | 2273 line_number, column_number); |
| 2268 first_token_idx++; | 2274 first_token_idx = TokenDescriptor(first_token_idx.value() + 1); |
| 2269 } | 2275 } |
| 2270 if ((bpt == NULL) && FLAG_verbose_debug) { | 2276 if ((bpt == NULL) && FLAG_verbose_debug) { |
| 2271 OS::Print("No executable code at line %" Pd " in '%s'\n", | 2277 OS::Print("No executable code at line %" Pd " in '%s'\n", |
| 2272 line_number, script_url.ToCString()); | 2278 line_number, script_url.ToCString()); |
| 2273 } | 2279 } |
| 2274 return bpt; | 2280 return bpt; |
| 2275 } | 2281 } |
| 2276 | 2282 |
| 2277 | 2283 |
| 2278 intptr_t Debugger::CacheObject(const Object& obj) { | 2284 intptr_t Debugger::CacheObject(const Object& obj) { |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached); | 2610 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached); |
| 2605 event.set_top_frame(top_frame); | 2611 event.set_top_frame(top_frame); |
| 2606 event.set_breakpoint(bpt); | 2612 event.set_breakpoint(bpt); |
| 2607 Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation()); | 2613 Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation()); |
| 2608 if (!closure_or_null.IsNull()) { | 2614 if (!closure_or_null.IsNull()) { |
| 2609 ASSERT(closure_or_null.IsInstance()); | 2615 ASSERT(closure_or_null.IsInstance()); |
| 2610 ASSERT(Instance::Cast(closure_or_null).IsClosure()); | 2616 ASSERT(Instance::Cast(closure_or_null).IsClosure()); |
| 2611 event.set_async_continuation(&closure_or_null); | 2617 event.set_async_continuation(&closure_or_null); |
| 2612 const Script& script = Script::Handle(top_frame->SourceScript()); | 2618 const Script& script = Script::Handle(top_frame->SourceScript()); |
| 2613 const TokenStream& tokens = TokenStream::Handle(script.tokens()); | 2619 const TokenStream& tokens = TokenStream::Handle(script.tokens()); |
| 2614 TokenStream::Iterator iter(tokens, top_frame->TokenPos()); | 2620 TokenStream::Iterator iter(tokens, top_frame->TokenPos().value()); |
| 2615 if ((iter.CurrentTokenKind() == Token::kIDENT) && | 2621 if ((iter.CurrentTokenKind() == Token::kIDENT) && |
| 2616 ((iter.CurrentLiteral() == Symbols::Await().raw()) || | 2622 ((iter.CurrentLiteral() == Symbols::Await().raw()) || |
| 2617 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) { | 2623 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) { |
| 2618 event.set_at_async_jump(true); | 2624 event.set_at_async_jump(true); |
| 2619 } | 2625 } |
| 2620 } | 2626 } |
| 2621 Pause(&event); | 2627 Pause(&event); |
| 2622 } | 2628 } |
| 2623 | 2629 |
| 2624 | 2630 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2652 // We returned from the "interesting frame", there can be no more | 2658 // We returned from the "interesting frame", there can be no more |
| 2653 // stepping breaks for it. Pause at the next appropriate location | 2659 // stepping breaks for it. Pause at the next appropriate location |
| 2654 // and let the user set the "interesting" frame again. | 2660 // and let the user set the "interesting" frame again. |
| 2655 stepping_fp_ = 0; | 2661 stepping_fp_ = 0; |
| 2656 } | 2662 } |
| 2657 } | 2663 } |
| 2658 | 2664 |
| 2659 if (!frame->IsDebuggable()) { | 2665 if (!frame->IsDebuggable()) { |
| 2660 return Error::null(); | 2666 return Error::null(); |
| 2661 } | 2667 } |
| 2662 if (!Token::IsDebugPause(frame->TokenPos())) { | 2668 if (!TokenDescriptor(frame->TokenPos()).IsDebugPause()) { |
| 2663 return Error::null(); | 2669 return Error::null(); |
| 2664 } | 2670 } |
| 2665 | 2671 |
| 2666 // If there is an active breakpoint at this pc, then we should have | 2672 // If there is an active breakpoint at this pc, then we should have |
| 2667 // already bailed out of this function in the skip_next_step_ test | 2673 // already bailed out of this function in the skip_next_step_ test |
| 2668 // above. | 2674 // above. |
| 2669 ASSERT(!HasActiveBreakpoint(frame->pc())); | 2675 ASSERT(!HasActiveBreakpoint(frame->pc())); |
| 2670 | 2676 |
| 2671 if (FLAG_verbose_debug) { | 2677 if (FLAG_verbose_debug) { |
| 2672 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", | 2678 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", |
| 2673 String::Handle(frame->SourceUrl()).ToCString(), | 2679 String::Handle(frame->SourceUrl()).ToCString(), |
| 2674 frame->LineNumber(), | 2680 frame->LineNumber(), |
| 2675 String::Handle(frame->QualifiedFunctionName()).ToCString(), | 2681 String::Handle(frame->QualifiedFunctionName()).ToCString(), |
| 2676 frame->TokenPos()); | 2682 frame->TokenPos().value()); |
| 2677 } | 2683 } |
| 2678 | 2684 |
| 2679 ASSERT(stack_trace_ == NULL); | 2685 ASSERT(stack_trace_ == NULL); |
| 2680 stack_trace_ = CollectStackTrace(); | 2686 stack_trace_ = CollectStackTrace(); |
| 2681 SignalPausedEvent(frame, NULL); | 2687 SignalPausedEvent(frame, NULL); |
| 2682 HandleSteppingRequest(stack_trace_); | 2688 HandleSteppingRequest(stack_trace_); |
| 2683 stack_trace_ = NULL; | 2689 stack_trace_ = NULL; |
| 2684 | 2690 |
| 2685 // If any error occurred while in the debug message loop, return it here. | 2691 // If any error occurred while in the debug message loop, return it here. |
| 2686 const Error& error = | 2692 const Error& error = |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2751 if (bpt_hit == NULL) { | 2757 if (bpt_hit == NULL) { |
| 2752 return Error::null(); | 2758 return Error::null(); |
| 2753 } | 2759 } |
| 2754 | 2760 |
| 2755 if (FLAG_verbose_debug) { | 2761 if (FLAG_verbose_debug) { |
| 2756 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " | 2762 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " |
| 2757 "(token %" Pd ") (address %#" Px ")\n", | 2763 "(token %" Pd ") (address %#" Px ")\n", |
| 2758 cbpt->IsInternal() ? "internal" : "user", | 2764 cbpt->IsInternal() ? "internal" : "user", |
| 2759 String::Handle(cbpt->SourceUrl()).ToCString(), | 2765 String::Handle(cbpt->SourceUrl()).ToCString(), |
| 2760 cbpt->LineNumber(), | 2766 cbpt->LineNumber(), |
| 2761 cbpt->token_pos(), | 2767 cbpt->token_pos().value(), |
| 2762 top_frame->pc()); | 2768 top_frame->pc()); |
| 2763 } | 2769 } |
| 2764 | 2770 |
| 2765 ASSERT(stack_trace_ == NULL); | 2771 ASSERT(stack_trace_ == NULL); |
| 2766 stack_trace_ = stack_trace; | 2772 stack_trace_ = stack_trace; |
| 2767 SignalPausedEvent(top_frame, bpt_hit); | 2773 SignalPausedEvent(top_frame, bpt_hit); |
| 2768 // When we single step from a user breakpoint, our next stepping | 2774 // When we single step from a user breakpoint, our next stepping |
| 2769 // point will be at the exact same pc. Skip it. | 2775 // point will be at the exact same pc. Skip it. |
| 2770 HandleSteppingRequest(stack_trace_, true /* skip next step */); | 2776 HandleSteppingRequest(stack_trace_, true /* skip next step */); |
| 2771 stack_trace_ = NULL; | 2777 stack_trace_ = NULL; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2830 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { | 2836 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { |
| 2831 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2837 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
| 2832 creation_message_sent_ = true; | 2838 creation_message_sent_ = true; |
| 2833 } | 2839 } |
| 2834 } | 2840 } |
| 2835 | 2841 |
| 2836 | 2842 |
| 2837 // Return innermost closure contained in 'function' that contains | 2843 // Return innermost closure contained in 'function' that contains |
| 2838 // the given token position. | 2844 // the given token position. |
| 2839 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2845 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
| 2840 intptr_t token_pos) { | 2846 TokenDescriptor token_pos) { |
| 2841 Zone* zone = Thread::Current()->zone(); | 2847 Zone* zone = Thread::Current()->zone(); |
| 2842 const Script& outer_origin = Script::Handle(zone, function.script()); | 2848 const Script& outer_origin = Script::Handle(zone, function.script()); |
| 2843 const GrowableObjectArray& closures = | 2849 const GrowableObjectArray& closures = |
| 2844 GrowableObjectArray::Handle(zone, | 2850 GrowableObjectArray::Handle(zone, |
| 2845 Isolate::Current()->object_store()->closure_functions()); | 2851 Isolate::Current()->object_store()->closure_functions()); |
| 2846 const intptr_t num_closures = closures.Length(); | 2852 const intptr_t num_closures = closures.Length(); |
| 2847 Function& closure = Function::Handle(zone); | 2853 Function& closure = Function::Handle(zone); |
| 2848 Function& best_fit = Function::Handle(zone); | 2854 Function& best_fit = Function::Handle(zone); |
| 2849 for (intptr_t i = 0; i < num_closures; i++) { | 2855 for (intptr_t i = 0; i < num_closures; i++) { |
| 2850 closure ^= closures.At(i); | 2856 closure ^= closures.At(i); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2895 | 2901 |
| 2896 // TODO(hausner): What should we do if function is optimized? | 2902 // TODO(hausner): What should we do if function is optimized? |
| 2897 // Can we deoptimize the function? | 2903 // Can we deoptimize the function? |
| 2898 ASSERT(!func.HasOptimizedCode()); | 2904 ASSERT(!func.HasOptimizedCode()); |
| 2899 | 2905 |
| 2900 // There is no local function within func that contains the | 2906 // There is no local function within func that contains the |
| 2901 // breakpoint token position. Resolve the breakpoint if necessary | 2907 // breakpoint token position. Resolve the breakpoint if necessary |
| 2902 // and set the code breakpoints. | 2908 // and set the code breakpoints. |
| 2903 if (!loc->IsResolved()) { | 2909 if (!loc->IsResolved()) { |
| 2904 // Resolve source breakpoint in the newly compiled function. | 2910 // Resolve source breakpoint in the newly compiled function. |
| 2905 intptr_t bp_pos = | 2911 TokenDescriptor bp_pos = |
| 2906 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), | 2912 ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), |
| 2907 loc->requested_column_number()); | 2913 loc->requested_column_number()); |
| 2908 if (!Token::IsDebugPause(bp_pos)) { | 2914 if (!TokenDescriptor(bp_pos).IsDebugPause()) { |
| 2909 if (FLAG_verbose_debug) { | 2915 if (FLAG_verbose_debug) { |
| 2910 OS::Print("Failed resolving breakpoint for function '%s'\n", | 2916 OS::Print("Failed resolving breakpoint for function '%s'\n", |
| 2911 String::Handle(func.name()).ToCString()); | 2917 String::Handle(func.name()).ToCString()); |
| 2912 } | 2918 } |
| 2913 continue; | 2919 continue; |
| 2914 } | 2920 } |
| 2915 intptr_t requested_pos = loc->token_pos(); | 2921 TokenDescriptor requested_pos = loc->token_pos(); |
| 2916 intptr_t requested_end_pos = loc->end_token_pos(); | 2922 TokenDescriptor requested_end_pos = loc->end_token_pos(); |
| 2917 loc->SetResolved(func, bp_pos); | 2923 loc->SetResolved(func, bp_pos); |
| 2918 Breakpoint* bpt = loc->breakpoints(); | 2924 Breakpoint* bpt = loc->breakpoints(); |
| 2919 while (bpt != NULL) { | 2925 while (bpt != NULL) { |
| 2920 if (FLAG_verbose_debug) { | 2926 if (FLAG_verbose_debug) { |
| 2921 OS::Print("Resolved BP %" Pd " to pos %" Pd ", " | 2927 OS::Print("Resolved BP %" Pd " to pos %" Pd ", " |
| 2922 "line %" Pd " col %" Pd ", " | 2928 "line %" Pd " col %" Pd ", " |
| 2923 "function '%s' (requested range %" Pd "-%" Pd ", " | 2929 "function '%s' (requested range %" Pd "-%" Pd ", " |
| 2924 "requested col %" Pd ")\n", | 2930 "requested col %" Pd ")\n", |
| 2925 bpt->id(), | 2931 bpt->id(), |
| 2926 loc->token_pos(), | 2932 loc->token_pos().value(), |
| 2927 loc->LineNumber(), | 2933 loc->LineNumber(), |
| 2928 loc->ColumnNumber(), | 2934 loc->ColumnNumber(), |
| 2929 func.ToFullyQualifiedCString(), | 2935 func.ToFullyQualifiedCString(), |
| 2930 requested_pos, | 2936 requested_pos.value(), |
| 2931 requested_end_pos, | 2937 requested_end_pos.value(), |
| 2932 loc->requested_column_number()); | 2938 loc->requested_column_number()); |
| 2933 } | 2939 } |
| 2934 SignalBpResolved(bpt); | 2940 SignalBpResolved(bpt); |
| 2935 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); | 2941 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); |
| 2936 bpt = bpt->next(); | 2942 bpt = bpt->next(); |
| 2937 } | 2943 } |
| 2938 } | 2944 } |
| 2939 ASSERT(loc->IsResolved()); | 2945 ASSERT(loc->IsResolved()); |
| 2940 if (FLAG_verbose_debug) { | 2946 if (FLAG_verbose_debug) { |
| 2941 Breakpoint* bpt = loc->breakpoints(); | 2947 Breakpoint* bpt = loc->breakpoints(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2984 if (prev_loc == NULL) { | 2990 if (prev_loc == NULL) { |
| 2985 latent_locations_ = loc; | 2991 latent_locations_ = loc; |
| 2986 } else { | 2992 } else { |
| 2987 prev_loc->set_next(loc); | 2993 prev_loc->set_next(loc); |
| 2988 } | 2994 } |
| 2989 // Now find the token range at the requested line and make a | 2995 // Now find the token range at the requested line and make a |
| 2990 // new unresolved source breakpoint. | 2996 // new unresolved source breakpoint. |
| 2991 intptr_t line_number = matched_loc->requested_line_number(); | 2997 intptr_t line_number = matched_loc->requested_line_number(); |
| 2992 intptr_t column_number = matched_loc->requested_column_number(); | 2998 intptr_t column_number = matched_loc->requested_column_number(); |
| 2993 ASSERT(line_number >= 0); | 2999 ASSERT(line_number >= 0); |
| 2994 intptr_t first_token_pos, last_token_pos; | 3000 TokenDescriptor first_token_pos, last_token_pos; |
| 2995 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); | 3001 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); |
| 2996 if (!Token::IsDebugPause(first_token_pos) || | 3002 if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) { |
| 2997 !Token::IsDebugPause(last_token_pos)) { | |
| 2998 // Script does not contain the given line number or there are no | 3003 // Script does not contain the given line number or there are no |
| 2999 // tokens on the line. Drop the breakpoint silently. | 3004 // tokens on the line. Drop the breakpoint silently. |
| 3000 Breakpoint* bpt = matched_loc->breakpoints(); | 3005 Breakpoint* bpt = matched_loc->breakpoints(); |
| 3001 while (bpt != NULL) { | 3006 while (bpt != NULL) { |
| 3002 if (FLAG_verbose_debug) { | 3007 if (FLAG_verbose_debug) { |
| 3003 OS::Print("No code found at line %" Pd ": " | 3008 OS::Print("No code found at line %" Pd ": " |
| 3004 "dropping latent breakpoint %" Pd " in '%s'\n", | 3009 "dropping latent breakpoint %" Pd " in '%s'\n", |
| 3005 line_number, | 3010 line_number, |
| 3006 bpt->id(), | 3011 bpt->id(), |
| 3007 url.ToCString()); | 3012 url.ToCString()); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3195 delete temp_bpt; | 3200 delete temp_bpt; |
| 3196 } else { | 3201 } else { |
| 3197 prev_bpt = curr_bpt; | 3202 prev_bpt = curr_bpt; |
| 3198 curr_bpt = curr_bpt->next(); | 3203 curr_bpt = curr_bpt->next(); |
| 3199 } | 3204 } |
| 3200 } | 3205 } |
| 3201 } | 3206 } |
| 3202 | 3207 |
| 3203 | 3208 |
| 3204 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, | 3209 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, |
| 3205 intptr_t token_pos, | 3210 TokenDescriptor token_pos, |
| 3206 intptr_t requested_column) { | 3211 intptr_t requested_column) { |
| 3207 BreakpointLocation* bpt = breakpoint_locations_; | 3212 BreakpointLocation* bpt = breakpoint_locations_; |
| 3208 while (bpt != NULL) { | 3213 while (bpt != NULL) { |
| 3209 if ((bpt->script_ == script.raw()) && | 3214 if ((bpt->script_ == script.raw()) && |
| 3210 (bpt->token_pos_ == token_pos) && | 3215 (bpt->token_pos_ == token_pos) && |
| 3211 (bpt->requested_column_number_ == requested_column)) { | 3216 (bpt->requested_column_number_ == requested_column)) { |
| 3212 return bpt; | 3217 return bpt; |
| 3213 } | 3218 } |
| 3214 bpt = bpt->next(); | 3219 bpt = bpt->next(); |
| 3215 } | 3220 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 } | 3267 } |
| 3263 | 3268 |
| 3264 | 3269 |
| 3265 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3270 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 3266 ASSERT(bpt->next() == NULL); | 3271 ASSERT(bpt->next() == NULL); |
| 3267 bpt->set_next(code_breakpoints_); | 3272 bpt->set_next(code_breakpoints_); |
| 3268 code_breakpoints_ = bpt; | 3273 code_breakpoints_ = bpt; |
| 3269 } | 3274 } |
| 3270 | 3275 |
| 3271 } // namespace dart | 3276 } // namespace dart |
| OLD | NEW |