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

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
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_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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698