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

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

Issue 1644793002: Replace intptr_t with TokenDescriptor (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debugger.h" 5 #include "vm/debugger.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698