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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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"
(...skipping 16 matching lines...) Expand all
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/timeline.h" 30 #include "vm/timeline.h"
31 #include "vm/token_position.h" 31 #include "vm/token_position.h"
32 #include "vm/visitor.h" 32 #include "vm/visitor.h"
33 33
34 34
35 namespace dart { 35 namespace dart {
36 36
37 DEFINE_FLAG(bool, show_invisible_frames, false, 37 DEFINE_FLAG(bool,
38 show_invisible_frames,
39 false,
38 "Show invisible frames in debugger stack traces"); 40 "Show invisible frames in debugger stack traces");
39 DEFINE_FLAG(bool, trace_debugger_stacktrace, false, 41 DEFINE_FLAG(bool,
42 trace_debugger_stacktrace,
43 false,
40 "Trace debugger stacktrace collection"); 44 "Trace debugger stacktrace collection");
41 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); 45 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
42 DEFINE_FLAG(bool, steal_breakpoints, false, 46 DEFINE_FLAG(bool,
47 steal_breakpoints,
48 false,
43 "Intercept breakpoints and other pause events before they " 49 "Intercept breakpoints and other pause events before they "
44 "are sent to the embedder and use a generic VM breakpoint " 50 "are sent to the embedder and use a generic VM breakpoint "
45 "handler instead. This handler dispatches breakpoints to " 51 "handler instead. This handler dispatches breakpoints to "
46 "the VM service."); 52 "the VM service.");
47 53
48 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); 54 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
49 55
50 56
51 #ifndef PRODUCT 57 #ifndef PRODUCT
52 58
53 Debugger::EventHandler* Debugger::event_handler_ = NULL; 59 Debugger::EventHandler* Debugger::event_handler_ = NULL;
54 60
55 61
56 class RemoteObjectCache : public ZoneAllocated { 62 class RemoteObjectCache : public ZoneAllocated {
57 public: 63 public:
58 explicit RemoteObjectCache(intptr_t initial_size); 64 explicit RemoteObjectCache(intptr_t initial_size);
59 intptr_t AddObject(const Object& obj); 65 intptr_t AddObject(const Object& obj);
60 RawObject* GetObj(intptr_t obj_id) const; 66 RawObject* GetObj(intptr_t obj_id) const;
61 bool IsValidId(intptr_t obj_id) const { 67 bool IsValidId(intptr_t obj_id) const { return obj_id < objs_->Length(); }
62 return obj_id < objs_->Length();
63 }
64 68
65 private: 69 private:
66 GrowableObjectArray* objs_; 70 GrowableObjectArray* objs_;
67 71
68 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); 72 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache);
69 }; 73 };
70 74
71 75
72 // Create an unresolved breakpoint in given token range and script. 76 // Create an unresolved breakpoint in given token range and script.
73 BreakpointLocation::BreakpointLocation(const Script& script, 77 BreakpointLocation::BreakpointLocation(const Script& script,
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 202 }
199 203
200 204
201 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) { 205 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
202 visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_)); 206 visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
203 visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_)); 207 visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
204 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); 208 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
205 209
206 Breakpoint* bpt = conditions_; 210 Breakpoint* bpt = conditions_;
207 while (bpt != NULL) { 211 while (bpt != NULL) {
208 bpt -> VisitObjectPointers(visitor); 212 bpt->VisitObjectPointers(visitor);
209 bpt = bpt->next(); 213 bpt = bpt->next();
210 } 214 }
211 } 215 }
212 216
213 217
214 void Breakpoint::PrintJSON(JSONStream* stream) { 218 void Breakpoint::PrintJSON(JSONStream* stream) {
215 JSONObject jsobj(stream); 219 JSONObject jsobj(stream);
216 jsobj.AddProperty("type", "Breakpoint"); 220 jsobj.AddProperty("type", "Breakpoint");
217 221
218 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id()); 222 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id());
(...skipping 11 matching lines...) Expand all
230 234
231 235
232 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 236 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
233 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_)); 237 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
234 #if !defined(TARGET_ARCH_DBC) 238 #if !defined(TARGET_ARCH_DBC)
235 visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_)); 239 visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_));
236 #endif 240 #endif
237 } 241 }
238 242
239 243
240 ActivationFrame::ActivationFrame( 244 ActivationFrame::ActivationFrame(uword pc,
241 uword pc, 245 uword fp,
242 uword fp, 246 uword sp,
243 uword sp, 247 const Code& code,
244 const Code& code, 248 const Array& deopt_frame,
245 const Array& deopt_frame, 249 intptr_t deopt_frame_offset)
246 intptr_t deopt_frame_offset) 250 : pc_(pc),
247 : pc_(pc), fp_(fp), sp_(sp), 251 fp_(fp),
252 sp_(sp),
248 ctx_(Context::ZoneHandle()), 253 ctx_(Context::ZoneHandle()),
249 code_(Code::ZoneHandle(code.raw())), 254 code_(Code::ZoneHandle(code.raw())),
250 function_(Function::ZoneHandle(code.function())), 255 function_(Function::ZoneHandle(code.function())),
251 token_pos_initialized_(false), 256 token_pos_initialized_(false),
252 token_pos_(TokenPosition::kNoSource), 257 token_pos_(TokenPosition::kNoSource),
253 try_index_(-1), 258 try_index_(-1),
254 line_number_(-1), 259 line_number_(-1),
255 column_number_(-1), 260 column_number_(-1),
256 context_level_(-1), 261 context_level_(-1),
257 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 262 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
258 deopt_frame_offset_(deopt_frame_offset), 263 deopt_frame_offset_(deopt_frame_offset),
259 vars_initialized_(false), 264 vars_initialized_(false),
260 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 265 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
261 desc_indices_(8), 266 desc_indices_(8),
262 pc_desc_(PcDescriptors::ZoneHandle()) { 267 pc_desc_(PcDescriptors::ZoneHandle()) {}
263 }
264 268
265 269
266 bool Debugger::NeedsIsolateEvents() { 270 bool Debugger::NeedsIsolateEvents() {
267 return ((isolate_ != Dart::vm_isolate()) && 271 return ((isolate_ != Dart::vm_isolate()) &&
268 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) && 272 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
269 ((event_handler_ != NULL) || Service::isolate_stream.enabled())); 273 ((event_handler_ != NULL) || Service::isolate_stream.enabled()));
270 } 274 }
271 275
272 276
273 bool Debugger::NeedsDebugEvents() { 277 bool Debugger::NeedsDebugEvents() {
274 ASSERT(isolate_ != Dart::vm_isolate() && 278 ASSERT(isolate_ != Dart::vm_isolate() &&
275 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)); 279 !ServiceIsolate::IsServiceIsolateDescendant(isolate_));
276 return (FLAG_warn_on_pause_with_no_debugger || 280 return (FLAG_warn_on_pause_with_no_debugger || (event_handler_ != NULL) ||
277 (event_handler_ != NULL) ||
278 Service::debug_stream.enabled()); 281 Service::debug_stream.enabled());
279 } 282 }
280 283
281 284
282 void Debugger::InvokeEventHandler(ServiceEvent* event) { 285 void Debugger::InvokeEventHandler(ServiceEvent* event) {
283 ASSERT(!event->IsPause()); // For pause events, call Pause instead. 286 ASSERT(!event->IsPause()); // For pause events, call Pause instead.
284 Service::HandleEvent(event); 287 Service::HandleEvent(event);
285 288
286 // Call the embedder's event handler, if it exists. 289 // Call the embedder's event handler, if it exists.
287 if (event_handler_ != NULL) { 290 if (event_handler_ != NULL) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 } 403 }
401 return bpt; 404 return bpt;
402 } 405 }
403 406
404 407
405 const char* Debugger::QualifiedFunctionName(const Function& func) { 408 const char* Debugger::QualifiedFunctionName(const Function& func) {
406 const String& func_name = String::Handle(func.name()); 409 const String& func_name = String::Handle(func.name());
407 Class& func_class = Class::Handle(func.Owner()); 410 Class& func_class = Class::Handle(func.Owner());
408 String& class_name = String::Handle(func_class.Name()); 411 String& class_name = String::Handle(func_class.Name());
409 412
410 return OS::SCreate(Thread::Current()->zone(), 413 return OS::SCreate(Thread::Current()->zone(), "%s%s%s",
411 "%s%s%s", func_class.IsTopLevel() ? "" : class_name.ToCString(), 414 func_class.IsTopLevel() ? "" : class_name.ToCString(),
412 func_class.IsTopLevel() ? "" : ".", 415 func_class.IsTopLevel() ? "" : ".", func_name.ToCString());
413 func_name.ToCString());
414 } 416 }
415 417
416 418
417 // Returns true if function contains the token position in the given script. 419 // Returns true if function contains the token position in the given script.
418 static bool FunctionContains(const Function& func, 420 static bool FunctionContains(const Function& func,
419 const Script& script, 421 const Script& script,
420 TokenPosition token_pos) { 422 TokenPosition token_pos) {
421 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { 423 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) {
422 // Check script equality second because it allocates 424 // Check script equality second because it allocates
423 // handles as a side effect. 425 // handles as a side effect.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 return column_number_; 583 return column_number_;
582 } 584 }
583 585
584 586
585 void ActivationFrame::GetVarDescriptors() { 587 void ActivationFrame::GetVarDescriptors() {
586 if (var_descriptors_.IsNull()) { 588 if (var_descriptors_.IsNull()) {
587 Code& unoptimized_code = Code::Handle(function().unoptimized_code()); 589 Code& unoptimized_code = Code::Handle(function().unoptimized_code());
588 if (unoptimized_code.IsNull()) { 590 if (unoptimized_code.IsNull()) {
589 Thread* thread = Thread::Current(); 591 Thread* thread = Thread::Current();
590 Zone* zone = thread->zone(); 592 Zone* zone = thread->zone();
591 const Error& error = Error::Handle(zone, 593 const Error& error = Error::Handle(
592 Compiler::EnsureUnoptimizedCode(thread, function())); 594 zone, Compiler::EnsureUnoptimizedCode(thread, function()));
593 if (!error.IsNull()) { 595 if (!error.IsNull()) {
594 Exceptions::PropagateError(error); 596 Exceptions::PropagateError(error);
595 } 597 }
596 unoptimized_code ^= function().unoptimized_code(); 598 unoptimized_code ^= function().unoptimized_code();
597 } 599 }
598 ASSERT(!unoptimized_code.IsNull()); 600 ASSERT(!unoptimized_code.IsNull());
599 var_descriptors_ = unoptimized_code.GetLocalVarDescriptors(); 601 var_descriptors_ = unoptimized_code.GetLocalVarDescriptors();
600 ASSERT(!var_descriptors_.IsNull()); 602 ASSERT(!var_descriptors_.IsNull());
601 } 603 }
602 } 604 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 if (!ctx_.IsNull()) return ctx_; 656 if (!ctx_.IsNull()) return ctx_;
655 GetVarDescriptors(); 657 GetVarDescriptors();
656 intptr_t var_desc_len = var_descriptors_.Length(); 658 intptr_t var_desc_len = var_descriptors_.Length();
657 for (intptr_t i = 0; i < var_desc_len; i++) { 659 for (intptr_t i = 0; i < var_desc_len; i++) {
658 RawLocalVarDescriptors::VarInfo var_info; 660 RawLocalVarDescriptors::VarInfo var_info;
659 var_descriptors_.GetInfo(i, &var_info); 661 var_descriptors_.GetInfo(i, &var_info);
660 const int8_t kind = var_info.kind(); 662 const int8_t kind = var_info.kind();
661 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { 663 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
662 if (FLAG_trace_debugger_stacktrace) { 664 if (FLAG_trace_debugger_stacktrace) {
663 OS::PrintErr("\tFound saved current ctx at index %d\n", 665 OS::PrintErr("\tFound saved current ctx at index %d\n",
664 var_info.index()); 666 var_info.index());
665 } 667 }
666 ctx_ ^= GetStackVar(var_info.index()); 668 ctx_ ^= GetStackVar(var_info.index());
667 return ctx_; 669 return ctx_;
668 } 670 }
669 } 671 }
670 return Context::ZoneHandle(Context::null()); 672 return Context::ZoneHandle(Context::null());
671 } 673 }
672 674
673 675
674 RawObject* ActivationFrame::GetAsyncOperation() { 676 RawObject* ActivationFrame::GetAsyncOperation() {
(...skipping 15 matching lines...) Expand all
690 return Object::null(); 692 return Object::null();
691 } 693 }
692 694
693 695
694 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 696 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
695 const Instance& exc_obj) const { 697 const Instance& exc_obj) const {
696 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); 698 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
697 Array& handled_types = Array::Handle(); 699 Array& handled_types = Array::Handle();
698 AbstractType& type = Type::Handle(); 700 AbstractType& type = Type::Handle();
699 const TypeArguments& no_instantiator = TypeArguments::Handle(); 701 const TypeArguments& no_instantiator = TypeArguments::Handle();
700 for (intptr_t frame_index = 0; 702 for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) {
701 frame_index < Length();
702 frame_index++) {
703 ActivationFrame* frame = FrameAt(frame_index); 703 ActivationFrame* frame = FrameAt(frame_index);
704 intptr_t try_index = frame->TryIndex(); 704 intptr_t try_index = frame->TryIndex();
705 if (try_index < 0) continue; 705 if (try_index < 0) continue;
706 handlers = frame->code().exception_handlers(); 706 handlers = frame->code().exception_handlers();
707 ASSERT(!handlers.IsNull()); 707 ASSERT(!handlers.IsNull());
708 intptr_t num_handlers_checked = 0; 708 intptr_t num_handlers_checked = 0;
709 while (try_index >= 0) { 709 while (try_index >= 0) {
710 // Detect circles in the exception handler data. 710 // Detect circles in the exception handler data.
711 num_handlers_checked++; 711 num_handlers_checked++;
712 ASSERT(num_handlers_checked <= handlers.num_entries()); 712 ASSERT(num_handlers_checked <= handlers.num_entries());
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 819
820 RawObject* ActivationFrame::GetParameter(intptr_t index) { 820 RawObject* ActivationFrame::GetParameter(intptr_t index) {
821 intptr_t num_parameters = function().num_fixed_parameters(); 821 intptr_t num_parameters = function().num_fixed_parameters();
822 ASSERT(0 <= index && index < num_parameters); 822 ASSERT(0 <= index && index < num_parameters);
823 823
824 if (function().NumOptionalParameters() > 0) { 824 if (function().NumOptionalParameters() > 0) {
825 // If the function has optional parameters, the first positional parameter 825 // If the function has optional parameters, the first positional parameter
826 // can be in a number of places in the caller's frame depending on how many 826 // can be in a number of places in the caller's frame depending on how many
827 // were actually supplied at the call site, but they are copied to a fixed 827 // were actually supplied at the call site, but they are copied to a fixed
828 // place in the callee's frame. 828 // place in the callee's frame.
829 return GetVariableValue(LocalVarAddress(fp(), 829 return GetVariableValue(
830 (kFirstLocalSlotFromFp - index))); 830 LocalVarAddress(fp(), (kFirstLocalSlotFromFp - index)));
831 } else { 831 } else {
832 intptr_t reverse_index = num_parameters - index; 832 intptr_t reverse_index = num_parameters - index;
833 return GetVariableValue(ParamAddress(fp(), reverse_index)); 833 return GetVariableValue(ParamAddress(fp(), reverse_index));
834 } 834 }
835 } 835 }
836 836
837 837
838 RawObject* ActivationFrame::GetClosure() { 838 RawObject* ActivationFrame::GetClosure() {
839 ASSERT(function().IsClosureFunction()); 839 ASSERT(function().IsClosureFunction());
840 return GetParameter(0); 840 return GetParameter(0);
841 } 841 }
842 842
843 843
844 RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) { 844 RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) {
845 if (deopt_frame_.IsNull()) { 845 if (deopt_frame_.IsNull()) {
846 return GetVariableValue(LocalVarAddress(fp(), slot_index)); 846 return GetVariableValue(LocalVarAddress(fp(), slot_index));
847 } else { 847 } else {
848 return deopt_frame_.At(LocalVarIndex(deopt_frame_offset_, slot_index)); 848 return deopt_frame_.At(LocalVarIndex(deopt_frame_offset_, slot_index));
849 } 849 }
850 } 850 }
851 851
852 852
853 void ActivationFrame::PrintContextMismatchError( 853 void ActivationFrame::PrintContextMismatchError(intptr_t ctx_slot,
854 intptr_t ctx_slot, 854 intptr_t frame_ctx_level,
855 intptr_t frame_ctx_level, 855 intptr_t var_ctx_level) {
856 intptr_t var_ctx_level) { 856 OS::PrintErr(
857 OS::PrintErr("-------------------------\n" 857 "-------------------------\n"
858 "Encountered context mismatch\n" 858 "Encountered context mismatch\n"
859 "\tctx_slot: %" Pd "\n" 859 "\tctx_slot: %" Pd
860 "\tframe_ctx_level: %" Pd "\n" 860 "\n"
861 "\tvar_ctx_level: %" Pd "\n\n", 861 "\tframe_ctx_level: %" Pd
862 ctx_slot, 862 "\n"
863 frame_ctx_level, 863 "\tvar_ctx_level: %" Pd "\n\n",
864 var_ctx_level); 864 ctx_slot, frame_ctx_level, var_ctx_level);
865 865
866 OS::PrintErr("-------------------------\n" 866 OS::PrintErr(
867 "Current frame:\n%s\n", 867 "-------------------------\n"
868 this->ToCString()); 868 "Current frame:\n%s\n",
869 this->ToCString());
869 870
870 OS::PrintErr("-------------------------\n" 871 OS::PrintErr(
871 "Context contents:\n"); 872 "-------------------------\n"
873 "Context contents:\n");
872 const Context& ctx = GetSavedCurrentContext(); 874 const Context& ctx = GetSavedCurrentContext();
873 ctx.Dump(8); 875 ctx.Dump(8);
874 876
875 OS::PrintErr("-------------------------\n" 877 OS::PrintErr(
876 "Debugger stack trace...\n\n"); 878 "-------------------------\n"
877 DebuggerStackTrace* stack = 879 "Debugger stack trace...\n\n");
878 Isolate::Current()->debugger()->StackTrace(); 880 DebuggerStackTrace* stack = Isolate::Current()->debugger()->StackTrace();
879 intptr_t num_frames = stack->Length(); 881 intptr_t num_frames = stack->Length();
880 for (intptr_t i = 0; i < num_frames; i++) { 882 for (intptr_t i = 0; i < num_frames; i++) {
881 ActivationFrame* frame = stack->FrameAt(i); 883 ActivationFrame* frame = stack->FrameAt(i);
882 OS::PrintErr("#%04" Pd " %s", i, frame->ToCString()); 884 OS::PrintErr("#%04" Pd " %s", i, frame->ToCString());
883 } 885 }
884 886
885 OS::PrintErr("-------------------------\n" 887 OS::PrintErr(
886 "All frames...\n\n"); 888 "-------------------------\n"
889 "All frames...\n\n");
887 StackFrameIterator iterator(false); 890 StackFrameIterator iterator(false);
888 StackFrame* frame = iterator.NextFrame(); 891 StackFrame* frame = iterator.NextFrame();
889 intptr_t num = 0; 892 intptr_t num = 0;
890 while ((frame != NULL)) { 893 while ((frame != NULL)) {
891 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); 894 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
892 frame = iterator.NextFrame(); 895 frame = iterator.NextFrame();
893 } 896 }
894 } 897 }
895 898
896 899
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level, 932 RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level,
930 intptr_t ctx_slot) { 933 intptr_t ctx_slot) {
931 const Context& ctx = GetSavedCurrentContext(); 934 const Context& ctx = GetSavedCurrentContext();
932 ASSERT(!ctx.IsNull()); 935 ASSERT(!ctx.IsNull());
933 936
934 // The context level at the PC/token index of this activation frame. 937 // The context level at the PC/token index of this activation frame.
935 intptr_t frame_ctx_level = ContextLevel(); 938 intptr_t frame_ctx_level = ContextLevel();
936 939
937 intptr_t level_diff = frame_ctx_level - var_ctx_level; 940 intptr_t level_diff = frame_ctx_level - var_ctx_level;
938 if (level_diff == 0) { 941 if (level_diff == 0) {
939 if ((ctx_slot < 0) || 942 if ((ctx_slot < 0) || (ctx_slot >= ctx.num_variables())) {
940 (ctx_slot >= ctx.num_variables())) {
941 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level); 943 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level);
942 } 944 }
943 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables())); 945 ASSERT((ctx_slot >= 0) && (ctx_slot < ctx.num_variables()));
944 return ctx.At(ctx_slot); 946 return ctx.At(ctx_slot);
945 } else { 947 } else {
946 ASSERT(level_diff > 0); 948 ASSERT(level_diff > 0);
947 Context& var_ctx = Context::Handle(ctx.raw()); 949 Context& var_ctx = Context::Handle(ctx.raw());
948 while (level_diff > 0 && !var_ctx.IsNull()) { 950 while (level_diff > 0 && !var_ctx.IsNull()) {
949 level_diff--; 951 level_diff--;
950 var_ctx = var_ctx.parent(); 952 var_ctx = var_ctx.parent();
951 } 953 }
952 if (var_ctx.IsNull() || 954 if (var_ctx.IsNull() || (ctx_slot < 0) ||
953 (ctx_slot < 0) ||
954 (ctx_slot >= var_ctx.num_variables())) { 955 (ctx_slot >= var_ctx.num_variables())) {
955 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level); 956 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level);
956 } 957 }
957 ASSERT(!var_ctx.IsNull()); 958 ASSERT(!var_ctx.IsNull());
958 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); 959 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables()));
959 return var_ctx.At(ctx_slot); 960 return var_ctx.At(ctx_slot);
960 } 961 }
961 } 962 }
962 963
963 964
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 if (IsPrivateVariableName(name)) { 1020 if (IsPrivateVariableName(name)) {
1020 name = String::ScrubName(name); 1021 name = String::ScrubName(name);
1021 } 1022 }
1022 param_names.Add(name); 1023 param_names.Add(name);
1023 param_values.Add(value); 1024 param_values.Add(value);
1024 } 1025 }
1025 } 1026 }
1026 1027
1027 if (function().is_static()) { 1028 if (function().is_static()) {
1028 const Class& cls = Class::Handle(function().Owner()); 1029 const Class& cls = Class::Handle(function().Owner());
1029 return cls.Evaluate(expr, 1030 return cls.Evaluate(expr, Array::Handle(Array::MakeArray(param_names)),
1030 Array::Handle(Array::MakeArray(param_names)),
1031 Array::Handle(Array::MakeArray(param_values))); 1031 Array::Handle(Array::MakeArray(param_values)));
1032 } else { 1032 } else {
1033 const Object& receiver = Object::Handle(GetReceiver()); 1033 const Object& receiver = Object::Handle(GetReceiver());
1034 const Class& method_cls = Class::Handle(function().origin()); 1034 const Class& method_cls = Class::Handle(function().origin());
1035 ASSERT(receiver.IsInstance() || receiver.IsNull()); 1035 ASSERT(receiver.IsInstance() || receiver.IsNull());
1036 if (!(receiver.IsInstance() || receiver.IsNull())) { 1036 if (!(receiver.IsInstance() || receiver.IsNull())) {
1037 return Object::null(); 1037 return Object::null();
1038 } 1038 }
1039 const Instance& inst = Instance::Cast(receiver); 1039 const Instance& inst = Instance::Cast(receiver);
1040 return inst.Evaluate(method_cls, 1040 return inst.Evaluate(method_cls, expr,
1041 expr,
1042 Array::Handle(Array::MakeArray(param_names)), 1041 Array::Handle(Array::MakeArray(param_names)),
1043 Array::Handle(Array::MakeArray(param_values))); 1042 Array::Handle(Array::MakeArray(param_values)));
1044 } 1043 }
1045 UNREACHABLE(); 1044 UNREACHABLE();
1046 return Object::null(); 1045 return Object::null();
1047 } 1046 }
1048 1047
1049 1048
1050 const char* ActivationFrame::ToCString() { 1049 const char* ActivationFrame::ToCString() {
1051 const String& url = String::Handle(SourceUrl()); 1050 const String& url = String::Handle(SourceUrl());
1052 intptr_t line = LineNumber(); 1051 intptr_t line = LineNumber();
1053 const char* func_name = Debugger::QualifiedFunctionName(function()); 1052 const char* func_name = Debugger::QualifiedFunctionName(function());
1054 return Thread::Current()->zone()-> 1053 return Thread::Current()->zone()->PrintToString(
1055 PrintToString("[ Frame pc(0x%" Px ") fp(0x%" Px ") sp(0x%" Px ")\n" 1054 "[ Frame pc(0x%" Px ") fp(0x%" Px ") sp(0x%" Px
1056 "\tfunction = %s\n" 1055 ")\n"
1057 "\turl = %s\n" 1056 "\tfunction = %s\n"
1058 "\tline = %" Pd "\n" 1057 "\turl = %s\n"
1059 "\tcontext = %s\n" 1058 "\tline = %" Pd
1060 "\tcontext level = %" Pd " ]\n", 1059 "\n"
1061 pc(), fp(), sp(), 1060 "\tcontext = %s\n"
1062 func_name, 1061 "\tcontext level = %" Pd " ]\n",
1063 url.ToCString(), 1062 pc(), fp(), sp(), func_name, url.ToCString(), line, ctx_.ToCString(),
1064 line, 1063 ContextLevel());
1065 ctx_.ToCString(),
1066 ContextLevel());
1067 } 1064 }
1068 1065
1069 1066
1070 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, 1067 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) {
1071 bool full) {
1072 const Script& script = Script::Handle(SourceScript()); 1068 const Script& script = Script::Handle(SourceScript());
1073 jsobj->AddProperty("type", "Frame"); 1069 jsobj->AddProperty("type", "Frame");
1074 TokenPosition pos = TokenPos(); 1070 TokenPosition pos = TokenPos();
1075 if (pos.IsSynthetic()) { 1071 if (pos.IsSynthetic()) {
1076 pos = pos.FromSynthetic(); 1072 pos = pos.FromSynthetic();
1077 } 1073 }
1078 jsobj->AddLocation(script, pos); 1074 jsobj->AddLocation(script, pos);
1079 jsobj->AddProperty("function", function(), !full); 1075 jsobj->AddProperty("function", function(), !full);
1080 jsobj->AddProperty("code", code()); 1076 jsobj->AddProperty("code", code());
1081 if (full) { 1077 if (full) {
1082 // TODO(cutch): The old "full" script usage no longer fits 1078 // TODO(cutch): The old "full" script usage no longer fits
1083 // in the world where we pass the script as part of the 1079 // in the world where we pass the script as part of the
1084 // location. 1080 // location.
1085 jsobj->AddProperty("script", script, !full); 1081 jsobj->AddProperty("script", script, !full);
1086 } 1082 }
1087 { 1083 {
1088 JSONArray jsvars(jsobj, "vars"); 1084 JSONArray jsvars(jsobj, "vars");
1089 const int num_vars = NumLocalVariables(); 1085 const int num_vars = NumLocalVariables();
1090 for (intptr_t v = 0; v < num_vars; v++) { 1086 for (intptr_t v = 0; v < num_vars; v++) {
1091 String& var_name = String::Handle(); 1087 String& var_name = String::Handle();
1092 Instance& var_value = Instance::Handle(); 1088 Instance& var_value = Instance::Handle();
1093 TokenPosition declaration_token_pos; 1089 TokenPosition declaration_token_pos;
1094 TokenPosition visible_start_token_pos; 1090 TokenPosition visible_start_token_pos;
1095 TokenPosition visible_end_token_pos; 1091 TokenPosition visible_end_token_pos;
1096 VariableAt(v, 1092 VariableAt(v, &var_name, &declaration_token_pos, &visible_start_token_pos,
1097 &var_name, 1093 &visible_end_token_pos, &var_value);
1098 &declaration_token_pos,
1099 &visible_start_token_pos,
1100 &visible_end_token_pos,
1101 &var_value);
1102 if (var_name.raw() != Symbols::AsyncOperation().raw()) { 1094 if (var_name.raw() != Symbols::AsyncOperation().raw()) {
1103 JSONObject jsvar(&jsvars); 1095 JSONObject jsvar(&jsvars);
1104 jsvar.AddProperty("type", "BoundVariable"); 1096 jsvar.AddProperty("type", "BoundVariable");
1105 var_name = String::ScrubName(var_name); 1097 var_name = String::ScrubName(var_name);
1106 jsvar.AddProperty("name", var_name.ToCString()); 1098 jsvar.AddProperty("name", var_name.ToCString());
1107 jsvar.AddProperty("value", var_value, !full); 1099 jsvar.AddProperty("value", var_value, !full);
1108 // Where was the variable declared? 1100 // Where was the variable declared?
1109 jsvar.AddProperty("declarationTokenPos", declaration_token_pos); 1101 jsvar.AddProperty("declarationTokenPos", declaration_token_pos);
1110 // When the variable becomes visible to the scope. 1102 // When the variable becomes visible to the scope.
1111 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos); 1103 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos);
1112 // When the variable stops being visible to the scope. 1104 // When the variable stops being visible to the scope.
1113 jsvar.AddProperty("scopeEndTokenPos", visible_end_token_pos); 1105 jsvar.AddProperty("scopeEndTokenPos", visible_end_token_pos);
1114 } 1106 }
1115 } 1107 }
1116 } 1108 }
1117 } 1109 }
1118 1110
1119 1111
1120
1121 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { 1112 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
1122 if (FLAG_show_invisible_frames || frame->function().is_visible()) { 1113 if (FLAG_show_invisible_frames || frame->function().is_visible()) {
1123 trace_.Add(frame); 1114 trace_.Add(frame);
1124 } 1115 }
1125 } 1116 }
1126 1117
1127 1118
1128 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall 1119 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
1129 | RawPcDescriptors::kUnoptStaticCall 1120 RawPcDescriptors::kUnoptStaticCall |
1130 | RawPcDescriptors::kRuntimeCall; 1121 RawPcDescriptors::kRuntimeCall;
1131 1122
1132 1123
1133 CodeBreakpoint::CodeBreakpoint(const Code& code, 1124 CodeBreakpoint::CodeBreakpoint(const Code& code,
1134 TokenPosition token_pos, 1125 TokenPosition token_pos,
1135 uword pc, 1126 uword pc,
1136 RawPcDescriptors::Kind kind) 1127 RawPcDescriptors::Kind kind)
1137 : code_(code.raw()), 1128 : code_(code.raw()),
1138 token_pos_(token_pos), 1129 token_pos_(token_pos),
1139 pc_(pc), 1130 pc_(pc),
1140 line_number_(-1), 1131 line_number_(-1),
1141 is_enabled_(false), 1132 is_enabled_(false),
1142 bpt_location_(NULL), 1133 bpt_location_(NULL),
1143 next_(NULL), 1134 next_(NULL),
1144 breakpoint_kind_(kind), 1135 breakpoint_kind_(kind),
1145 #if !defined(TARGET_ARCH_DBC) 1136 #if !defined(TARGET_ARCH_DBC)
1146 saved_value_(Code::null()) 1137 saved_value_(Code::null())
1147 #else 1138 #else
1148 saved_value_(Bytecode::kTrap), 1139 saved_value_(Bytecode::kTrap),
1149 saved_value_fastsmi_(Bytecode::kTrap) 1140 saved_value_fastsmi_(Bytecode::kTrap)
1150 #endif 1141 #endif
1151 { 1142 {
1152 ASSERT(!code.IsNull()); 1143 ASSERT(!code.IsNull());
1153 ASSERT(token_pos_.IsReal()); 1144 ASSERT(token_pos_.IsReal());
1154 ASSERT(pc_ != 0); 1145 ASSERT(pc_ != 0);
1155 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); 1146 ASSERT((breakpoint_kind_ & kSafepointKind) != 0);
1156 } 1147 }
1157 1148
1158 1149
1159 CodeBreakpoint::~CodeBreakpoint() { 1150 CodeBreakpoint::~CodeBreakpoint() {
1160 // Make sure we don't leave patched code behind. 1151 // Make sure we don't leave patched code behind.
1161 ASSERT(!IsEnabled()); 1152 ASSERT(!IsEnabled());
1162 // Poison the data so we catch use after free errors. 1153 // Poison the data so we catch use after free errors.
1163 #ifdef DEBUG 1154 #ifdef DEBUG
1164 code_ = Code::null(); 1155 code_ = Code::null();
1165 pc_ = 0ul; 1156 pc_ = 0ul;
1166 bpt_location_ = NULL; 1157 bpt_location_ = NULL;
1167 next_ = NULL; 1158 next_ = NULL;
1168 breakpoint_kind_ = RawPcDescriptors::kOther; 1159 breakpoint_kind_ = RawPcDescriptors::kOther;
1169 #endif 1160 #endif
1170 } 1161 }
1171 1162
1172 1163
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 1198
1208 void CodeBreakpoint::Disable() { 1199 void CodeBreakpoint::Disable() {
1209 if (is_enabled_) { 1200 if (is_enabled_) {
1210 RestoreCode(); 1201 RestoreCode();
1211 } 1202 }
1212 ASSERT(!is_enabled_); 1203 ASSERT(!is_enabled_);
1213 } 1204 }
1214 1205
1215 1206
1216 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) { 1207 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) {
1217 objs_ = &GrowableObjectArray::ZoneHandle( 1208 objs_ =
1218 GrowableObjectArray::New(initial_size)); 1209 &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New(initial_size));
1219 } 1210 }
1220 1211
1221 1212
1222 intptr_t RemoteObjectCache::AddObject(const Object& obj) { 1213 intptr_t RemoteObjectCache::AddObject(const Object& obj) {
1223 intptr_t len = objs_->Length(); 1214 intptr_t len = objs_->Length();
1224 for (intptr_t i = 0; i < len; i++) { 1215 for (intptr_t i = 0; i < len; i++) {
1225 if (objs_->At(i) == obj.raw()) { 1216 if (objs_->At(i) == obj.raw()) {
1226 return i; 1217 return i;
1227 } 1218 }
1228 } 1219 }
(...skipping 17 matching lines...) Expand all
1246 breakpoint_locations_(NULL), 1237 breakpoint_locations_(NULL),
1247 code_breakpoints_(NULL), 1238 code_breakpoints_(NULL),
1248 resume_action_(kContinue), 1239 resume_action_(kContinue),
1249 ignore_breakpoints_(false), 1240 ignore_breakpoints_(false),
1250 pause_event_(NULL), 1241 pause_event_(NULL),
1251 obj_cache_(NULL), 1242 obj_cache_(NULL),
1252 stack_trace_(NULL), 1243 stack_trace_(NULL),
1253 stepping_fp_(0), 1244 stepping_fp_(0),
1254 skip_next_step_(false), 1245 skip_next_step_(false),
1255 synthetic_async_breakpoint_(NULL), 1246 synthetic_async_breakpoint_(NULL),
1256 exc_pause_info_(kNoPauseOnExceptions) { 1247 exc_pause_info_(kNoPauseOnExceptions) {}
1257 }
1258 1248
1259 1249
1260 Debugger::~Debugger() { 1250 Debugger::~Debugger() {
1261 isolate_id_ = ILLEGAL_ISOLATE_ID; 1251 isolate_id_ = ILLEGAL_ISOLATE_ID;
1262 ASSERT(!IsPaused()); 1252 ASSERT(!IsPaused());
1263 ASSERT(latent_locations_ == NULL); 1253 ASSERT(latent_locations_ == NULL);
1264 ASSERT(breakpoint_locations_ == NULL); 1254 ASSERT(breakpoint_locations_ == NULL);
1265 ASSERT(code_breakpoints_ == NULL); 1255 ASSERT(code_breakpoints_ == NULL);
1266 ASSERT(stack_trace_ == NULL); 1256 ASSERT(stack_trace_ == NULL);
1267 ASSERT(obj_cache_ == NULL); 1257 ASSERT(obj_cache_ == NULL);
(...skipping 24 matching lines...) Expand all
1292 bpt->Disable(); 1282 bpt->Disable();
1293 delete bpt; 1283 delete bpt;
1294 } 1284 }
1295 if (NeedsIsolateEvents()) { 1285 if (NeedsIsolateEvents()) {
1296 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit); 1286 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
1297 InvokeEventHandler(&event); 1287 InvokeEventHandler(&event);
1298 } 1288 }
1299 } 1289 }
1300 1290
1301 1291
1302 static RawFunction* ResolveLibraryFunction( 1292 static RawFunction* ResolveLibraryFunction(const Library& library,
1303 const Library& library, 1293 const String& fname) {
1304 const String& fname) {
1305 ASSERT(!library.IsNull()); 1294 ASSERT(!library.IsNull());
1306 const Object& object = Object::Handle(library.ResolveName(fname)); 1295 const Object& object = Object::Handle(library.ResolveName(fname));
1307 if (!object.IsNull() && object.IsFunction()) { 1296 if (!object.IsNull() && object.IsFunction()) {
1308 return Function::Cast(object).raw(); 1297 return Function::Cast(object).raw();
1309 } 1298 }
1310 return Function::null(); 1299 return Function::null();
1311 } 1300 }
1312 1301
1313 1302
1314 bool Debugger::SetupStepOverAsyncSuspension() { 1303 bool Debugger::SetupStepOverAsyncSuspension() {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 } 1409 }
1421 1410
1422 1411
1423 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1412 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1424 uword pc, 1413 uword pc,
1425 StackFrame* frame, 1414 StackFrame* frame,
1426 const Code& code, 1415 const Code& code,
1427 const Array& deopt_frame, 1416 const Array& deopt_frame,
1428 intptr_t deopt_frame_offset) { 1417 intptr_t deopt_frame_offset) {
1429 ASSERT(code.ContainsInstructionAt(pc)); 1418 ASSERT(code.ContainsInstructionAt(pc));
1430 ActivationFrame* activation = 1419 ActivationFrame* activation = new ActivationFrame(
1431 new ActivationFrame(pc, frame->fp(), frame->sp(), code, 1420 pc, frame->fp(), frame->sp(), code, deopt_frame, deopt_frame_offset);
1432 deopt_frame, deopt_frame_offset);
1433 if (FLAG_trace_debugger_stacktrace) { 1421 if (FLAG_trace_debugger_stacktrace) {
1434 const Context& ctx = activation->GetSavedCurrentContext(); 1422 const Context& ctx = activation->GetSavedCurrentContext();
1435 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); 1423 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString());
1436 } 1424 }
1437 if (FLAG_trace_debugger_stacktrace) { 1425 if (FLAG_trace_debugger_stacktrace) {
1438 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); 1426 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
1439 } 1427 }
1440 return activation; 1428 return activation;
1441 } 1429 }
1442 1430
1443 1431
1444 RawArray* Debugger::DeoptimizeToArray(Thread* thread, 1432 RawArray* Debugger::DeoptimizeToArray(Thread* thread,
1445 StackFrame* frame, 1433 StackFrame* frame,
1446 const Code& code) { 1434 const Code& code) {
1447 ASSERT(code.is_optimized()); 1435 ASSERT(code.is_optimized());
1448 Isolate* isolate = thread->isolate(); 1436 Isolate* isolate = thread->isolate();
1449 // Create the DeoptContext for this deoptimization. 1437 // Create the DeoptContext for this deoptimization.
1450 DeoptContext* deopt_context = 1438 DeoptContext* deopt_context =
1451 new DeoptContext(frame, code, 1439 new DeoptContext(frame, code, DeoptContext::kDestIsAllocated, NULL, NULL,
1452 DeoptContext::kDestIsAllocated, 1440 true, false /* deoptimizing_code */);
1453 NULL,
1454 NULL,
1455 true,
1456 false /* deoptimizing_code */);
1457 isolate->set_deopt_context(deopt_context); 1441 isolate->set_deopt_context(deopt_context);
1458 1442
1459 deopt_context->FillDestFrame(); 1443 deopt_context->FillDestFrame();
1460 deopt_context->MaterializeDeferredObjects(); 1444 deopt_context->MaterializeDeferredObjects();
1461 const Array& dest_frame = Array::Handle(thread->zone(), 1445 const Array& dest_frame =
1462 deopt_context->DestFrameAsArray()); 1446 Array::Handle(thread->zone(), deopt_context->DestFrameAsArray());
1463 1447
1464 isolate->set_deopt_context(NULL); 1448 isolate->set_deopt_context(NULL);
1465 delete deopt_context; 1449 delete deopt_context;
1466 1450
1467 return dest_frame.raw(); 1451 return dest_frame.raw();
1468 } 1452 }
1469 1453
1470 1454
1471 DebuggerStackTrace* Debugger::CollectStackTrace() { 1455 DebuggerStackTrace* Debugger::CollectStackTrace() {
1472 Thread* thread = Thread::Current(); 1456 Thread* thread = Thread::Current();
1473 Zone* zone = thread->zone(); 1457 Zone* zone = thread->zone();
1474 Isolate* isolate = thread->isolate(); 1458 Isolate* isolate = thread->isolate();
1475 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1459 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1476 StackFrameIterator iterator(false); 1460 StackFrameIterator iterator(false);
1477 Code& code = Code::Handle(zone); 1461 Code& code = Code::Handle(zone);
1478 Code& inlined_code = Code::Handle(zone); 1462 Code& inlined_code = Code::Handle(zone);
1479 Array& deopt_frame = Array::Handle(zone); 1463 Array& deopt_frame = Array::Handle(zone);
1480 1464
1481 for (StackFrame* frame = iterator.NextFrame(); 1465 for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
1482 frame != NULL;
1483 frame = iterator.NextFrame()) { 1466 frame = iterator.NextFrame()) {
1484 ASSERT(frame->IsValid()); 1467 ASSERT(frame->IsValid());
1485 if (FLAG_trace_debugger_stacktrace) { 1468 if (FLAG_trace_debugger_stacktrace) {
1486 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n", 1469 OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
1487 frame->ToCString()); 1470 frame->ToCString());
1488 } 1471 }
1489 if (frame->IsDartFrame()) { 1472 if (frame->IsDartFrame()) {
1490 code = frame->LookupDartCode(); 1473 code = frame->LookupDartCode();
1491 if (code.is_optimized() && !FLAG_precompiled_runtime) { 1474 if (code.is_optimized() && !FLAG_precompiled_runtime) {
1492 deopt_frame = DeoptimizeToArray(thread, frame, code); 1475 deopt_frame = DeoptimizeToArray(thread, frame, code);
1493 for (InlinedFunctionsIterator it(code, frame->pc()); 1476 for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
1494 !it.Done();
1495 it.Advance()) { 1477 it.Advance()) {
1496 inlined_code = it.code(); 1478 inlined_code = it.code();
1497 if (FLAG_trace_debugger_stacktrace) { 1479 if (FLAG_trace_debugger_stacktrace) {
1498 const Function& function = 1480 const Function& function =
1499 Function::Handle(zone, inlined_code.function()); 1481 Function::Handle(zone, inlined_code.function());
1500 ASSERT(!function.IsNull()); 1482 ASSERT(!function.IsNull());
1501 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n", 1483 OS::PrintErr("CollectStackTrace: visiting inlined function: %s\n",
1502 function.ToFullyQualifiedCString()); 1484 function.ToFullyQualifiedCString());
1503 } 1485 }
1504 intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); 1486 intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
1505 stack_trace->AddActivation(CollectDartFrame(isolate, 1487 stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame,
1506 it.pc(), 1488 inlined_code, deopt_frame,
1507 frame,
1508 inlined_code,
1509 deopt_frame,
1510 deopt_frame_offset)); 1489 deopt_frame_offset));
1511 } 1490 }
1512 } else { 1491 } else {
1513 stack_trace->AddActivation(CollectDartFrame(isolate, 1492 stack_trace->AddActivation(CollectDartFrame(
1514 frame->pc(), 1493 isolate, frame->pc(), frame, code, Object::null_array(), 0));
1515 frame,
1516 code,
1517 Object::null_array(),
1518 0));
1519 } 1494 }
1520 } 1495 }
1521 } 1496 }
1522 return stack_trace; 1497 return stack_trace;
1523 } 1498 }
1524 1499
1525 1500
1526 ActivationFrame* Debugger::TopDartFrame() const { 1501 ActivationFrame* Debugger::TopDartFrame() const {
1527 StackFrameIterator iterator(false); 1502 StackFrameIterator iterator(false);
1528 StackFrame* frame = iterator.NextFrame(); 1503 StackFrame* frame = iterator.NextFrame();
1529 while ((frame != NULL) && !frame->IsDartFrame()) { 1504 while ((frame != NULL) && !frame->IsDartFrame()) {
1530 frame = iterator.NextFrame(); 1505 frame = iterator.NextFrame();
1531 } 1506 }
1532 Code& code = Code::Handle(frame->LookupDartCode()); 1507 Code& code = Code::Handle(frame->LookupDartCode());
1533 ActivationFrame* activation = 1508 ActivationFrame* activation = new ActivationFrame(
1534 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, 1509 frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0);
1535 Object::null_array(), 0);
1536 return activation; 1510 return activation;
1537 } 1511 }
1538 1512
1539 1513
1540 DebuggerStackTrace* Debugger::StackTrace() { 1514 DebuggerStackTrace* Debugger::StackTrace() {
1541 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); 1515 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace();
1542 } 1516 }
1543 1517
1544 DebuggerStackTrace* Debugger::CurrentStackTrace() { 1518 DebuggerStackTrace* Debugger::CurrentStackTrace() {
1545 return CollectStackTrace(); 1519 return CollectStackTrace();
(...skipping 25 matching lines...) Expand all
1571 for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) { 1545 for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) {
1572 function = it.function(); 1546 function = it.function();
1573 code = it.code(); 1547 code = it.code();
1574 ASSERT(function.raw() == code.function()); 1548 ASSERT(function.raw() == code.function());
1575 uword pc = it.pc(); 1549 uword pc = it.pc();
1576 ASSERT(pc != 0); 1550 ASSERT(pc != 0);
1577 ASSERT(code.PayloadStart() <= pc); 1551 ASSERT(code.PayloadStart() <= pc);
1578 ASSERT(pc < (code.PayloadStart() + code.Size())); 1552 ASSERT(pc < (code.PayloadStart() + code.Size()));
1579 1553
1580 ActivationFrame* activation = new ActivationFrame( 1554 ActivationFrame* activation = new ActivationFrame(
1581 pc, fp, sp, code, deopt_frame, deopt_frame_offset); 1555 pc, fp, sp, code, deopt_frame, deopt_frame_offset);
1582 stack_trace->AddActivation(activation); 1556 stack_trace->AddActivation(activation);
1583 } 1557 }
1584 } else { 1558 } else {
1585 ActivationFrame* activation = new ActivationFrame( 1559 ActivationFrame* activation = new ActivationFrame(
1586 pc, fp, sp, code, deopt_frame, deopt_frame_offset); 1560 pc, fp, sp, code, deopt_frame, deopt_frame_offset);
1587 stack_trace->AddActivation(activation); 1561 stack_trace->AddActivation(activation);
1588 } 1562 }
1589 } 1563 }
1590 } 1564 }
1591 return stack_trace; 1565 return stack_trace;
1592 } 1566 }
1593 1567
1594 1568
1595 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) { 1569 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) {
1596 ASSERT((pause_info == kNoPauseOnExceptions) || 1570 ASSERT((pause_info == kNoPauseOnExceptions) ||
(...skipping 28 matching lines...) Expand all
1625 } 1599 }
1626 return false; 1600 return false;
1627 } 1601 }
1628 1602
1629 1603
1630 void Debugger::PauseException(const Instance& exc) { 1604 void Debugger::PauseException(const Instance& exc) {
1631 // We ignore this exception event when the VM is executing code invoked 1605 // We ignore this exception event when the VM is executing code invoked
1632 // by the debugger to evaluate variables values, when we see a nested 1606 // by the debugger to evaluate variables values, when we see a nested
1633 // breakpoint or exception event, or if the debugger is not 1607 // breakpoint or exception event, or if the debugger is not
1634 // interested in exception events. 1608 // interested in exception events.
1635 if (ignore_breakpoints_ || 1609 if (ignore_breakpoints_ || IsPaused() ||
1636 IsPaused() ||
1637 (exc_pause_info_ == kNoPauseOnExceptions)) { 1610 (exc_pause_info_ == kNoPauseOnExceptions)) {
1638 return; 1611 return;
1639 } 1612 }
1640 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1613 DebuggerStackTrace* stack_trace = CollectStackTrace();
1641 if (!ShouldPauseOnException(stack_trace, exc)) { 1614 if (!ShouldPauseOnException(stack_trace, exc)) {
1642 return; 1615 return;
1643 } 1616 }
1644 ServiceEvent event(isolate_, ServiceEvent::kPauseException); 1617 ServiceEvent event(isolate_, ServiceEvent::kPauseException);
1645 event.set_exception(&exc); 1618 event.set_exception(&exc);
1646 if (stack_trace->Length() > 0) { 1619 if (stack_trace->Length() > 0) {
1647 event.set_top_frame(stack_trace->FrameAt(0)); 1620 event.set_top_frame(stack_trace->FrameAt(0));
1648 } 1621 }
1649 ASSERT(stack_trace_ == NULL); 1622 ASSERT(stack_trace_ == NULL);
1650 stack_trace_ = stack_trace; 1623 stack_trace_ = stack_trace;
1651 Pause(&event); 1624 Pause(&event);
1652 stack_trace_ = NULL; 1625 stack_trace_ = NULL;
1653 } 1626 }
1654 1627
1655 1628
1656 static TokenPosition LastTokenOnLine(Zone* zone, 1629 static TokenPosition LastTokenOnLine(Zone* zone,
1657 const TokenStream& tokens, 1630 const TokenStream& tokens,
1658 TokenPosition pos) { 1631 TokenPosition pos) {
1659 TokenStream::Iterator iter(zone, 1632 TokenStream::Iterator iter(zone, tokens, pos,
1660 tokens,
1661 pos,
1662 TokenStream::Iterator::kAllTokens); 1633 TokenStream::Iterator::kAllTokens);
1663 ASSERT(iter.IsValid()); 1634 ASSERT(iter.IsValid());
1664 TokenPosition last_pos = pos; 1635 TokenPosition last_pos = pos;
1665 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && 1636 while ((iter.CurrentTokenKind() != Token::kNEWLINE) &&
1666 (iter.CurrentTokenKind() != Token::kEOS)) { 1637 (iter.CurrentTokenKind() != Token::kEOS)) {
1667 last_pos = iter.CurrentPosition(); 1638 last_pos = iter.CurrentPosition();
1668 iter.Advance(); 1639 iter.Advance();
1669 } 1640 }
1670 return last_pos; 1641 return last_pos;
1671 } 1642 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 // 1691 //
1721 // If no best fit token can be found, the search is expanded, 1692 // If no best fit token can be found, the search is expanded,
1722 // searching through the rest of the current function by calling this 1693 // searching through the rest of the current function by calling this
1723 // function recursively. 1694 // function recursively.
1724 // 1695 //
1725 // TODO(turnidge): Given that we usually call this function with a 1696 // TODO(turnidge): Given that we usually call this function with a
1726 // token range restricted to a single line, this could be a one-pass 1697 // token range restricted to a single line, this could be a one-pass
1727 // algorithm, which would be simpler. I believe that it only needs 1698 // algorithm, which would be simpler. I believe that it only needs
1728 // two passes to support the recursive try-the-whole-function case. 1699 // two passes to support the recursive try-the-whole-function case.
1729 // Rewrite this later, once there are more tests in place. 1700 // Rewrite this later, once there are more tests in place.
1730 TokenPosition Debugger::ResolveBreakpointPos( 1701 TokenPosition Debugger::ResolveBreakpointPos(const Function& func,
1731 const Function& func, 1702 TokenPosition requested_token_pos,
1732 TokenPosition requested_token_pos, 1703 TokenPosition last_token_pos,
1733 TokenPosition last_token_pos, 1704 intptr_t requested_column) {
1734 intptr_t requested_column) {
1735 ASSERT(func.HasCode()); 1705 ASSERT(func.HasCode());
1736 ASSERT(!func.HasOptimizedCode()); 1706 ASSERT(!func.HasOptimizedCode());
1737 1707
1738 if (requested_token_pos < func.token_pos()) { 1708 if (requested_token_pos < func.token_pos()) {
1739 requested_token_pos = func.token_pos(); 1709 requested_token_pos = func.token_pos();
1740 } 1710 }
1741 if (last_token_pos > func.end_token_pos()) { 1711 if (last_token_pos > func.end_token_pos()) {
1742 last_token_pos = func.end_token_pos(); 1712 last_token_pos = func.end_token_pos();
1743 } 1713 }
1744 1714
1745 Zone* zone = Thread::Current()->zone(); 1715 Zone* zone = Thread::Current()->zone();
1746 Script& script = Script::Handle(zone, func.script()); 1716 Script& script = Script::Handle(zone, func.script());
1747 Code& code = Code::Handle(zone, func.unoptimized_code()); 1717 Code& code = Code::Handle(zone, func.unoptimized_code());
1748 ASSERT(!code.IsNull()); 1718 ASSERT(!code.IsNull());
1749 PcDescriptors& desc = PcDescriptors::Handle(zone, code.pc_descriptors()); 1719 PcDescriptors& desc = PcDescriptors::Handle(zone, code.pc_descriptors());
1750 1720
1751 // First pass: find the safe point which is closest to the beginning 1721 // First pass: find the safe point which is closest to the beginning
1752 // of the given token range. 1722 // of the given token range.
1753 TokenPosition best_fit_pos = TokenPosition::kMaxSource; 1723 TokenPosition best_fit_pos = TokenPosition::kMaxSource;
1754 intptr_t best_column = INT_MAX; 1724 intptr_t best_column = INT_MAX;
1755 PcDescriptors::Iterator iter(desc, kSafepointKind); 1725 PcDescriptors::Iterator iter(desc, kSafepointKind);
1756 while (iter.MoveNext()) { 1726 while (iter.MoveNext()) {
1757 const TokenPosition pos = iter.TokenPos(); 1727 const TokenPosition pos = iter.TokenPos();
1758 if ((!pos.IsReal()) || 1728 if ((!pos.IsReal()) || (pos < requested_token_pos) ||
1759 (pos < requested_token_pos) ||
1760 (pos > last_token_pos)) { 1729 (pos > last_token_pos)) {
1761 // Token is not in the target range. 1730 // Token is not in the target range.
1762 continue; 1731 continue;
1763 } 1732 }
1764 1733
1765 intptr_t token_start_column = -1; 1734 intptr_t token_start_column = -1;
1766 if (requested_column >= 0) { 1735 if (requested_column >= 0) {
1767 intptr_t ignored = -1; 1736 intptr_t ignored = -1;
1768 intptr_t token_len = -1; 1737 intptr_t token_len = -1;
1769 // TODO(turnidge): GetTokenLocation is a very expensive 1738 // TODO(turnidge): GetTokenLocation is a very expensive
(...skipping 25 matching lines...) Expand all
1795 if (best_fit_pos != TokenPosition::kMaxSource) { 1764 if (best_fit_pos != TokenPosition::kMaxSource) {
1796 const Script& script = Script::Handle(zone, func.script()); 1765 const Script& script = Script::Handle(zone, func.script());
1797 const TokenStream& tokens = TokenStream::Handle(zone, script.tokens()); 1766 const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
1798 const TokenPosition begin_pos = best_fit_pos; 1767 const TokenPosition begin_pos = best_fit_pos;
1799 const TokenPosition end_of_line_pos = 1768 const TokenPosition end_of_line_pos =
1800 LastTokenOnLine(zone, tokens, begin_pos); 1769 LastTokenOnLine(zone, tokens, begin_pos);
1801 uword lowest_pc_offset = kUwordMax; 1770 uword lowest_pc_offset = kUwordMax;
1802 PcDescriptors::Iterator iter(desc, kSafepointKind); 1771 PcDescriptors::Iterator iter(desc, kSafepointKind);
1803 while (iter.MoveNext()) { 1772 while (iter.MoveNext()) {
1804 const TokenPosition pos = iter.TokenPos(); 1773 const TokenPosition pos = iter.TokenPos();
1805 if (!pos.IsReal() || 1774 if (!pos.IsReal() || (pos < begin_pos) || (pos > end_of_line_pos)) {
1806 (pos < begin_pos) ||
1807 (pos > end_of_line_pos)) {
1808 // Token is not on same line as best fit. 1775 // Token is not on same line as best fit.
1809 continue; 1776 continue;
1810 } 1777 }
1811 1778
1812 if (requested_column >= 0) { 1779 if (requested_column >= 0) {
1813 intptr_t ignored = -1; 1780 intptr_t ignored = -1;
1814 intptr_t token_start_column = -1; 1781 intptr_t token_start_column = -1;
1815 // We look for other tokens at the best column in case there 1782 // We look for other tokens at the best column in case there
1816 // is more than one token at the same column offset. 1783 // is more than one token at the same column offset.
1817 script.GetTokenLocation(pos, &ignored, &token_start_column); 1784 script.GetTokenLocation(pos, &ignored, &token_start_column);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 } 1829 }
1863 } 1830 }
1864 } 1831 }
1865 if (lowest_pc_offset == kUwordMax) { 1832 if (lowest_pc_offset == kUwordMax) {
1866 return; 1833 return;
1867 } 1834 }
1868 uword lowest_pc = code.PayloadStart() + lowest_pc_offset; 1835 uword lowest_pc = code.PayloadStart() + lowest_pc_offset;
1869 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc); 1836 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
1870 if (code_bpt == NULL) { 1837 if (code_bpt == NULL) {
1871 // No code breakpoint for this code exists; create one. 1838 // No code breakpoint for this code exists; create one.
1872 code_bpt = new CodeBreakpoint(code, loc->token_pos_, 1839 code_bpt =
1873 lowest_pc, lowest_kind); 1840 new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind);
1874 RegisterCodeBreakpoint(code_bpt); 1841 RegisterCodeBreakpoint(code_bpt);
1875 } 1842 }
1876 code_bpt->set_bpt_location(loc); 1843 code_bpt->set_bpt_location(loc);
1877 if (loc->AnyEnabled()) { 1844 if (loc->AnyEnabled()) {
1878 code_bpt->Enable(); 1845 code_bpt->Enable();
1879 } 1846 }
1880 } 1847 }
1881 1848
1882 1849
1883 void Debugger::FindCompiledFunctions(const Script& script, 1850 void Debugger::FindCompiledFunctions(const Script& script,
1884 TokenPosition start_pos, 1851 TokenPosition start_pos,
1885 TokenPosition end_pos, 1852 TokenPosition end_pos,
1886 GrowableObjectArray* function_list) { 1853 GrowableObjectArray* function_list) {
1887 Zone* zone = Thread::Current()->zone(); 1854 Zone* zone = Thread::Current()->zone();
1888 Class& cls = Class::Handle(zone); 1855 Class& cls = Class::Handle(zone);
1889 Array& functions = Array::Handle(zone); 1856 Array& functions = Array::Handle(zone);
1890 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); 1857 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
1891 Function& function = Function::Handle(zone); 1858 Function& function = Function::Handle(zone);
1892 1859
1893 closures = isolate_->object_store()->closure_functions(); 1860 closures = isolate_->object_store()->closure_functions();
1894 const intptr_t num_closures = closures.Length(); 1861 const intptr_t num_closures = closures.Length();
1895 for (intptr_t pos = 0; pos < num_closures; pos++) { 1862 for (intptr_t pos = 0; pos < num_closures; pos++) {
1896 function ^= closures.At(pos); 1863 function ^= closures.At(pos);
1897 ASSERT(!function.IsNull()); 1864 ASSERT(!function.IsNull());
1898 if ((function.token_pos() == start_pos) 1865 if ((function.token_pos() == start_pos) &&
1899 && (function.end_token_pos() == end_pos) 1866 (function.end_token_pos() == end_pos) &&
1900 && (function.script() == script.raw())) { 1867 (function.script() == script.raw())) {
1901 if (function.HasCode() && function.is_debuggable()) { 1868 if (function.HasCode() && function.is_debuggable()) {
1902 function_list->Add(function); 1869 function_list->Add(function);
1903 } 1870 }
1904 if (function.HasImplicitClosureFunction()) { 1871 if (function.HasImplicitClosureFunction()) {
1905 function = function.ImplicitClosureFunction(); 1872 function = function.ImplicitClosureFunction();
1906 if (function.HasCode() && function.is_debuggable()) { 1873 if (function.HasCode() && function.is_debuggable()) {
1907 function_list->Add(function); 1874 function_list->Add(function);
1908 } 1875 }
1909 } 1876 }
1910 } 1877 }
(...skipping 15 matching lines...) Expand all
1926 // the class is defined in a differenct 'script'. There could 1893 // the class is defined in a differenct 'script'. There could
1927 // be mixin functions from the given script in this class. 1894 // be mixin functions from the given script in this class.
1928 functions = cls.functions(); 1895 functions = cls.functions();
1929 if (!functions.IsNull()) { 1896 if (!functions.IsNull()) {
1930 const intptr_t num_functions = functions.Length(); 1897 const intptr_t num_functions = functions.Length();
1931 for (intptr_t pos = 0; pos < num_functions; pos++) { 1898 for (intptr_t pos = 0; pos < num_functions; pos++) {
1932 function ^= functions.At(pos); 1899 function ^= functions.At(pos);
1933 ASSERT(!function.IsNull()); 1900 ASSERT(!function.IsNull());
1934 // Check token position first to avoid unnecessary calls 1901 // Check token position first to avoid unnecessary calls
1935 // to script() which allocates handles. 1902 // to script() which allocates handles.
1936 if ((function.token_pos() == start_pos) 1903 if ((function.token_pos() == start_pos) &&
1937 && (function.end_token_pos() == end_pos) 1904 (function.end_token_pos() == end_pos) &&
1938 && (function.script() == script.raw())) { 1905 (function.script() == script.raw())) {
1939 if (function.HasCode() && function.is_debuggable()) { 1906 if (function.HasCode() && function.is_debuggable()) {
1940 function_list->Add(function); 1907 function_list->Add(function);
1941 } 1908 }
1942 if (function.HasImplicitClosureFunction()) { 1909 if (function.HasImplicitClosureFunction()) {
1943 function = function.ImplicitClosureFunction(); 1910 function = function.ImplicitClosureFunction();
1944 if (function.HasCode() && function.is_debuggable()) { 1911 if (function.HasCode() && function.is_debuggable()) {
1945 function_list->Add(function); 1912 function_list->Add(function);
1946 } 1913 }
1947 } 1914 }
1948 } 1915 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 if (func.IsNull()) { 2001 if (func.IsNull()) {
2035 return NULL; 2002 return NULL;
2036 } 2003 }
2037 // There may be more than one function object for a given function 2004 // There may be more than one function object for a given function
2038 // in source code. There may be implicit closure functions, and 2005 // in source code. There may be implicit closure functions, and
2039 // there may be copies of mixin functions. Collect all compiled 2006 // there may be copies of mixin functions. Collect all compiled
2040 // functions whose source code range matches exactly the best fit 2007 // functions whose source code range matches exactly the best fit
2041 // function we found. 2008 // function we found.
2042 GrowableObjectArray& functions = 2009 GrowableObjectArray& functions =
2043 GrowableObjectArray::Handle(GrowableObjectArray::New()); 2010 GrowableObjectArray::Handle(GrowableObjectArray::New());
2044 FindCompiledFunctions(script, 2011 FindCompiledFunctions(script, func.token_pos(), func.end_token_pos(),
2045 func.token_pos(),
2046 func.end_token_pos(),
2047 &functions); 2012 &functions);
2048 2013
2049 if (functions.Length() > 0) { 2014 if (functions.Length() > 0) {
2050 // One or more function object containing this breakpoint location 2015 // One or more function object containing this breakpoint location
2051 // have already been compiled. We can resolve the breakpoint now. 2016 // have already been compiled. We can resolve the breakpoint now.
2052 DeoptimizeWorld(); 2017 DeoptimizeWorld();
2053 func ^= functions.At(0); 2018 func ^= functions.At(0);
2054 TokenPosition breakpoint_pos = 2019 TokenPosition breakpoint_pos =
2055 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column); 2020 ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column);
2056 if (breakpoint_pos.IsReal()) { 2021 if (breakpoint_pos.IsReal()) {
(...skipping 12 matching lines...) Expand all
2069 const intptr_t num_functions = functions.Length(); 2034 const intptr_t num_functions = functions.Length();
2070 for (intptr_t i = 0; i < num_functions; i++) { 2035 for (intptr_t i = 0; i < num_functions; i++) {
2071 func ^= functions.At(i); 2036 func ^= functions.At(i);
2072 ASSERT(func.HasCode()); 2037 ASSERT(func.HasCode());
2073 MakeCodeBreakpointAt(func, bpt); 2038 MakeCodeBreakpointAt(func, bpt);
2074 } 2039 }
2075 if (FLAG_verbose_debug) { 2040 if (FLAG_verbose_debug) {
2076 intptr_t line_number; 2041 intptr_t line_number;
2077 intptr_t column_number; 2042 intptr_t column_number;
2078 script.GetTokenLocation(breakpoint_pos, &line_number, &column_number); 2043 script.GetTokenLocation(breakpoint_pos, &line_number, &column_number);
2079 OS::Print("Resolved BP for " 2044 OS::Print(
2080 "function '%s' at line %" Pd " col %" Pd "\n", 2045 "Resolved BP for "
2081 func.ToFullyQualifiedCString(), 2046 "function '%s' at line %" Pd " col %" Pd "\n",
2082 line_number, column_number); 2047 func.ToFullyQualifiedCString(), line_number, column_number);
2083 } 2048 }
2084 return bpt; 2049 return bpt;
2085 } 2050 }
2086 } 2051 }
2087 // There is no compiled function at this token position. 2052 // There is no compiled function at this token position.
2088 // Register an unresolved breakpoint. 2053 // Register an unresolved breakpoint.
2089 if (FLAG_verbose_debug && !func.IsNull()) { 2054 if (FLAG_verbose_debug && !func.IsNull()) {
2090 intptr_t line_number; 2055 intptr_t line_number;
2091 intptr_t column_number; 2056 intptr_t column_number;
2092 script.GetTokenLocation(token_pos, &line_number, &column_number); 2057 script.GetTokenLocation(token_pos, &line_number, &column_number);
2093 OS::Print("Registering pending breakpoint for " 2058 OS::Print(
2094 "uncompiled function '%s' at line %" Pd " col %" Pd "\n", 2059 "Registering pending breakpoint for "
2095 func.ToFullyQualifiedCString(), 2060 "uncompiled function '%s' at line %" Pd " col %" Pd "\n",
2096 line_number, column_number); 2061 func.ToFullyQualifiedCString(), line_number, column_number);
2097 } 2062 }
2098 BreakpointLocation* bpt = 2063 BreakpointLocation* bpt =
2099 GetBreakpointLocation(script, token_pos, requested_column); 2064 GetBreakpointLocation(script, token_pos, requested_column);
2100 if (bpt == NULL) { 2065 if (bpt == NULL) {
2101 bpt = new BreakpointLocation(script, token_pos, last_token_pos, 2066 bpt = new BreakpointLocation(script, token_pos, last_token_pos,
2102 requested_line, requested_column); 2067 requested_line, requested_column);
2103 RegisterBreakpointLocation(bpt); 2068 RegisterBreakpointLocation(bpt);
2104 } 2069 }
2105 return bpt; 2070 return bpt;
2106 } 2071 }
(...skipping 29 matching lines...) Expand all
2136 } 2101 }
2137 2102
2138 2103
2139 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function, 2104 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
2140 bool single_shot) { 2105 bool single_shot) {
2141 ASSERT(!target_function.IsNull()); 2106 ASSERT(!target_function.IsNull());
2142 if (!target_function.is_debuggable()) { 2107 if (!target_function.is_debuggable()) {
2143 return NULL; 2108 return NULL;
2144 } 2109 }
2145 const Script& script = Script::Handle(target_function.script()); 2110 const Script& script = Script::Handle(target_function.script());
2146 BreakpointLocation* bpt_location = 2111 BreakpointLocation* bpt_location = SetBreakpoint(
2147 SetBreakpoint(script, 2112 script, target_function.token_pos(), target_function.end_token_pos(), -1,
2148 target_function.token_pos(), 2113 -1 /* no requested line/col */);
2149 target_function.end_token_pos(),
2150 -1, -1 /* no requested line/col */);
2151 if (single_shot) { 2114 if (single_shot) {
2152 return bpt_location->AddSingleShot(this); 2115 return bpt_location->AddSingleShot(this);
2153 } else { 2116 } else {
2154 return bpt_location->AddRepeated(this); 2117 return bpt_location->AddRepeated(this);
2155 } 2118 }
2156 } 2119 }
2157 2120
2158 2121
2159 Breakpoint* Debugger::SetBreakpointAtActivation( 2122 Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure,
2160 const Instance& closure, bool for_over_await) { 2123 bool for_over_await) {
2161 if (!closure.IsClosure()) { 2124 if (!closure.IsClosure()) {
2162 return NULL; 2125 return NULL;
2163 } 2126 }
2164 const Function& func = Function::Handle(Closure::Cast(closure).function()); 2127 const Function& func = Function::Handle(Closure::Cast(closure).function());
2165 const Script& script = Script::Handle(func.script()); 2128 const Script& script = Script::Handle(func.script());
2166 BreakpointLocation* bpt_location = SetBreakpoint(script, 2129 BreakpointLocation* bpt_location = SetBreakpoint(
2167 func.token_pos(), 2130 script, func.token_pos(), func.end_token_pos(), -1, -1 /* no line/col */);
2168 func.end_token_pos(),
2169 -1, -1 /* no line/col */);
2170 return bpt_location->AddPerClosure(this, closure, for_over_await); 2131 return bpt_location->AddPerClosure(this, closure, for_over_await);
2171 } 2132 }
2172 2133
2173 2134
2174 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) { 2135 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) {
2175 if (!closure.IsClosure()) { 2136 if (!closure.IsClosure()) {
2176 return NULL; 2137 return NULL;
2177 } 2138 }
2178 2139
2179 BreakpointLocation* loc = breakpoint_locations_; 2140 BreakpointLocation* loc = breakpoint_locations_;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 2172
2212 2173
2213 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url, 2174 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url,
2214 intptr_t line_number, 2175 intptr_t line_number,
2215 intptr_t column_number) { 2176 intptr_t column_number) {
2216 // Prevent future tests from calling this function in the wrong 2177 // Prevent future tests from calling this function in the wrong
2217 // execution state. If you hit this assert, consider using 2178 // execution state. If you hit this assert, consider using
2218 // Dart_SetBreakpoint instead. 2179 // Dart_SetBreakpoint instead.
2219 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM); 2180 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2220 2181
2221 BreakpointLocation* loc = BreakpointLocationAtLineCol(script_url, 2182 BreakpointLocation* loc =
2222 line_number, 2183 BreakpointLocationAtLineCol(script_url, line_number, column_number);
2223 column_number);
2224 if (loc != NULL) { 2184 if (loc != NULL) {
2225 return loc->AddRepeated(this); 2185 return loc->AddRepeated(this);
2226 } 2186 }
2227 return NULL; 2187 return NULL;
2228 } 2188 }
2229 2189
2230 2190
2231 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( 2191 BreakpointLocation* Debugger::BreakpointLocationAtLineCol(
2232 const String& script_url, 2192 const String& script_url,
2233 intptr_t line_number, 2193 intptr_t line_number,
2234 intptr_t column_number) { 2194 intptr_t column_number) {
2235 Zone* zone = Thread::Current()->zone(); 2195 Zone* zone = Thread::Current()->zone();
2236 Library& lib = Library::Handle(zone); 2196 Library& lib = Library::Handle(zone);
2237 Script& script = Script::Handle(zone); 2197 Script& script = Script::Handle(zone);
2238 const GrowableObjectArray& libs = 2198 const GrowableObjectArray& libs =
2239 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); 2199 GrowableObjectArray::Handle(isolate_->object_store()->libraries());
2240 const GrowableObjectArray& scripts = 2200 const GrowableObjectArray& scripts =
2241 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); 2201 GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
2242 for (intptr_t i = 0; i < libs.Length(); i++) { 2202 for (intptr_t i = 0; i < libs.Length(); i++) {
2243 lib ^= libs.At(i); 2203 lib ^= libs.At(i);
2244 script = lib.LookupScript(script_url); 2204 script = lib.LookupScript(script_url);
2245 if (!script.IsNull()) { 2205 if (!script.IsNull()) {
2246 scripts.Add(script); 2206 scripts.Add(script);
2247 } 2207 }
2248 } 2208 }
2249 if (scripts.Length() == 0) { 2209 if (scripts.Length() == 0) {
2250 // No script found with given url. Create a latent breakpoint which 2210 // No script found with given url. Create a latent breakpoint which
2251 // will be set if the url is loaded later. 2211 // will be set if the url is loaded later.
2252 BreakpointLocation* latent_bpt = GetLatentBreakpoint(script_url, 2212 BreakpointLocation* latent_bpt =
2253 line_number, 2213 GetLatentBreakpoint(script_url, line_number, column_number);
2254 column_number);
2255 if (FLAG_verbose_debug) { 2214 if (FLAG_verbose_debug) {
2256 OS::Print("Set latent breakpoint in url '%s' at " 2215 OS::Print(
2257 "line %" Pd " col %" Pd "\n", 2216 "Set latent breakpoint in url '%s' at "
2258 script_url.ToCString(), 2217 "line %" Pd " col %" Pd "\n",
2259 line_number, column_number); 2218 script_url.ToCString(), line_number, column_number);
2260 } 2219 }
2261 return latent_bpt; 2220 return latent_bpt;
2262 } 2221 }
2263 if (scripts.Length() > 1) { 2222 if (scripts.Length() > 1) {
2264 if (FLAG_verbose_debug) { 2223 if (FLAG_verbose_debug) {
2265 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString()); 2224 OS::Print("Multiple scripts match url '%s'\n", script_url.ToCString());
2266 } 2225 }
2267 return NULL; 2226 return NULL;
2268 } 2227 }
2269 script ^= scripts.At(0); 2228 script ^= scripts.At(0);
2270 TokenPosition first_token_idx, last_token_idx; 2229 TokenPosition first_token_idx, last_token_idx;
2271 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx); 2230 script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx);
2272 if (!first_token_idx.IsReal()) { 2231 if (!first_token_idx.IsReal()) {
2273 // Script does not contain the given line number. 2232 // Script does not contain the given line number.
2274 if (FLAG_verbose_debug) { 2233 if (FLAG_verbose_debug) {
2275 OS::Print("Script '%s' does not contain line number %" Pd "\n", 2234 OS::Print("Script '%s' does not contain line number %" Pd "\n",
2276 script_url.ToCString(), line_number); 2235 script_url.ToCString(), line_number);
2277 } 2236 }
2278 return NULL; 2237 return NULL;
2279 } else if (!last_token_idx.IsReal()) { 2238 } else if (!last_token_idx.IsReal()) {
2280 // Line does not contain any tokens. 2239 // Line does not contain any tokens.
2281 if (FLAG_verbose_debug) { 2240 if (FLAG_verbose_debug) {
2282 OS::Print("No executable code at line %" Pd " in '%s'\n", 2241 OS::Print("No executable code at line %" Pd " in '%s'\n", line_number,
2283 line_number, script_url.ToCString()); 2242 script_url.ToCString());
2284 } 2243 }
2285 return NULL; 2244 return NULL;
2286 } 2245 }
2287 2246
2288 BreakpointLocation* bpt = NULL; 2247 BreakpointLocation* bpt = NULL;
2289 ASSERT(first_token_idx <= last_token_idx); 2248 ASSERT(first_token_idx <= last_token_idx);
2290 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) { 2249 while ((bpt == NULL) && (first_token_idx <= last_token_idx)) {
2291 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, 2250 bpt = SetBreakpoint(script, first_token_idx, last_token_idx, line_number,
2292 line_number, column_number); 2251 column_number);
2293 first_token_idx.Next(); 2252 first_token_idx.Next();
2294 } 2253 }
2295 if ((bpt == NULL) && FLAG_verbose_debug) { 2254 if ((bpt == NULL) && FLAG_verbose_debug) {
2296 OS::Print("No executable code at line %" Pd " in '%s'\n", 2255 OS::Print("No executable code at line %" Pd " in '%s'\n", line_number,
2297 line_number, script_url.ToCString()); 2256 script_url.ToCString());
2298 } 2257 }
2299 return bpt; 2258 return bpt;
2300 } 2259 }
2301 2260
2302 2261
2303 intptr_t Debugger::CacheObject(const Object& obj) { 2262 intptr_t Debugger::CacheObject(const Object& obj) {
2304 ASSERT(obj_cache_ != NULL); 2263 ASSERT(obj_cache_ != NULL);
2305 return obj_cache_->AddObject(obj); 2264 return obj_cache_->AddObject(obj);
2306 } 2265 }
2307 2266
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 pause_event_ = event; 2496 pause_event_ = event;
2538 pause_event_->UpdateTimestamp(); 2497 pause_event_->UpdateTimestamp();
2539 obj_cache_ = new RemoteObjectCache(64); 2498 obj_cache_ = new RemoteObjectCache(64);
2540 2499
2541 // We are about to invoke the debugger's event handler. Disable 2500 // We are about to invoke the debugger's event handler. Disable
2542 // interrupts for this thread while waiting for debug commands over 2501 // interrupts for this thread while waiting for debug commands over
2543 // the service protocol. 2502 // the service protocol.
2544 { 2503 {
2545 Thread* thread = Thread::Current(); 2504 Thread* thread = Thread::Current();
2546 DisableThreadInterruptsScope dtis(thread); 2505 DisableThreadInterruptsScope dtis(thread);
2547 TimelineDurationScope tds(thread, 2506 TimelineDurationScope tds(thread, Timeline::GetDebuggerStream(),
2548 Timeline::GetDebuggerStream(),
2549 "Debugger Pause"); 2507 "Debugger Pause");
2550 2508
2551 // Send the pause event. 2509 // Send the pause event.
2552 Service::HandleEvent(event); 2510 Service::HandleEvent(event);
2553 2511
2554 { 2512 {
2555 TransitionVMToNative transition(Thread::Current()); 2513 TransitionVMToNative transition(Thread::Current());
2556 if (FLAG_steal_breakpoints || (event_handler_ == NULL)) { 2514 if (FLAG_steal_breakpoints || (event_handler_ == NULL)) {
2557 // We allow the embedder's default breakpoint handler to be overridden. 2515 // We allow the embedder's default breakpoint handler to be overridden.
2558 isolate_->PauseEventHandler(); 2516 isolate_->PauseEventHandler();
2559 } else if (event_handler_ != NULL) { 2517 } else if (event_handler_ != NULL) {
2560 (*event_handler_)(event); 2518 (*event_handler_)(event);
2561 } 2519 }
2562 } 2520 }
2563 2521
2564 // Notify the service that we have resumed. 2522 // Notify the service that we have resumed.
2565 const Error& error = 2523 const Error& error = Error::Handle(Thread::Current()->sticky_error());
2566 Error::Handle(Thread::Current()->sticky_error()); 2524 ASSERT(error.IsNull() || error.IsUnwindError() ||
2567 ASSERT(error.IsNull() ||
2568 error.IsUnwindError() ||
2569 error.IsUnhandledException()); 2525 error.IsUnhandledException());
2570 2526
2571 // Only send a resume event when the isolate is not unwinding. 2527 // Only send a resume event when the isolate is not unwinding.
2572 if (!error.IsUnwindError()) { 2528 if (!error.IsUnwindError()) {
2573 ServiceEvent resume_event(event->isolate(), ServiceEvent::kResume); 2529 ServiceEvent resume_event(event->isolate(), ServiceEvent::kResume);
2574 resume_event.set_top_frame(event->top_frame()); 2530 resume_event.set_top_frame(event->top_frame());
2575 Service::HandleEvent(&resume_event); 2531 Service::HandleEvent(&resume_event);
2576 } 2532 }
2577 } 2533 }
2578 2534
2579 pause_event_ = NULL; 2535 pause_event_ = NULL;
2580 obj_cache_ = NULL; // Zone allocated 2536 obj_cache_ = NULL; // Zone allocated
2581 } 2537 }
2582 2538
2583 2539
2584 void Debugger::EnterSingleStepMode() { 2540 void Debugger::EnterSingleStepMode() {
2585 stepping_fp_ = 0; 2541 stepping_fp_ = 0;
2586 DeoptimizeWorld(); 2542 DeoptimizeWorld();
2587 isolate_->set_single_step(true); 2543 isolate_->set_single_step(true);
2588 } 2544 }
2589 2545
2590 2546
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2634 bool Debugger::IsDebuggable(const Function& func) { 2590 bool Debugger::IsDebuggable(const Function& func) {
2635 if (!func.is_debuggable()) { 2591 if (!func.is_debuggable()) {
2636 return false; 2592 return false;
2637 } 2593 }
2638 const Class& cls = Class::Handle(func.Owner()); 2594 const Class& cls = Class::Handle(func.Owner());
2639 const Library& lib = Library::Handle(cls.library()); 2595 const Library& lib = Library::Handle(cls.library());
2640 return lib.IsDebuggable(); 2596 return lib.IsDebuggable();
2641 } 2597 }
2642 2598
2643 2599
2644 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, 2600 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) {
2645 Breakpoint* bpt) {
2646 resume_action_ = kContinue; 2601 resume_action_ = kContinue;
2647 stepping_fp_ = 0; 2602 stepping_fp_ = 0;
2648 isolate_->set_single_step(false); 2603 isolate_->set_single_step(false);
2649 ASSERT(!IsPaused()); 2604 ASSERT(!IsPaused());
2650 ASSERT(obj_cache_ == NULL); 2605 ASSERT(obj_cache_ == NULL);
2651 if ((bpt != NULL) && bpt->IsSingleShot()) { 2606 if ((bpt != NULL) && bpt->IsSingleShot()) {
2652 RemoveBreakpoint(bpt->id()); 2607 RemoveBreakpoint(bpt->id());
2653 bpt = NULL; 2608 bpt = NULL;
2654 } 2609 }
2655 2610
2656 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint); 2611 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint);
2657 event.set_top_frame(top_frame); 2612 event.set_top_frame(top_frame);
2658 event.set_breakpoint(bpt); 2613 event.set_breakpoint(bpt);
2659 event.set_at_async_jump(IsAtAsyncJump(top_frame)); 2614 event.set_at_async_jump(IsAtAsyncJump(top_frame));
2660 Pause(&event); 2615 Pause(&event);
2661 } 2616 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 } 2772 }
2818 2773
2819 if (bpt_hit->is_synthetic_async()) { 2774 if (bpt_hit->is_synthetic_async()) {
2820 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2775 DebuggerStackTrace* stack_trace = CollectStackTrace();
2821 ASSERT(stack_trace->Length() > 0); 2776 ASSERT(stack_trace->Length() > 0);
2822 ASSERT(stack_trace_ == NULL); 2777 ASSERT(stack_trace_ == NULL);
2823 stack_trace_ = stack_trace; 2778 stack_trace_ = stack_trace;
2824 2779
2825 // Hit a synthetic async breakpoint. 2780 // Hit a synthetic async breakpoint.
2826 if (FLAG_verbose_debug) { 2781 if (FLAG_verbose_debug) {
2827 OS::Print(">>> hit synthetic breakpoint at %s:%" Pd " " 2782 OS::Print(">>> hit synthetic breakpoint at %s:%" Pd
2783 " "
2828 "(token %s) (address %#" Px ")\n", 2784 "(token %s) (address %#" Px ")\n",
2829 String::Handle(cbpt->SourceUrl()).ToCString(), 2785 String::Handle(cbpt->SourceUrl()).ToCString(),
2830 cbpt->LineNumber(), 2786 cbpt->LineNumber(), cbpt->token_pos().ToCString(),
2831 cbpt->token_pos().ToCString(),
2832 top_frame->pc()); 2787 top_frame->pc());
2833 } 2788 }
2834 2789
2835 ASSERT(synthetic_async_breakpoint_ == NULL); 2790 ASSERT(synthetic_async_breakpoint_ == NULL);
2836 synthetic_async_breakpoint_ = bpt_hit; 2791 synthetic_async_breakpoint_ = bpt_hit;
2837 bpt_hit = NULL; 2792 bpt_hit = NULL;
2838 2793
2839 // We are at the entry of an async function. 2794 // We are at the entry of an async function.
2840 // We issue a step over to resume at the point after the await statement. 2795 // We issue a step over to resume at the point after the await statement.
2841 SetStepOver(); 2796 SetStepOver();
2842 // When we single step from a user breakpoint, our next stepping 2797 // When we single step from a user breakpoint, our next stepping
2843 // point will be at the exact same pc. Skip it. 2798 // point will be at the exact same pc. Skip it.
2844 HandleSteppingRequest(stack_trace_, true /* skip next step */); 2799 HandleSteppingRequest(stack_trace_, true /* skip next step */);
2845 stack_trace_ = NULL; 2800 stack_trace_ = NULL;
2846 return Error::null(); 2801 return Error::null();
2847 } 2802 }
2848 2803
2849 if (FLAG_verbose_debug) { 2804 if (FLAG_verbose_debug) {
2850 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " 2805 OS::Print(">>> hit %s breakpoint at %s:%" Pd
2806 " "
2851 "(token %s) (address %#" Px ")\n", 2807 "(token %s) (address %#" Px ")\n",
2852 cbpt->IsInternal() ? "internal" : "user", 2808 cbpt->IsInternal() ? "internal" : "user",
2853 String::Handle(cbpt->SourceUrl()).ToCString(), 2809 String::Handle(cbpt->SourceUrl()).ToCString(), cbpt->LineNumber(),
2854 cbpt->LineNumber(), 2810 cbpt->token_pos().ToCString(), top_frame->pc());
2855 cbpt->token_pos().ToCString(),
2856 top_frame->pc());
2857 } 2811 }
2858 2812
2859 ASSERT(stack_trace_ == NULL); 2813 ASSERT(stack_trace_ == NULL);
2860 stack_trace_ = stack_trace; 2814 stack_trace_ = stack_trace;
2861 SignalPausedEvent(top_frame, bpt_hit); 2815 SignalPausedEvent(top_frame, bpt_hit);
2862 // When we single step from a user breakpoint, our next stepping 2816 // When we single step from a user breakpoint, our next stepping
2863 // point will be at the exact same pc. Skip it. 2817 // point will be at the exact same pc. Skip it.
2864 HandleSteppingRequest(stack_trace_, true /* skip next step */); 2818 HandleSteppingRequest(stack_trace_, true /* skip next step */);
2865 stack_trace_ = NULL; 2819 stack_trace_ = NULL;
2866 if (cbpt->IsInternal()) { 2820 if (cbpt->IsInternal()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 } 2874 }
2921 } 2875 }
2922 2876
2923 2877
2924 // Return innermost closure contained in 'function' that contains 2878 // Return innermost closure contained in 'function' that contains
2925 // the given token position. 2879 // the given token position.
2926 RawFunction* Debugger::FindInnermostClosure(const Function& function, 2880 RawFunction* Debugger::FindInnermostClosure(const Function& function,
2927 TokenPosition token_pos) { 2881 TokenPosition token_pos) {
2928 Zone* zone = Thread::Current()->zone(); 2882 Zone* zone = Thread::Current()->zone();
2929 const Script& outer_origin = Script::Handle(zone, function.script()); 2883 const Script& outer_origin = Script::Handle(zone, function.script());
2930 const GrowableObjectArray& closures = 2884 const GrowableObjectArray& closures = GrowableObjectArray::Handle(
2931 GrowableObjectArray::Handle(zone, 2885 zone, Isolate::Current()->object_store()->closure_functions());
2932 Isolate::Current()->object_store()->closure_functions());
2933 const intptr_t num_closures = closures.Length(); 2886 const intptr_t num_closures = closures.Length();
2934 Function& closure = Function::Handle(zone); 2887 Function& closure = Function::Handle(zone);
2935 Function& best_fit = Function::Handle(zone); 2888 Function& best_fit = Function::Handle(zone);
2936 for (intptr_t i = 0; i < num_closures; i++) { 2889 for (intptr_t i = 0; i < num_closures; i++) {
2937 closure ^= closures.At(i); 2890 closure ^= closures.At(i);
2938 if ((function.token_pos() < closure.token_pos()) && 2891 if ((function.token_pos() < closure.token_pos()) &&
2939 (closure.end_token_pos() < function.end_token_pos()) && 2892 (closure.end_token_pos() < function.end_token_pos()) &&
2940 (closure.token_pos() <= token_pos) && 2893 (closure.token_pos() <= token_pos) &&
2941 (token_pos <= closure.end_token_pos()) && 2894 (token_pos <= closure.end_token_pos()) &&
2942 (closure.script() == outer_origin.raw())) { 2895 (closure.script() == outer_origin.raw())) {
(...skipping 12 matching lines...) Expand all
2955 if (!func.is_debuggable()) { 2908 if (!func.is_debuggable()) {
2956 // Nothing to do if the function is not debuggable. If there is 2909 // Nothing to do if the function is not debuggable. If there is
2957 // a pending breakpoint in an inner function (that is debuggable), 2910 // a pending breakpoint in an inner function (that is debuggable),
2958 // we'll resolve the breakpoint when the inner function is compiled. 2911 // we'll resolve the breakpoint when the inner function is compiled.
2959 return; 2912 return;
2960 } 2913 }
2961 // Iterate over all source breakpoints to check whether breakpoints 2914 // Iterate over all source breakpoints to check whether breakpoints
2962 // need to be set in the newly compiled function. 2915 // need to be set in the newly compiled function.
2963 Zone* zone = Thread::Current()->zone(); 2916 Zone* zone = Thread::Current()->zone();
2964 Script& script = Script::Handle(zone); 2917 Script& script = Script::Handle(zone);
2965 for (BreakpointLocation* loc = breakpoint_locations_; 2918 for (BreakpointLocation* loc = breakpoint_locations_; loc != NULL;
2966 loc != NULL; 2919 loc = loc->next()) {
2967 loc = loc->next()) {
2968 script = loc->script(); 2920 script = loc->script();
2969 if (FunctionContains(func, script, loc->token_pos())) { 2921 if (FunctionContains(func, script, loc->token_pos())) {
2970 Function& inner_function = Function::Handle(zone); 2922 Function& inner_function = Function::Handle(zone);
2971 inner_function = FindInnermostClosure(func, loc->token_pos()); 2923 inner_function = FindInnermostClosure(func, loc->token_pos());
2972 if (!inner_function.IsNull()) { 2924 if (!inner_function.IsNull()) {
2973 // The local function of a function we just compiled cannot 2925 // The local function of a function we just compiled cannot
2974 // be compiled already. 2926 // be compiled already.
2975 ASSERT(!inner_function.HasCode()); 2927 ASSERT(!inner_function.HasCode());
2976 if (FLAG_verbose_debug) { 2928 if (FLAG_verbose_debug) {
2977 OS::Print("Pending BP remains unresolved in inner function '%s'\n", 2929 OS::Print("Pending BP remains unresolved in inner function '%s'\n",
(...skipping 20 matching lines...) Expand all
2998 String::Handle(func.name()).ToCString()); 2950 String::Handle(func.name()).ToCString());
2999 } 2951 }
3000 continue; 2952 continue;
3001 } 2953 }
3002 TokenPosition requested_pos = loc->token_pos(); 2954 TokenPosition requested_pos = loc->token_pos();
3003 TokenPosition requested_end_pos = loc->end_token_pos(); 2955 TokenPosition requested_end_pos = loc->end_token_pos();
3004 loc->SetResolved(func, bp_pos); 2956 loc->SetResolved(func, bp_pos);
3005 Breakpoint* bpt = loc->breakpoints(); 2957 Breakpoint* bpt = loc->breakpoints();
3006 while (bpt != NULL) { 2958 while (bpt != NULL) {
3007 if (FLAG_verbose_debug) { 2959 if (FLAG_verbose_debug) {
3008 OS::Print("Resolved BP %" Pd " to pos %s, " 2960 OS::Print("Resolved BP %" Pd
3009 "line %" Pd " col %" Pd ", " 2961 " to pos %s, "
2962 "line %" Pd " col %" Pd
2963 ", "
3010 "function '%s' (requested range %s-%s, " 2964 "function '%s' (requested range %s-%s, "
3011 "requested col %" Pd ")\n", 2965 "requested col %" Pd ")\n",
3012 bpt->id(), 2966 bpt->id(), loc->token_pos().ToCString(),
3013 loc->token_pos().ToCString(), 2967 loc->LineNumber(), loc->ColumnNumber(),
3014 loc->LineNumber(), 2968 func.ToFullyQualifiedCString(), requested_pos.ToCString(),
3015 loc->ColumnNumber(),
3016 func.ToFullyQualifiedCString(),
3017 requested_pos.ToCString(),
3018 requested_end_pos.ToCString(), 2969 requested_end_pos.ToCString(),
3019 loc->requested_column_number()); 2970 loc->requested_column_number());
3020 } 2971 }
3021 SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); 2972 SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
3022 bpt = bpt->next(); 2973 bpt = bpt->next();
3023 } 2974 }
3024 } 2975 }
3025 ASSERT(loc->IsResolved()); 2976 ASSERT(loc->IsResolved());
3026 if (FLAG_verbose_debug) { 2977 if (FLAG_verbose_debug) {
3027 Breakpoint* bpt = loc->breakpoints(); 2978 Breakpoint* bpt = loc->breakpoints();
3028 while (bpt != NULL) { 2979 while (bpt != NULL) {
3029 OS::Print("Setting breakpoint %" Pd " at line %" Pd " col %" Pd "" 2980 OS::Print("Setting breakpoint %" Pd " at line %" Pd " col %" Pd
2981 ""
3030 " for %s '%s'\n", 2982 " for %s '%s'\n",
3031 bpt->id(), 2983 bpt->id(), loc->LineNumber(), loc->ColumnNumber(),
3032 loc->LineNumber(),
3033 loc->ColumnNumber(),
3034 func.IsClosureFunction() ? "closure" : "function", 2984 func.IsClosureFunction() ? "closure" : "function",
3035 String::Handle(func.name()).ToCString()); 2985 String::Handle(func.name()).ToCString());
3036 bpt = bpt->next(); 2986 bpt = bpt->next();
3037 } 2987 }
3038 } 2988 }
3039 MakeCodeBreakpointAt(func, loc); 2989 MakeCodeBreakpointAt(func, loc);
3040 } 2990 }
3041 } 2991 }
3042 } 2992 }
3043 2993
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 intptr_t column_number = matched_loc->requested_column_number(); 3028 intptr_t column_number = matched_loc->requested_column_number();
3079 ASSERT(line_number >= 0); 3029 ASSERT(line_number >= 0);
3080 TokenPosition first_token_pos, last_token_pos; 3030 TokenPosition first_token_pos, last_token_pos;
3081 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos); 3031 script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos);
3082 if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) { 3032 if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) {
3083 // Script does not contain the given line number or there are no 3033 // Script does not contain the given line number or there are no
3084 // tokens on the line. Drop the breakpoint silently. 3034 // tokens on the line. Drop the breakpoint silently.
3085 Breakpoint* bpt = matched_loc->breakpoints(); 3035 Breakpoint* bpt = matched_loc->breakpoints();
3086 while (bpt != NULL) { 3036 while (bpt != NULL) {
3087 if (FLAG_verbose_debug) { 3037 if (FLAG_verbose_debug) {
3088 OS::Print("No code found at line %" Pd ": " 3038 OS::Print("No code found at line %" Pd
3039 ": "
3089 "dropping latent breakpoint %" Pd " in '%s'\n", 3040 "dropping latent breakpoint %" Pd " in '%s'\n",
3090 line_number, 3041 line_number, bpt->id(), url.ToCString());
3091 bpt->id(),
3092 url.ToCString());
3093 } 3042 }
3094 Breakpoint* prev = bpt; 3043 Breakpoint* prev = bpt;
3095 bpt = bpt->next(); 3044 bpt = bpt->next();
3096 delete prev; 3045 delete prev;
3097 } 3046 }
3098 delete matched_loc; 3047 delete matched_loc;
3099 } else { 3048 } else {
3100 // We don't expect to already have a breakpoint for this location. 3049 // We don't expect to already have a breakpoint for this location.
3101 // If there is one, assert in debug build but silently drop 3050 // If there is one, assert in debug build but silently drop
3102 // the latent breakpoint in release build. 3051 // the latent breakpoint in release build.
3103 BreakpointLocation* existing_loc = 3052 BreakpointLocation* existing_loc =
3104 GetBreakpointLocation(script, first_token_pos, column_number); 3053 GetBreakpointLocation(script, first_token_pos, column_number);
3105 ASSERT(existing_loc == NULL); 3054 ASSERT(existing_loc == NULL);
3106 if (existing_loc == NULL) { 3055 if (existing_loc == NULL) {
3107 // Create and register a new source breakpoint for the 3056 // Create and register a new source breakpoint for the
3108 // latent breakpoint. 3057 // latent breakpoint.
3109 BreakpointLocation* unresolved_loc = 3058 BreakpointLocation* unresolved_loc =
3110 new BreakpointLocation(script, 3059 new BreakpointLocation(script, first_token_pos, last_token_pos,
3111 first_token_pos, last_token_pos,
3112 line_number, column_number); 3060 line_number, column_number);
3113 RegisterBreakpointLocation(unresolved_loc); 3061 RegisterBreakpointLocation(unresolved_loc);
3114 3062
3115 // Move breakpoints over. 3063 // Move breakpoints over.
3116 Breakpoint* bpt = matched_loc->breakpoints(); 3064 Breakpoint* bpt = matched_loc->breakpoints();
3117 unresolved_loc->set_breakpoints(bpt); 3065 unresolved_loc->set_breakpoints(bpt);
3118 matched_loc->set_breakpoints(NULL); 3066 matched_loc->set_breakpoints(NULL);
3119 while (bpt != NULL) { 3067 while (bpt != NULL) {
3120 bpt->set_bpt_location(unresolved_loc); 3068 bpt->set_bpt_location(unresolved_loc);
3121 if (FLAG_verbose_debug) { 3069 if (FLAG_verbose_debug) {
3122 OS::Print("Converted latent breakpoint " 3070 OS::Print(
3123 "%" Pd " in '%s' at line %" Pd " col %" Pd "\n", 3071 "Converted latent breakpoint "
3124 bpt->id(), 3072 "%" Pd " in '%s' at line %" Pd " col %" Pd "\n",
3125 url.ToCString(), 3073 bpt->id(), url.ToCString(), line_number, column_number);
3126 line_number, column_number);
3127 } 3074 }
3128 bpt = bpt->next(); 3075 bpt = bpt->next();
3129 } 3076 }
3130 SyncBreakpointLocation(unresolved_loc); 3077 SyncBreakpointLocation(unresolved_loc);
3131 } 3078 }
3132 delete matched_loc; 3079 delete matched_loc;
3133 // Break out of the iteration over loaded libraries. If the 3080 // Break out of the iteration over loaded libraries. If the
3134 // same url has been loaded into more than one library, we 3081 // same url has been loaded into more than one library, we
3135 // only set a breakpoint in the first one. 3082 // only set a breakpoint in the first one.
3136 // TODO(hausner): There is one possible pitfall here. 3083 // TODO(hausner): There is one possible pitfall here.
3137 // If the user sets a latent breakpoint using a partial url that 3084 // If the user sets a latent breakpoint using a partial url that
3138 // ends up matching more than one script, the breakpoint might 3085 // ends up matching more than one script, the breakpoint might
3139 // get set in the wrong script. 3086 // get set in the wrong script.
3140 // It would be better if we could warn the user if multiple 3087 // It would be better if we could warn the user if multiple
3141 // scripts are matching. 3088 // scripts are matching.
3142 break; 3089 break;
3143 } 3090 }
3144 } 3091 }
3145 } 3092 }
3146 if (!found_match) { 3093 if (!found_match) {
3147 // No matching url found in any of the libraries. 3094 // No matching url found in any of the libraries.
3148 if (FLAG_verbose_debug) { 3095 if (FLAG_verbose_debug) {
3149 Breakpoint* bpt = loc->breakpoints(); 3096 Breakpoint* bpt = loc->breakpoints();
3150 while (bpt != NULL) { 3097 while (bpt != NULL) {
3151 OS::Print("No match found for latent breakpoint id " 3098 OS::Print(
3152 "%" Pd " with url '%s'\n", 3099 "No match found for latent breakpoint id "
3153 bpt->id(), 3100 "%" Pd " with url '%s'\n",
3154 url.ToCString()); 3101 bpt->id(), url.ToCString());
3155 bpt = bpt->next(); 3102 bpt = bpt->next();
3156 } 3103 }
3157 } 3104 }
3158 loc = loc->next(); 3105 loc = loc->next();
3159 } 3106 }
3160 } 3107 }
3161 } 3108 }
3162 3109
3163 3110
3164 // TODO(hausner): Could potentially make this faster by checking 3111 // TODO(hausner): Could potentially make this faster by checking
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 } 3229 }
3283 } 3230 }
3284 } 3231 }
3285 3232
3286 3233
3287 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, 3234 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script,
3288 TokenPosition token_pos, 3235 TokenPosition token_pos,
3289 intptr_t requested_column) { 3236 intptr_t requested_column) {
3290 BreakpointLocation* bpt = breakpoint_locations_; 3237 BreakpointLocation* bpt = breakpoint_locations_;
3291 while (bpt != NULL) { 3238 while (bpt != NULL) {
3292 if ((bpt->script_ == script.raw()) && 3239 if ((bpt->script_ == script.raw()) && (bpt->token_pos_ == token_pos) &&
3293 (bpt->token_pos_ == token_pos) &&
3294 (bpt->requested_column_number_ == requested_column)) { 3240 (bpt->requested_column_number_ == requested_column)) {
3295 return bpt; 3241 return bpt;
3296 } 3242 }
3297 bpt = bpt->next(); 3243 bpt = bpt->next();
3298 } 3244 }
3299 return NULL; 3245 return NULL;
3300 } 3246 }
3301 3247
3302 3248
3303 Breakpoint* Debugger::GetBreakpointById(intptr_t id) { 3249 Breakpoint* Debugger::GetBreakpointById(intptr_t id) {
(...skipping 12 matching lines...) Expand all
3316 } 3262 }
3317 3263
3318 3264
3319 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, 3265 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url,
3320 intptr_t line, 3266 intptr_t line,
3321 intptr_t column) { 3267 intptr_t column) {
3322 BreakpointLocation* bpt = latent_locations_; 3268 BreakpointLocation* bpt = latent_locations_;
3323 String& bpt_url = String::Handle(); 3269 String& bpt_url = String::Handle();
3324 while (bpt != NULL) { 3270 while (bpt != NULL) {
3325 bpt_url = bpt->url(); 3271 bpt_url = bpt->url();
3326 if (bpt_url.Equals(url) && 3272 if (bpt_url.Equals(url) && (bpt->requested_line_number() == line) &&
3327 (bpt->requested_line_number() == line) &&
3328 (bpt->requested_column_number() == column)) { 3273 (bpt->requested_column_number() == column)) {
3329 return bpt; 3274 return bpt;
3330 } 3275 }
3331 bpt = bpt->next(); 3276 bpt = bpt->next();
3332 } 3277 }
3333 // No breakpoint for this location requested. Allocate new one. 3278 // No breakpoint for this location requested. Allocate new one.
3334 bpt = new BreakpointLocation(url, line, column); 3279 bpt = new BreakpointLocation(url, line, column);
3335 bpt->set_next(latent_locations_); 3280 bpt->set_next(latent_locations_);
3336 latent_locations_ = bpt; 3281 latent_locations_ = bpt;
3337 return bpt; 3282 return bpt;
3338 } 3283 }
3339 3284
3340 3285
3341 void Debugger::RegisterBreakpointLocation(BreakpointLocation* bpt) { 3286 void Debugger::RegisterBreakpointLocation(BreakpointLocation* bpt) {
3342 ASSERT(bpt->next() == NULL); 3287 ASSERT(bpt->next() == NULL);
3343 bpt->set_next(breakpoint_locations_); 3288 bpt->set_next(breakpoint_locations_);
3344 breakpoint_locations_ = bpt; 3289 breakpoint_locations_ = bpt;
3345 } 3290 }
3346 3291
3347 3292
3348 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 3293 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3349 ASSERT(bpt->next() == NULL); 3294 ASSERT(bpt->next() == NULL);
3350 bpt->set_next(code_breakpoints_); 3295 bpt->set_next(code_breakpoints_);
3351 code_breakpoints_ = bpt; 3296 code_breakpoints_ = bpt;
3352 } 3297 }
3353 3298
3354 #endif // !PRODUCT 3299 #endif // !PRODUCT
3355 3300
3356 } // namespace dart 3301 } // 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