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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debugger.h" 5 #include "vm/debugger.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "platform/address_sanitizer.h" 9 #include "platform/address_sanitizer.h"
10 10
(...skipping 18 matching lines...) Expand all
29 #include "vm/service_isolate.h" 29 #include "vm/service_isolate.h"
30 #include "vm/stack_frame.h" 30 #include "vm/stack_frame.h"
31 #include "vm/stack_trace.h" 31 #include "vm/stack_trace.h"
32 #include "vm/stub_code.h" 32 #include "vm/stub_code.h"
33 #include "vm/symbols.h" 33 #include "vm/symbols.h"
34 #include "vm/thread_interrupter.h" 34 #include "vm/thread_interrupter.h"
35 #include "vm/timeline.h" 35 #include "vm/timeline.h"
36 #include "vm/token_position.h" 36 #include "vm/token_position.h"
37 #include "vm/visitor.h" 37 #include "vm/visitor.h"
38 38
39
40 namespace dart { 39 namespace dart {
41 40
42 DEFINE_FLAG(bool, 41 DEFINE_FLAG(bool,
43 show_invisible_frames, 42 show_invisible_frames,
44 false, 43 false,
45 "Show invisible frames in debugger stack traces"); 44 "Show invisible frames in debugger stack traces");
46 DEFINE_FLAG(bool, 45 DEFINE_FLAG(bool,
47 trace_debugger_stacktrace, 46 trace_debugger_stacktrace,
48 false, 47 false,
49 "Trace debugger stacktrace collection"); 48 "Trace debugger stacktrace collection");
50 DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind"); 49 DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind");
51 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); 50 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
52 DEFINE_FLAG(bool, 51 DEFINE_FLAG(bool,
53 steal_breakpoints, 52 steal_breakpoints,
54 false, 53 false,
55 "Intercept breakpoints and other pause events before they " 54 "Intercept breakpoints and other pause events before they "
56 "are sent to the embedder and use a generic VM breakpoint " 55 "are sent to the embedder and use a generic VM breakpoint "
57 "handler instead. This handler dispatches breakpoints to " 56 "handler instead. This handler dispatches breakpoints to "
58 "the VM service."); 57 "the VM service.");
59 58
60 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); 59 DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
61 60
62
63 #ifndef PRODUCT 61 #ifndef PRODUCT
64 62
65 Debugger::EventHandler* Debugger::event_handler_ = NULL; 63 Debugger::EventHandler* Debugger::event_handler_ = NULL;
66 64
67
68 class RemoteObjectCache : public ZoneAllocated { 65 class RemoteObjectCache : public ZoneAllocated {
69 public: 66 public:
70 explicit RemoteObjectCache(intptr_t initial_size); 67 explicit RemoteObjectCache(intptr_t initial_size);
71 intptr_t AddObject(const Object& obj); 68 intptr_t AddObject(const Object& obj);
72 RawObject* GetObj(intptr_t obj_id) const; 69 RawObject* GetObj(intptr_t obj_id) const;
73 bool IsValidId(intptr_t obj_id) const { return obj_id < objs_->Length(); } 70 bool IsValidId(intptr_t obj_id) const { return obj_id < objs_->Length(); }
74 71
75 private: 72 private:
76 GrowableObjectArray* objs_; 73 GrowableObjectArray* objs_;
77 74
78 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache); 75 DISALLOW_COPY_AND_ASSIGN(RemoteObjectCache);
79 }; 76 };
80 77
81
82 // Create an unresolved breakpoint in given token range and script. 78 // Create an unresolved breakpoint in given token range and script.
83 BreakpointLocation::BreakpointLocation(const Script& script, 79 BreakpointLocation::BreakpointLocation(const Script& script,
84 TokenPosition token_pos, 80 TokenPosition token_pos,
85 TokenPosition end_token_pos, 81 TokenPosition end_token_pos,
86 intptr_t requested_line_number, 82 intptr_t requested_line_number,
87 intptr_t requested_column_number) 83 intptr_t requested_column_number)
88 : script_(script.raw()), 84 : script_(script.raw()),
89 url_(script.url()), 85 url_(script.url()),
90 token_pos_(token_pos), 86 token_pos_(token_pos),
91 end_token_pos_(end_token_pos), 87 end_token_pos_(end_token_pos),
(...skipping 21 matching lines...) Expand all
113 next_(NULL), 109 next_(NULL),
114 conditions_(NULL), 110 conditions_(NULL),
115 requested_line_number_(requested_line_number), 111 requested_line_number_(requested_line_number),
116 requested_column_number_(requested_column_number), 112 requested_column_number_(requested_column_number),
117 function_(Function::null()), 113 function_(Function::null()),
118 line_number_(-1), 114 line_number_(-1),
119 column_number_(-1) { 115 column_number_(-1) {
120 ASSERT(requested_line_number_ >= 0); 116 ASSERT(requested_line_number_ >= 0);
121 } 117 }
122 118
123
124 BreakpointLocation::~BreakpointLocation() { 119 BreakpointLocation::~BreakpointLocation() {
125 Breakpoint* bpt = breakpoints(); 120 Breakpoint* bpt = breakpoints();
126 while (bpt != NULL) { 121 while (bpt != NULL) {
127 Breakpoint* temp = bpt; 122 Breakpoint* temp = bpt;
128 bpt = bpt->next(); 123 bpt = bpt->next();
129 delete temp; 124 delete temp;
130 } 125 }
131 } 126 }
132 127
133
134 bool BreakpointLocation::AnyEnabled() const { 128 bool BreakpointLocation::AnyEnabled() const {
135 return breakpoints() != NULL; 129 return breakpoints() != NULL;
136 } 130 }
137 131
138
139 void BreakpointLocation::SetResolved(const Function& func, 132 void BreakpointLocation::SetResolved(const Function& func,
140 TokenPosition token_pos) { 133 TokenPosition token_pos) {
141 ASSERT(!IsLatent()); 134 ASSERT(!IsLatent());
142 ASSERT(func.script() == script_); 135 ASSERT(func.script() == script_);
143 ASSERT((func.token_pos() <= token_pos) && 136 ASSERT((func.token_pos() <= token_pos) &&
144 (token_pos <= func.end_token_pos())); 137 (token_pos <= func.end_token_pos()));
145 ASSERT(func.is_debuggable()); 138 ASSERT(func.is_debuggable());
146 function_ = func.raw(); 139 function_ = func.raw();
147 token_pos_ = token_pos; 140 token_pos_ = token_pos;
148 end_token_pos_ = token_pos; 141 end_token_pos_ = token_pos;
149 is_resolved_ = true; 142 is_resolved_ = true;
150 } 143 }
151 144
152
153 // TODO(hausner): Get rid of library parameter. A source breakpoint location 145 // TODO(hausner): Get rid of library parameter. A source breakpoint location
154 // does not imply a library, since the same source code can be included 146 // does not imply a library, since the same source code can be included
155 // in more than one library, e.g. the text location of mixin functions. 147 // in more than one library, e.g. the text location of mixin functions.
156 void BreakpointLocation::GetCodeLocation(Library* lib, 148 void BreakpointLocation::GetCodeLocation(Library* lib,
157 Script* script, 149 Script* script,
158 TokenPosition* pos) const { 150 TokenPosition* pos) const {
159 if (IsLatent()) { 151 if (IsLatent()) {
160 *lib = Library::null(); 152 *lib = Library::null();
161 *script = Script::null(); 153 *script = Script::null();
162 *pos = TokenPosition::kNoSource; 154 *pos = TokenPosition::kNoSource;
163 } else { 155 } else {
164 *script = this->script(); 156 *script = this->script();
165 *pos = token_pos_; 157 *pos = token_pos_;
166 if (IsResolved()) { 158 if (IsResolved()) {
167 const Function& func = Function::Handle(function_); 159 const Function& func = Function::Handle(function_);
168 ASSERT(!func.IsNull()); 160 ASSERT(!func.IsNull());
169 const Class& cls = Class::Handle(func.origin()); 161 const Class& cls = Class::Handle(func.origin());
170 *lib = cls.library(); 162 *lib = cls.library();
171 } else { 163 } else {
172 *lib = Library::null(); 164 *lib = Library::null();
173 } 165 }
174 } 166 }
175 } 167 }
176 168
177
178 intptr_t BreakpointLocation::LineNumber() { 169 intptr_t BreakpointLocation::LineNumber() {
179 ASSERT(IsResolved()); 170 ASSERT(IsResolved());
180 // Compute line number lazily since it causes scanning of the script. 171 // Compute line number lazily since it causes scanning of the script.
181 if (line_number_ < 0) { 172 if (line_number_ < 0) {
182 const Script& script = Script::Handle(this->script()); 173 const Script& script = Script::Handle(this->script());
183 script.GetTokenLocation(token_pos_, &line_number_, NULL); 174 script.GetTokenLocation(token_pos_, &line_number_, NULL);
184 } 175 }
185 return line_number_; 176 return line_number_;
186 } 177 }
187 178
188
189 intptr_t BreakpointLocation::ColumnNumber() { 179 intptr_t BreakpointLocation::ColumnNumber() {
190 ASSERT(IsResolved()); 180 ASSERT(IsResolved());
191 // Compute column number lazily since it causes scanning of the script. 181 // Compute column number lazily since it causes scanning of the script.
192 if (column_number_ < 0) { 182 if (column_number_ < 0) {
193 const Script& script = Script::Handle(this->script()); 183 const Script& script = Script::Handle(this->script());
194 script.GetTokenLocation(token_pos_, &line_number_, &column_number_); 184 script.GetTokenLocation(token_pos_, &line_number_, &column_number_);
195 } 185 }
196 return column_number_; 186 return column_number_;
197 } 187 }
198 188
199
200 void Breakpoint::set_bpt_location(BreakpointLocation* new_bpt_location) { 189 void Breakpoint::set_bpt_location(BreakpointLocation* new_bpt_location) {
201 // Only latent breakpoints can be moved. 190 // Only latent breakpoints can be moved.
202 ASSERT((new_bpt_location == NULL) || bpt_location_->IsLatent()); 191 ASSERT((new_bpt_location == NULL) || bpt_location_->IsLatent());
203 bpt_location_ = new_bpt_location; 192 bpt_location_ = new_bpt_location;
204 } 193 }
205 194
206
207 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 195 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
208 visitor->VisitPointer(reinterpret_cast<RawObject**>(&closure_)); 196 visitor->VisitPointer(reinterpret_cast<RawObject**>(&closure_));
209 } 197 }
210 198
211
212 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) { 199 void BreakpointLocation::VisitObjectPointers(ObjectPointerVisitor* visitor) {
213 visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_)); 200 visitor->VisitPointer(reinterpret_cast<RawObject**>(&script_));
214 visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_)); 201 visitor->VisitPointer(reinterpret_cast<RawObject**>(&url_));
215 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); 202 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
216 203
217 Breakpoint* bpt = conditions_; 204 Breakpoint* bpt = conditions_;
218 while (bpt != NULL) { 205 while (bpt != NULL) {
219 bpt->VisitObjectPointers(visitor); 206 bpt->VisitObjectPointers(visitor);
220 bpt = bpt->next(); 207 bpt = bpt->next();
221 } 208 }
222 } 209 }
223 210
224
225 void Breakpoint::PrintJSON(JSONStream* stream) { 211 void Breakpoint::PrintJSON(JSONStream* stream) {
226 JSONObject jsobj(stream); 212 JSONObject jsobj(stream);
227 jsobj.AddProperty("type", "Breakpoint"); 213 jsobj.AddProperty("type", "Breakpoint");
228 214
229 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id()); 215 jsobj.AddFixedServiceId("breakpoints/%" Pd "", id());
230 jsobj.AddProperty("breakpointNumber", id()); 216 jsobj.AddProperty("breakpointNumber", id());
231 if (is_synthetic_async()) { 217 if (is_synthetic_async()) {
232 jsobj.AddProperty("isSyntheticAsyncContinuation", is_synthetic_async()); 218 jsobj.AddProperty("isSyntheticAsyncContinuation", is_synthetic_async());
233 } 219 }
234 jsobj.AddProperty("resolved", bpt_location_->IsResolved()); 220 jsobj.AddProperty("resolved", bpt_location_->IsResolved());
235 if (bpt_location_->IsResolved()) { 221 if (bpt_location_->IsResolved()) {
236 jsobj.AddLocation(bpt_location_); 222 jsobj.AddLocation(bpt_location_);
237 } else { 223 } else {
238 jsobj.AddUnresolvedLocation(bpt_location_); 224 jsobj.AddUnresolvedLocation(bpt_location_);
239 } 225 }
240 } 226 }
241 227
242
243 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 228 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
244 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_)); 229 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_));
245 #if !defined(TARGET_ARCH_DBC) 230 #if !defined(TARGET_ARCH_DBC)
246 visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_)); 231 visitor->VisitPointer(reinterpret_cast<RawObject**>(&saved_value_));
247 #endif 232 #endif
248 } 233 }
249 234
250
251 ActivationFrame::ActivationFrame(uword pc, 235 ActivationFrame::ActivationFrame(uword pc,
252 uword fp, 236 uword fp,
253 uword sp, 237 uword sp,
254 const Code& code, 238 const Code& code,
255 const Array& deopt_frame, 239 const Array& deopt_frame,
256 intptr_t deopt_frame_offset, 240 intptr_t deopt_frame_offset,
257 ActivationFrame::Kind kind) 241 ActivationFrame::Kind kind)
258 : pc_(pc), 242 : pc_(pc),
259 fp_(fp), 243 fp_(fp),
260 sp_(sp), 244 sp_(sp),
261 ctx_(Context::ZoneHandle()), 245 ctx_(Context::ZoneHandle()),
262 code_(Code::ZoneHandle(code.raw())), 246 code_(Code::ZoneHandle(code.raw())),
263 function_(Function::ZoneHandle(code.function())), 247 function_(Function::ZoneHandle(code.function())),
264 live_frame_((kind == kRegular) || (kind == kAsyncActivation)), 248 live_frame_((kind == kRegular) || (kind == kAsyncActivation)),
265 token_pos_initialized_(false), 249 token_pos_initialized_(false),
266 token_pos_(TokenPosition::kNoSource), 250 token_pos_(TokenPosition::kNoSource),
267 try_index_(-1), 251 try_index_(-1),
268 deopt_id_(Thread::kNoDeoptId), 252 deopt_id_(Thread::kNoDeoptId),
269 line_number_(-1), 253 line_number_(-1),
270 column_number_(-1), 254 column_number_(-1),
271 context_level_(-1), 255 context_level_(-1),
272 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 256 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
273 deopt_frame_offset_(deopt_frame_offset), 257 deopt_frame_offset_(deopt_frame_offset),
274 kind_(kind), 258 kind_(kind),
275 vars_initialized_(false), 259 vars_initialized_(false),
276 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 260 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
277 desc_indices_(8), 261 desc_indices_(8),
278 pc_desc_(PcDescriptors::ZoneHandle()) {} 262 pc_desc_(PcDescriptors::ZoneHandle()) {}
279 263
280
281 ActivationFrame::ActivationFrame(Kind kind) 264 ActivationFrame::ActivationFrame(Kind kind)
282 : pc_(0), 265 : pc_(0),
283 fp_(0), 266 fp_(0),
284 sp_(0), 267 sp_(0),
285 ctx_(Context::ZoneHandle()), 268 ctx_(Context::ZoneHandle()),
286 code_(Code::ZoneHandle()), 269 code_(Code::ZoneHandle()),
287 function_(Function::ZoneHandle()), 270 function_(Function::ZoneHandle()),
288 live_frame_(kind == kRegular), 271 live_frame_(kind == kRegular),
289 token_pos_initialized_(false), 272 token_pos_initialized_(false),
290 token_pos_(TokenPosition::kNoSource), 273 token_pos_(TokenPosition::kNoSource),
291 try_index_(-1), 274 try_index_(-1),
292 line_number_(-1), 275 line_number_(-1),
293 column_number_(-1), 276 column_number_(-1),
294 context_level_(-1), 277 context_level_(-1),
295 deopt_frame_(Array::ZoneHandle()), 278 deopt_frame_(Array::ZoneHandle()),
296 deopt_frame_offset_(0), 279 deopt_frame_offset_(0),
297 kind_(kind), 280 kind_(kind),
298 vars_initialized_(false), 281 vars_initialized_(false),
299 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 282 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
300 desc_indices_(8), 283 desc_indices_(8),
301 pc_desc_(PcDescriptors::ZoneHandle()) {} 284 pc_desc_(PcDescriptors::ZoneHandle()) {}
302 285
303
304 ActivationFrame::ActivationFrame(const Closure& async_activation) 286 ActivationFrame::ActivationFrame(const Closure& async_activation)
305 : pc_(0), 287 : pc_(0),
306 fp_(0), 288 fp_(0),
307 sp_(0), 289 sp_(0),
308 ctx_(Context::ZoneHandle()), 290 ctx_(Context::ZoneHandle()),
309 code_(Code::ZoneHandle()), 291 code_(Code::ZoneHandle()),
310 function_(Function::ZoneHandle()), 292 function_(Function::ZoneHandle()),
311 live_frame_(false), 293 live_frame_(false),
312 token_pos_initialized_(false), 294 token_pos_initialized_(false),
313 token_pos_(TokenPosition::kNoSource), 295 token_pos_(TokenPosition::kNoSource),
(...skipping 10 matching lines...) Expand all
324 pc_desc_(PcDescriptors::ZoneHandle()) { 306 pc_desc_(PcDescriptors::ZoneHandle()) {
325 // Extract the function and the code from the asynchronous activation. 307 // Extract the function and the code from the asynchronous activation.
326 function_ = async_activation.function(); 308 function_ = async_activation.function();
327 function_.EnsureHasCompiledUnoptimizedCode(); 309 function_.EnsureHasCompiledUnoptimizedCode();
328 code_ = function_.unoptimized_code(); 310 code_ = function_.unoptimized_code();
329 ctx_ = async_activation.context(); 311 ctx_ = async_activation.context();
330 ASSERT(fp_ == 0); 312 ASSERT(fp_ == 0);
331 ASSERT(!ctx_.IsNull()); 313 ASSERT(!ctx_.IsNull());
332 } 314 }
333 315
334
335 bool Debugger::NeedsIsolateEvents() { 316 bool Debugger::NeedsIsolateEvents() {
336 return ((isolate_ != Dart::vm_isolate()) && 317 return ((isolate_ != Dart::vm_isolate()) &&
337 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) && 318 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
338 ((event_handler_ != NULL) || Service::isolate_stream.enabled())); 319 ((event_handler_ != NULL) || Service::isolate_stream.enabled()));
339 } 320 }
340 321
341
342 bool Debugger::NeedsDebugEvents() { 322 bool Debugger::NeedsDebugEvents() {
343 ASSERT(isolate_ != Dart::vm_isolate() && 323 ASSERT(isolate_ != Dart::vm_isolate() &&
344 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)); 324 !ServiceIsolate::IsServiceIsolateDescendant(isolate_));
345 return (FLAG_warn_on_pause_with_no_debugger || (event_handler_ != NULL) || 325 return (FLAG_warn_on_pause_with_no_debugger || (event_handler_ != NULL) ||
346 Service::debug_stream.enabled()); 326 Service::debug_stream.enabled());
347 } 327 }
348 328
349
350 void Debugger::InvokeEventHandler(ServiceEvent* event) { 329 void Debugger::InvokeEventHandler(ServiceEvent* event) {
351 ASSERT(!event->IsPause()); // For pause events, call Pause instead. 330 ASSERT(!event->IsPause()); // For pause events, call Pause instead.
352 Service::HandleEvent(event); 331 Service::HandleEvent(event);
353 332
354 // Call the embedder's event handler, if it exists. 333 // Call the embedder's event handler, if it exists.
355 if (event_handler_ != NULL) { 334 if (event_handler_ != NULL) {
356 TransitionVMToNative transition(Thread::Current()); 335 TransitionVMToNative transition(Thread::Current());
357 (*event_handler_)(event); 336 (*event_handler_)(event);
358 } 337 }
359 } 338 }
360 339
361
362 RawError* Debugger::PauseInterrupted() { 340 RawError* Debugger::PauseInterrupted() {
363 return PauseRequest(ServiceEvent::kPauseInterrupted); 341 return PauseRequest(ServiceEvent::kPauseInterrupted);
364 } 342 }
365 343
366
367 RawError* Debugger::PausePostRequest() { 344 RawError* Debugger::PausePostRequest() {
368 return PauseRequest(ServiceEvent::kPausePostRequest); 345 return PauseRequest(ServiceEvent::kPausePostRequest);
369 } 346 }
370 347
371
372 RawError* Debugger::PauseRequest(ServiceEvent::EventKind kind) { 348 RawError* Debugger::PauseRequest(ServiceEvent::EventKind kind) {
373 if (ignore_breakpoints_ || IsPaused()) { 349 if (ignore_breakpoints_ || IsPaused()) {
374 // We don't let the isolate get interrupted if we are already 350 // We don't let the isolate get interrupted if we are already
375 // paused or ignoring breakpoints. 351 // paused or ignoring breakpoints.
376 return Error::null(); 352 return Error::null();
377 } 353 }
378 ServiceEvent event(isolate_, kind); 354 ServiceEvent event(isolate_, kind);
379 DebuggerStackTrace* trace = CollectStackTrace(); 355 DebuggerStackTrace* trace = CollectStackTrace();
380 if (trace->Length() > 0) { 356 if (trace->Length() > 0) {
381 event.set_top_frame(trace->FrameAt(0)); 357 event.set_top_frame(trace->FrameAt(0));
382 } 358 }
383 CacheStackTraces(trace, CollectAsyncCausalStackTrace(), 359 CacheStackTraces(trace, CollectAsyncCausalStackTrace(),
384 CollectAwaiterReturnStackTrace()); 360 CollectAwaiterReturnStackTrace());
385 resume_action_ = kContinue; 361 resume_action_ = kContinue;
386 Pause(&event); 362 Pause(&event);
387 HandleSteppingRequest(trace); 363 HandleSteppingRequest(trace);
388 ClearCachedStackTraces(); 364 ClearCachedStackTraces();
389 365
390 // If any error occurred while in the debug message loop, return it here. 366 // If any error occurred while in the debug message loop, return it here.
391 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 367 const Error& error = Error::Handle(Thread::Current()->sticky_error());
392 ASSERT(error.IsNull() || error.IsUnwindError()); 368 ASSERT(error.IsNull() || error.IsUnwindError());
393 Thread::Current()->clear_sticky_error(); 369 Thread::Current()->clear_sticky_error();
394 return error.raw(); 370 return error.raw();
395 } 371 }
396 372
397
398 void Debugger::SendBreakpointEvent(ServiceEvent::EventKind kind, 373 void Debugger::SendBreakpointEvent(ServiceEvent::EventKind kind,
399 Breakpoint* bpt) { 374 Breakpoint* bpt) {
400 if (NeedsDebugEvents()) { 375 if (NeedsDebugEvents()) {
401 // TODO(turnidge): Currently we send single-shot breakpoint events 376 // TODO(turnidge): Currently we send single-shot breakpoint events
402 // to the vm service. Do we want to change this? 377 // to the vm service. Do we want to change this?
403 ServiceEvent event(isolate_, kind); 378 ServiceEvent event(isolate_, kind);
404 event.set_breakpoint(bpt); 379 event.set_breakpoint(bpt);
405 InvokeEventHandler(&event); 380 InvokeEventHandler(&event);
406 } 381 }
407 } 382 }
408 383
409
410 void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) { 384 void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) {
411 bpt->set_next(breakpoints()); 385 bpt->set_next(breakpoints());
412 set_breakpoints(bpt); 386 set_breakpoints(bpt);
413 387
414 dbg->SyncBreakpointLocation(this); 388 dbg->SyncBreakpointLocation(this);
415 dbg->SendBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt); 389 dbg->SendBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
416 } 390 }
417 391
418
419 Breakpoint* BreakpointLocation::AddRepeated(Debugger* dbg) { 392 Breakpoint* BreakpointLocation::AddRepeated(Debugger* dbg) {
420 Breakpoint* bpt = breakpoints(); 393 Breakpoint* bpt = breakpoints();
421 while (bpt != NULL) { 394 while (bpt != NULL) {
422 if (bpt->IsRepeated()) break; 395 if (bpt->IsRepeated()) break;
423 bpt = bpt->next(); 396 bpt = bpt->next();
424 } 397 }
425 if (bpt == NULL) { 398 if (bpt == NULL) {
426 bpt = new Breakpoint(dbg->nextId(), this); 399 bpt = new Breakpoint(dbg->nextId(), this);
427 bpt->SetIsRepeated(); 400 bpt->SetIsRepeated();
428 AddBreakpoint(bpt, dbg); 401 AddBreakpoint(bpt, dbg);
429 } 402 }
430 return bpt; 403 return bpt;
431 } 404 }
432 405
433
434 Breakpoint* BreakpointLocation::AddSingleShot(Debugger* dbg) { 406 Breakpoint* BreakpointLocation::AddSingleShot(Debugger* dbg) {
435 Breakpoint* bpt = breakpoints(); 407 Breakpoint* bpt = breakpoints();
436 while (bpt != NULL) { 408 while (bpt != NULL) {
437 if (bpt->IsSingleShot()) break; 409 if (bpt->IsSingleShot()) break;
438 bpt = bpt->next(); 410 bpt = bpt->next();
439 } 411 }
440 if (bpt == NULL) { 412 if (bpt == NULL) {
441 bpt = new Breakpoint(dbg->nextId(), this); 413 bpt = new Breakpoint(dbg->nextId(), this);
442 bpt->SetIsSingleShot(); 414 bpt->SetIsSingleShot();
443 AddBreakpoint(bpt, dbg); 415 AddBreakpoint(bpt, dbg);
444 } 416 }
445 return bpt; 417 return bpt;
446 } 418 }
447 419
448
449 Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg, 420 Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg,
450 const Instance& closure, 421 const Instance& closure,
451 bool for_over_await) { 422 bool for_over_await) {
452 Breakpoint* bpt = NULL; 423 Breakpoint* bpt = NULL;
453 // Do not reuse existing breakpoints for stepping over await clauses. 424 // Do not reuse existing breakpoints for stepping over await clauses.
454 // A second async step-over command will set a new breakpoint before 425 // A second async step-over command will set a new breakpoint before
455 // the existing one gets deleted when first async step-over resumes. 426 // the existing one gets deleted when first async step-over resumes.
456 if (!for_over_await) { 427 if (!for_over_await) {
457 bpt = breakpoints(); 428 bpt = breakpoints();
458 while (bpt != NULL) { 429 while (bpt != NULL) {
459 if (bpt->IsPerClosure() && (bpt->closure() == closure.raw())) break; 430 if (bpt->IsPerClosure() && (bpt->closure() == closure.raw())) break;
460 bpt = bpt->next(); 431 bpt = bpt->next();
461 } 432 }
462 } 433 }
463 if (bpt == NULL) { 434 if (bpt == NULL) {
464 bpt = new Breakpoint(dbg->nextId(), this); 435 bpt = new Breakpoint(dbg->nextId(), this);
465 bpt->SetIsPerClosure(closure); 436 bpt->SetIsPerClosure(closure);
466 bpt->set_is_synthetic_async(for_over_await); 437 bpt->set_is_synthetic_async(for_over_await);
467 AddBreakpoint(bpt, dbg); 438 AddBreakpoint(bpt, dbg);
468 } 439 }
469 return bpt; 440 return bpt;
470 } 441 }
471 442
472
473 const char* Debugger::QualifiedFunctionName(const Function& func) { 443 const char* Debugger::QualifiedFunctionName(const Function& func) {
474 const String& func_name = String::Handle(func.name()); 444 const String& func_name = String::Handle(func.name());
475 Class& func_class = Class::Handle(func.Owner()); 445 Class& func_class = Class::Handle(func.Owner());
476 String& class_name = String::Handle(func_class.Name()); 446 String& class_name = String::Handle(func_class.Name());
477 447
478 return OS::SCreate(Thread::Current()->zone(), "%s%s%s", 448 return OS::SCreate(Thread::Current()->zone(), "%s%s%s",
479 func_class.IsTopLevel() ? "" : class_name.ToCString(), 449 func_class.IsTopLevel() ? "" : class_name.ToCString(),
480 func_class.IsTopLevel() ? "" : ".", func_name.ToCString()); 450 func_class.IsTopLevel() ? "" : ".", func_name.ToCString());
481 } 451 }
482 452
483
484 // Returns true if the function |func| overlaps the token range 453 // Returns true if the function |func| overlaps the token range
485 // [|token_pos|, |end_token_pos|] in |script|. 454 // [|token_pos|, |end_token_pos|] in |script|.
486 static bool FunctionOverlaps(const Function& func, 455 static bool FunctionOverlaps(const Function& func,
487 const Script& script, 456 const Script& script,
488 TokenPosition token_pos, 457 TokenPosition token_pos,
489 TokenPosition end_token_pos) { 458 TokenPosition end_token_pos) {
490 TokenPosition func_start = func.token_pos(); 459 TokenPosition func_start = func.token_pos();
491 if (((func_start <= token_pos) && (token_pos <= func.end_token_pos())) || 460 if (((func_start <= token_pos) && (token_pos <= func.end_token_pos())) ||
492 ((token_pos <= func_start) && (func_start <= end_token_pos))) { 461 ((token_pos <= func_start) && (func_start <= end_token_pos))) {
493 // Check script equality second because it allocates 462 // Check script equality second because it allocates
494 // handles as a side effect. 463 // handles as a side effect.
495 return func.script() == script.raw(); 464 return func.script() == script.raw();
496 } 465 }
497 return false; 466 return false;
498 } 467 }
499 468
500
501 static bool IsImplicitFunction(const Function& func) { 469 static bool IsImplicitFunction(const Function& func) {
502 switch (func.kind()) { 470 switch (func.kind()) {
503 case RawFunction::kImplicitGetter: 471 case RawFunction::kImplicitGetter:
504 case RawFunction::kImplicitSetter: 472 case RawFunction::kImplicitSetter:
505 case RawFunction::kImplicitStaticFinalGetter: 473 case RawFunction::kImplicitStaticFinalGetter:
506 case RawFunction::kMethodExtractor: 474 case RawFunction::kMethodExtractor:
507 case RawFunction::kNoSuchMethodDispatcher: 475 case RawFunction::kNoSuchMethodDispatcher:
508 case RawFunction::kInvokeFieldDispatcher: 476 case RawFunction::kInvokeFieldDispatcher:
509 case RawFunction::kIrregexpFunction: 477 case RawFunction::kIrregexpFunction:
510 return true; 478 return true;
511 default: 479 default:
512 if (func.token_pos() == func.end_token_pos()) { 480 if (func.token_pos() == func.end_token_pos()) {
513 // |func| could be an implicit constructor for example. 481 // |func| could be an implicit constructor for example.
514 return true; 482 return true;
515 } 483 }
516 } 484 }
517 return false; 485 return false;
518 } 486 }
519 487
520
521 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { 488 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) {
522 if (!func.HasCode()) { 489 if (!func.HasCode()) {
523 // If the function is not compiled yet, just check whether there 490 // If the function is not compiled yet, just check whether there
524 // is a user-defined breakpoint that falls into the token 491 // is a user-defined breakpoint that falls into the token
525 // range of the function. This may be a false positive: the breakpoint 492 // range of the function. This may be a false positive: the breakpoint
526 // might be inside a local closure. 493 // might be inside a local closure.
527 Script& script = Script::Handle(zone); 494 Script& script = Script::Handle(zone);
528 BreakpointLocation* sbpt = breakpoint_locations_; 495 BreakpointLocation* sbpt = breakpoint_locations_;
529 while (sbpt != NULL) { 496 while (sbpt != NULL) {
530 script = sbpt->script(); 497 script = sbpt->script();
531 if (FunctionOverlaps(func, script, sbpt->token_pos(), 498 if (FunctionOverlaps(func, script, sbpt->token_pos(),
532 sbpt->end_token_pos())) { 499 sbpt->end_token_pos())) {
533 return true; 500 return true;
534 } 501 }
535 sbpt = sbpt->next_; 502 sbpt = sbpt->next_;
536 } 503 }
537 return false; 504 return false;
538 } 505 }
539 CodeBreakpoint* cbpt = code_breakpoints_; 506 CodeBreakpoint* cbpt = code_breakpoints_;
540 while (cbpt != NULL) { 507 while (cbpt != NULL) {
541 if (func.raw() == cbpt->function()) { 508 if (func.raw() == cbpt->function()) {
542 return true; 509 return true;
543 } 510 }
544 cbpt = cbpt->next_; 511 cbpt = cbpt->next_;
545 } 512 }
546 return false; 513 return false;
547 } 514 }
548 515
549
550 bool Debugger::HasBreakpoint(const Code& code) { 516 bool Debugger::HasBreakpoint(const Code& code) {
551 CodeBreakpoint* cbpt = code_breakpoints_; 517 CodeBreakpoint* cbpt = code_breakpoints_;
552 while (cbpt != NULL) { 518 while (cbpt != NULL) {
553 if (code.raw() == cbpt->code_) { 519 if (code.raw() == cbpt->code_) {
554 return true; 520 return true;
555 } 521 }
556 cbpt = cbpt->next_; 522 cbpt = cbpt->next_;
557 } 523 }
558 return false; 524 return false;
559 } 525 }
560 526
561
562 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const { 527 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const {
563 PrintBreakpointsListToJSONArray(breakpoint_locations_, jsarr); 528 PrintBreakpointsListToJSONArray(breakpoint_locations_, jsarr);
564 PrintBreakpointsListToJSONArray(latent_locations_, jsarr); 529 PrintBreakpointsListToJSONArray(latent_locations_, jsarr);
565 } 530 }
566 531
567
568 void Debugger::PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt, 532 void Debugger::PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
569 JSONArray* jsarr) const { 533 JSONArray* jsarr) const {
570 while (sbpt != NULL) { 534 while (sbpt != NULL) {
571 Breakpoint* bpt = sbpt->breakpoints(); 535 Breakpoint* bpt = sbpt->breakpoints();
572 while (bpt != NULL) { 536 while (bpt != NULL) {
573 jsarr->AddValue(bpt); 537 jsarr->AddValue(bpt);
574 bpt = bpt->next(); 538 bpt = bpt->next();
575 } 539 }
576 sbpt = sbpt->next_; 540 sbpt = sbpt->next_;
577 } 541 }
578 } 542 }
579 543
580
581 void Debugger::PrintSettingsToJSONObject(JSONObject* jsobj) const { 544 void Debugger::PrintSettingsToJSONObject(JSONObject* jsobj) const {
582 // This won't cut it when we support filtering by class, etc. 545 // This won't cut it when we support filtering by class, etc.
583 switch (GetExceptionPauseInfo()) { 546 switch (GetExceptionPauseInfo()) {
584 case kNoPauseOnExceptions: 547 case kNoPauseOnExceptions:
585 jsobj->AddProperty("_exceptions", "none"); 548 jsobj->AddProperty("_exceptions", "none");
586 break; 549 break;
587 case kPauseOnAllExceptions: 550 case kPauseOnAllExceptions:
588 jsobj->AddProperty("_exceptions", "all"); 551 jsobj->AddProperty("_exceptions", "all");
589 break; 552 break;
590 case kPauseOnUnhandledExceptions: 553 case kPauseOnUnhandledExceptions:
591 jsobj->AddProperty("_exceptions", "unhandled"); 554 jsobj->AddProperty("_exceptions", "unhandled");
592 break; 555 break;
593 default: 556 default:
594 UNREACHABLE(); 557 UNREACHABLE();
595 } 558 }
596 } 559 }
597 560
598
599 RawString* ActivationFrame::QualifiedFunctionName() { 561 RawString* ActivationFrame::QualifiedFunctionName() {
600 return String::New(Debugger::QualifiedFunctionName(function())); 562 return String::New(Debugger::QualifiedFunctionName(function()));
601 } 563 }
602 564
603
604 RawString* ActivationFrame::SourceUrl() { 565 RawString* ActivationFrame::SourceUrl() {
605 const Script& script = Script::Handle(SourceScript()); 566 const Script& script = Script::Handle(SourceScript());
606 return script.url(); 567 return script.url();
607 } 568 }
608 569
609
610 RawScript* ActivationFrame::SourceScript() { 570 RawScript* ActivationFrame::SourceScript() {
611 return function().script(); 571 return function().script();
612 } 572 }
613 573
614
615 RawLibrary* ActivationFrame::Library() { 574 RawLibrary* ActivationFrame::Library() {
616 const Class& cls = Class::Handle(function().origin()); 575 const Class& cls = Class::Handle(function().origin());
617 return cls.library(); 576 return cls.library();
618 } 577 }
619 578
620
621 void ActivationFrame::GetPcDescriptors() { 579 void ActivationFrame::GetPcDescriptors() {
622 if (pc_desc_.IsNull()) { 580 if (pc_desc_.IsNull()) {
623 pc_desc_ = code().pc_descriptors(); 581 pc_desc_ = code().pc_descriptors();
624 ASSERT(!pc_desc_.IsNull()); 582 ASSERT(!pc_desc_.IsNull());
625 } 583 }
626 } 584 }
627 585
628
629 // Compute token_pos_ and try_index_ and token_pos_initialized_. 586 // Compute token_pos_ and try_index_ and token_pos_initialized_.
630 TokenPosition ActivationFrame::TokenPos() { 587 TokenPosition ActivationFrame::TokenPos() {
631 if (!token_pos_initialized_) { 588 if (!token_pos_initialized_) {
632 token_pos_initialized_ = true; 589 token_pos_initialized_ = true;
633 token_pos_ = TokenPosition::kNoSource; 590 token_pos_ = TokenPosition::kNoSource;
634 GetPcDescriptors(); 591 GetPcDescriptors();
635 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); 592 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
636 uword pc_offset = pc_ - code().PayloadStart(); 593 uword pc_offset = pc_ - code().PayloadStart();
637 while (iter.MoveNext()) { 594 while (iter.MoveNext()) {
638 if (iter.PcOffset() == pc_offset) { 595 if (iter.PcOffset() == pc_offset) {
639 try_index_ = iter.TryIndex(); 596 try_index_ = iter.TryIndex();
640 token_pos_ = iter.TokenPos(); 597 token_pos_ = iter.TokenPos();
641 deopt_id_ = iter.DeoptId(); 598 deopt_id_ = iter.DeoptId();
642 break; 599 break;
643 } 600 }
644 } 601 }
645 } 602 }
646 return token_pos_; 603 return token_pos_;
647 } 604 }
648 605
649
650 intptr_t ActivationFrame::TryIndex() { 606 intptr_t ActivationFrame::TryIndex() {
651 if (!token_pos_initialized_) { 607 if (!token_pos_initialized_) {
652 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. 608 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_.
653 } 609 }
654 return try_index_; 610 return try_index_;
655 } 611 }
656 612
657
658 intptr_t ActivationFrame::DeoptId() { 613 intptr_t ActivationFrame::DeoptId() {
659 if (!token_pos_initialized_) { 614 if (!token_pos_initialized_) {
660 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. 615 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_.
661 } 616 }
662 return deopt_id_; 617 return deopt_id_;
663 } 618 }
664 619
665
666 intptr_t ActivationFrame::LineNumber() { 620 intptr_t ActivationFrame::LineNumber() {
667 // Compute line number lazily since it causes scanning of the script. 621 // Compute line number lazily since it causes scanning of the script.
668 if ((line_number_ < 0) && TokenPos().IsSourcePosition()) { 622 if ((line_number_ < 0) && TokenPos().IsSourcePosition()) {
669 const TokenPosition token_pos = TokenPos().SourcePosition(); 623 const TokenPosition token_pos = TokenPos().SourcePosition();
670 const Script& script = Script::Handle(SourceScript()); 624 const Script& script = Script::Handle(SourceScript());
671 script.GetTokenLocation(token_pos, &line_number_, NULL); 625 script.GetTokenLocation(token_pos, &line_number_, NULL);
672 } 626 }
673 return line_number_; 627 return line_number_;
674 } 628 }
675 629
676
677 intptr_t ActivationFrame::ColumnNumber() { 630 intptr_t ActivationFrame::ColumnNumber() {
678 // Compute column number lazily since it causes scanning of the script. 631 // Compute column number lazily since it causes scanning of the script.
679 if ((column_number_ < 0) && TokenPos().IsSourcePosition()) { 632 if ((column_number_ < 0) && TokenPos().IsSourcePosition()) {
680 const TokenPosition token_pos = TokenPos().SourcePosition(); 633 const TokenPosition token_pos = TokenPos().SourcePosition();
681 const Script& script = Script::Handle(SourceScript()); 634 const Script& script = Script::Handle(SourceScript());
682 if (script.HasSource()) { 635 if (script.HasSource()) {
683 script.GetTokenLocation(token_pos, &line_number_, &column_number_); 636 script.GetTokenLocation(token_pos, &line_number_, &column_number_);
684 } else { 637 } else {
685 column_number_ = -1; 638 column_number_ = -1;
686 } 639 }
687 } 640 }
688 return column_number_; 641 return column_number_;
689 } 642 }
690 643
691
692 void ActivationFrame::GetVarDescriptors() { 644 void ActivationFrame::GetVarDescriptors() {
693 if (var_descriptors_.IsNull()) { 645 if (var_descriptors_.IsNull()) {
694 Code& unoptimized_code = Code::Handle(function().unoptimized_code()); 646 Code& unoptimized_code = Code::Handle(function().unoptimized_code());
695 if (unoptimized_code.IsNull()) { 647 if (unoptimized_code.IsNull()) {
696 Thread* thread = Thread::Current(); 648 Thread* thread = Thread::Current();
697 Zone* zone = thread->zone(); 649 Zone* zone = thread->zone();
698 const Error& error = Error::Handle( 650 const Error& error = Error::Handle(
699 zone, Compiler::EnsureUnoptimizedCode(thread, function())); 651 zone, Compiler::EnsureUnoptimizedCode(thread, function()));
700 if (!error.IsNull()) { 652 if (!error.IsNull()) {
701 Exceptions::PropagateError(error); 653 Exceptions::PropagateError(error);
702 } 654 }
703 unoptimized_code ^= function().unoptimized_code(); 655 unoptimized_code ^= function().unoptimized_code();
704 } 656 }
705 ASSERT(!unoptimized_code.IsNull()); 657 ASSERT(!unoptimized_code.IsNull());
706 var_descriptors_ = unoptimized_code.GetLocalVarDescriptors(); 658 var_descriptors_ = unoptimized_code.GetLocalVarDescriptors();
707 ASSERT(!var_descriptors_.IsNull()); 659 ASSERT(!var_descriptors_.IsNull());
708 } 660 }
709 } 661 }
710 662
711
712 bool ActivationFrame::IsDebuggable() const { 663 bool ActivationFrame::IsDebuggable() const {
713 return Debugger::IsDebuggable(function()); 664 return Debugger::IsDebuggable(function());
714 } 665 }
715 666
716
717 void ActivationFrame::PrintDescriptorsError(const char* message) { 667 void ActivationFrame::PrintDescriptorsError(const char* message) {
718 OS::PrintErr("Bad descriptors: %s\n", message); 668 OS::PrintErr("Bad descriptors: %s\n", message);
719 OS::PrintErr("function %s\n", function().ToQualifiedCString()); 669 OS::PrintErr("function %s\n", function().ToQualifiedCString());
720 OS::PrintErr("pc_ %" Px "\n", pc_); 670 OS::PrintErr("pc_ %" Px "\n", pc_);
721 OS::PrintErr("deopt_id_ %" Px "\n", deopt_id_); 671 OS::PrintErr("deopt_id_ %" Px "\n", deopt_id_);
722 OS::PrintErr("context_level_ %" Px "\n", context_level_); 672 OS::PrintErr("context_level_ %" Px "\n", context_level_);
723 DisassembleToStdout formatter; 673 DisassembleToStdout formatter;
724 code().Disassemble(&formatter); 674 code().Disassemble(&formatter);
725 PcDescriptors::Handle(code().pc_descriptors()).Print(); 675 PcDescriptors::Handle(code().pc_descriptors()).Print();
726 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, 676 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames,
727 Thread::Current(), 677 Thread::Current(),
728 StackFrameIterator::kNoCrossThreadIteration); 678 StackFrameIterator::kNoCrossThreadIteration);
729 StackFrame* frame = frames.NextFrame(); 679 StackFrame* frame = frames.NextFrame();
730 while (frame != NULL) { 680 while (frame != NULL) {
731 OS::PrintErr("%s\n", frame->ToCString()); 681 OS::PrintErr("%s\n", frame->ToCString());
732 frame = frames.NextFrame(); 682 frame = frames.NextFrame();
733 } 683 }
734 OS::Abort(); 684 OS::Abort();
735 } 685 }
736 686
737
738 // Calculate the context level at the current token index of the frame. 687 // Calculate the context level at the current token index of the frame.
739 intptr_t ActivationFrame::ContextLevel() { 688 intptr_t ActivationFrame::ContextLevel() {
740 const Context& ctx = GetSavedCurrentContext(); 689 const Context& ctx = GetSavedCurrentContext();
741 if (context_level_ < 0 && !ctx.IsNull()) { 690 if (context_level_ < 0 && !ctx.IsNull()) {
742 ASSERT(!code_.is_optimized()); 691 ASSERT(!code_.is_optimized());
743 692
744 GetVarDescriptors(); 693 GetVarDescriptors();
745 intptr_t deopt_id = DeoptId(); 694 intptr_t deopt_id = DeoptId();
746 if (deopt_id == Thread::kNoDeoptId) { 695 if (deopt_id == Thread::kNoDeoptId) {
747 PrintDescriptorsError("Missing deopt id"); 696 PrintDescriptorsError("Missing deopt id");
(...skipping 13 matching lines...) Expand all
761 } 710 }
762 } 711 }
763 if (!found) { 712 if (!found) {
764 PrintDescriptorsError("Missing context level"); 713 PrintDescriptorsError("Missing context level");
765 } 714 }
766 ASSERT(context_level_ >= 0); 715 ASSERT(context_level_ >= 0);
767 } 716 }
768 return context_level_; 717 return context_level_;
769 } 718 }
770 719
771
772 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) { 720 RawObject* ActivationFrame::GetAsyncContextVariable(const String& name) {
773 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) { 721 if (!function_.IsAsyncClosure() && !function_.IsAsyncGenClosure()) {
774 return Object::null(); 722 return Object::null();
775 } 723 }
776 GetVarDescriptors(); 724 GetVarDescriptors();
777 intptr_t var_desc_len = var_descriptors_.Length(); 725 intptr_t var_desc_len = var_descriptors_.Length();
778 for (intptr_t i = 0; i < var_desc_len; i++) { 726 for (intptr_t i = 0; i < var_desc_len; i++) {
779 RawLocalVarDescriptors::VarInfo var_info; 727 RawLocalVarDescriptors::VarInfo var_info;
780 var_descriptors_.GetInfo(i, &var_info); 728 var_descriptors_.GetInfo(i, &var_info);
781 if (var_descriptors_.GetName(i) == name.raw()) { 729 if (var_descriptors_.GetName(i) == name.raw()) {
782 const int8_t kind = var_info.kind(); 730 const int8_t kind = var_info.kind();
783 if (!live_frame_) { 731 if (!live_frame_) {
784 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 732 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
785 } 733 }
786 if (kind == RawLocalVarDescriptors::kStackVar) { 734 if (kind == RawLocalVarDescriptors::kStackVar) {
787 return GetStackVar(var_info.index()); 735 return GetStackVar(var_info.index());
788 } else { 736 } else {
789 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 737 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
790 if (!live_frame_) { 738 if (!live_frame_) {
791 ASSERT(!ctx_.IsNull()); 739 ASSERT(!ctx_.IsNull());
792 return ctx_.At(var_info.index()); 740 return ctx_.At(var_info.index());
793 } 741 }
794 return GetContextVar(var_info.scope_id, var_info.index()); 742 return GetContextVar(var_info.scope_id, var_info.index());
795 } 743 }
796 } 744 }
797 } 745 }
798 return Object::null(); 746 return Object::null();
799 } 747 }
800 748
801
802 RawObject* ActivationFrame::GetAsyncCompleter() { 749 RawObject* ActivationFrame::GetAsyncCompleter() {
803 return GetAsyncContextVariable(Symbols::AsyncCompleter()); 750 return GetAsyncContextVariable(Symbols::AsyncCompleter());
804 } 751 }
805 752
806
807 RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) { 753 RawObject* ActivationFrame::GetAsyncCompleterAwaiter(const Object& completer) {
808 const Class& sync_completer_cls = Class::Handle(completer.clazz()); 754 const Class& sync_completer_cls = Class::Handle(completer.clazz());
809 ASSERT(!sync_completer_cls.IsNull()); 755 ASSERT(!sync_completer_cls.IsNull());
810 const Class& completer_cls = Class::Handle(sync_completer_cls.SuperClass()); 756 const Class& completer_cls = Class::Handle(sync_completer_cls.SuperClass());
811 const Field& future_field = 757 const Field& future_field =
812 Field::Handle(completer_cls.LookupInstanceFieldAllowPrivate( 758 Field::Handle(completer_cls.LookupInstanceFieldAllowPrivate(
813 Symbols::CompleterFuture())); 759 Symbols::CompleterFuture()));
814 ASSERT(!future_field.IsNull()); 760 ASSERT(!future_field.IsNull());
815 Instance& future = Instance::Handle(); 761 Instance& future = Instance::Handle();
816 future ^= Instance::Cast(completer).GetField(future_field); 762 future ^= Instance::Cast(completer).GetField(future_field);
817 if (future.IsNull()) { 763 if (future.IsNull()) {
818 // The completer object may not be fully initialized yet. 764 // The completer object may not be fully initialized yet.
819 return Object::null(); 765 return Object::null();
820 } 766 }
821 const Class& future_cls = Class::Handle(future.clazz()); 767 const Class& future_cls = Class::Handle(future.clazz());
822 ASSERT(!future_cls.IsNull()); 768 ASSERT(!future_cls.IsNull());
823 const Field& awaiter_field = Field::Handle( 769 const Field& awaiter_field = Field::Handle(
824 future_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter())); 770 future_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
825 ASSERT(!awaiter_field.IsNull()); 771 ASSERT(!awaiter_field.IsNull());
826 return future.GetField(awaiter_field); 772 return future.GetField(awaiter_field);
827 } 773 }
828 774
829
830 RawObject* ActivationFrame::GetAsyncStreamControllerStream() { 775 RawObject* ActivationFrame::GetAsyncStreamControllerStream() {
831 return GetAsyncContextVariable(Symbols::ControllerStream()); 776 return GetAsyncContextVariable(Symbols::ControllerStream());
832 } 777 }
833 778
834
835 RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter( 779 RawObject* ActivationFrame::GetAsyncStreamControllerStreamAwaiter(
836 const Object& stream) { 780 const Object& stream) {
837 const Class& stream_cls = Class::Handle(stream.clazz()); 781 const Class& stream_cls = Class::Handle(stream.clazz());
838 ASSERT(!stream_cls.IsNull()); 782 ASSERT(!stream_cls.IsNull());
839 const Class& stream_impl_cls = Class::Handle(stream_cls.SuperClass()); 783 const Class& stream_impl_cls = Class::Handle(stream_cls.SuperClass());
840 const Field& awaiter_field = Field::Handle( 784 const Field& awaiter_field = Field::Handle(
841 stream_impl_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter())); 785 stream_impl_cls.LookupInstanceFieldAllowPrivate(Symbols::_Awaiter()));
842 ASSERT(!awaiter_field.IsNull()); 786 ASSERT(!awaiter_field.IsNull());
843 return Instance::Cast(stream).GetField(awaiter_field); 787 return Instance::Cast(stream).GetField(awaiter_field);
844 } 788 }
845 789
846
847 RawObject* ActivationFrame::GetAsyncAwaiter() { 790 RawObject* ActivationFrame::GetAsyncAwaiter() {
848 const Object& async_stream_controller_stream = 791 const Object& async_stream_controller_stream =
849 Object::Handle(GetAsyncStreamControllerStream()); 792 Object::Handle(GetAsyncStreamControllerStream());
850 if (!async_stream_controller_stream.IsNull()) { 793 if (!async_stream_controller_stream.IsNull()) {
851 return GetAsyncStreamControllerStreamAwaiter( 794 return GetAsyncStreamControllerStreamAwaiter(
852 async_stream_controller_stream); 795 async_stream_controller_stream);
853 } 796 }
854 const Object& completer = Object::Handle(GetAsyncCompleter()); 797 const Object& completer = Object::Handle(GetAsyncCompleter());
855 if (!completer.IsNull()) { 798 if (!completer.IsNull()) {
856 return GetAsyncCompleterAwaiter(completer); 799 return GetAsyncCompleterAwaiter(completer);
857 } 800 }
858 return Object::null(); 801 return Object::null();
859 } 802 }
860 803
861
862 RawObject* ActivationFrame::GetCausalStack() { 804 RawObject* ActivationFrame::GetCausalStack() {
863 return GetAsyncContextVariable(Symbols::AsyncStackTraceVar()); 805 return GetAsyncContextVariable(Symbols::AsyncStackTraceVar());
864 } 806 }
865 807
866
867 bool ActivationFrame::HandlesException(const Instance& exc_obj) { 808 bool ActivationFrame::HandlesException(const Instance& exc_obj) {
868 if ((kind_ == kAsyncSuspensionMarker) || (kind_ == kAsyncCausal)) { 809 if ((kind_ == kAsyncSuspensionMarker) || (kind_ == kAsyncCausal)) {
869 // These frames are historical. 810 // These frames are historical.
870 return false; 811 return false;
871 } 812 }
872 intptr_t try_index = TryIndex(); 813 intptr_t try_index = TryIndex();
873 if (try_index < 0) { 814 if (try_index < 0) {
874 return false; 815 return false;
875 } 816 }
876 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); 817 ExceptionHandlers& handlers = ExceptionHandlers::Handle();
(...skipping 27 matching lines...) Expand all
904 Object::null_type_arguments(), NULL)) { 845 Object::null_type_arguments(), NULL)) {
905 return true; 846 return true;
906 } 847 }
907 } 848 }
908 } 849 }
909 try_index = handlers.OuterTryIndex(try_index); 850 try_index = handlers.OuterTryIndex(try_index);
910 } 851 }
911 return false; 852 return false;
912 } 853 }
913 854
914
915 void ActivationFrame::ExtractTokenPositionFromAsyncClosure() { 855 void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
916 // Attempt to determine the token position from the async closure. 856 // Attempt to determine the token position from the async closure.
917 ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure()); 857 ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
918 // This should only be called on frames that aren't active on the stack. 858 // This should only be called on frames that aren't active on the stack.
919 ASSERT(fp() == 0); 859 ASSERT(fp() == 0);
920 const Array& await_to_token_map = 860 const Array& await_to_token_map =
921 Array::Handle(code_.await_token_positions()); 861 Array::Handle(code_.await_token_positions());
922 if (await_to_token_map.IsNull()) { 862 if (await_to_token_map.IsNull()) {
923 // No mapping. 863 // No mapping.
924 return; 864 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 // TODO(johnmccutchan): Is this heuristic precise enough? 898 // TODO(johnmccutchan): Is this heuristic precise enough?
959 if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) { 899 if (iter.TryIndex() != CatchClauseNode::kInvalidTryIndex) {
960 if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) { 900 if ((try_index_ == -1) || (iter.TryIndex() < try_index_)) {
961 try_index_ = iter.TryIndex(); 901 try_index_ = iter.TryIndex();
962 } 902 }
963 } 903 }
964 } 904 }
965 } 905 }
966 } 906 }
967 907
968
969 bool ActivationFrame::IsAsyncMachinery() const { 908 bool ActivationFrame::IsAsyncMachinery() const {
970 Isolate* isolate = Isolate::Current(); 909 Isolate* isolate = Isolate::Current();
971 if (function_.raw() == isolate->object_store()->complete_on_async_return()) { 910 if (function_.raw() == isolate->object_store()->complete_on_async_return()) {
972 // We are completing an async function's completer. 911 // We are completing an async function's completer.
973 return true; 912 return true;
974 } 913 }
975 if (function_.Owner() == 914 if (function_.Owner() ==
976 isolate->object_store()->async_star_stream_controller()) { 915 isolate->object_store()->async_star_stream_controller()) {
977 // We are inside the async* stream controller code. 916 // We are inside the async* stream controller code.
978 return true; 917 return true;
979 } 918 }
980 return false; 919 return false;
981 } 920 }
982 921
983
984 // Get the saved current context of this activation. 922 // Get the saved current context of this activation.
985 const Context& ActivationFrame::GetSavedCurrentContext() { 923 const Context& ActivationFrame::GetSavedCurrentContext() {
986 if (!ctx_.IsNull()) return ctx_; 924 if (!ctx_.IsNull()) return ctx_;
987 GetVarDescriptors(); 925 GetVarDescriptors();
988 intptr_t var_desc_len = var_descriptors_.Length(); 926 intptr_t var_desc_len = var_descriptors_.Length();
989 Object& obj = Object::Handle(); 927 Object& obj = Object::Handle();
990 for (intptr_t i = 0; i < var_desc_len; i++) { 928 for (intptr_t i = 0; i < var_desc_len; i++) {
991 RawLocalVarDescriptors::VarInfo var_info; 929 RawLocalVarDescriptors::VarInfo var_info;
992 var_descriptors_.GetInfo(i, &var_info); 930 var_descriptors_.GetInfo(i, &var_info);
993 const int8_t kind = var_info.kind(); 931 const int8_t kind = var_info.kind();
(...skipping 12 matching lines...) Expand all
1006 ctx_ ^= Context::Cast(obj).raw(); 944 ctx_ ^= Context::Cast(obj).raw();
1007 } else { 945 } else {
1008 ASSERT(obj.IsNull()); 946 ASSERT(obj.IsNull());
1009 } 947 }
1010 return ctx_; 948 return ctx_;
1011 } 949 }
1012 } 950 }
1013 return ctx_; 951 return ctx_;
1014 } 952 }
1015 953
1016
1017 RawObject* ActivationFrame::GetAsyncOperation() { 954 RawObject* ActivationFrame::GetAsyncOperation() {
1018 GetVarDescriptors(); 955 GetVarDescriptors();
1019 intptr_t var_desc_len = var_descriptors_.Length(); 956 intptr_t var_desc_len = var_descriptors_.Length();
1020 for (intptr_t i = 0; i < var_desc_len; i++) { 957 for (intptr_t i = 0; i < var_desc_len; i++) {
1021 RawLocalVarDescriptors::VarInfo var_info; 958 RawLocalVarDescriptors::VarInfo var_info;
1022 var_descriptors_.GetInfo(i, &var_info); 959 var_descriptors_.GetInfo(i, &var_info);
1023 if (var_descriptors_.GetName(i) == Symbols::AsyncOperation().raw()) { 960 if (var_descriptors_.GetName(i) == Symbols::AsyncOperation().raw()) {
1024 const int8_t kind = var_info.kind(); 961 const int8_t kind = var_info.kind();
1025 if (kind == RawLocalVarDescriptors::kStackVar) { 962 if (kind == RawLocalVarDescriptors::kStackVar) {
1026 return GetStackVar(var_info.index()); 963 return GetStackVar(var_info.index());
1027 } else { 964 } else {
1028 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 965 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
1029 return GetContextVar(var_info.scope_id, var_info.index()); 966 return GetContextVar(var_info.scope_id, var_info.index());
1030 } 967 }
1031 } 968 }
1032 } 969 }
1033 return Object::null(); 970 return Object::null();
1034 } 971 }
1035 972
1036
1037 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 973 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
1038 const Instance& exc_obj) const { 974 const Instance& exc_obj) const {
1039 for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) { 975 for (intptr_t frame_index = 0; frame_index < Length(); frame_index++) {
1040 ActivationFrame* frame = FrameAt(frame_index); 976 ActivationFrame* frame = FrameAt(frame_index);
1041 if (frame->HandlesException(exc_obj)) { 977 if (frame->HandlesException(exc_obj)) {
1042 return frame; 978 return frame;
1043 } 979 }
1044 } 980 }
1045 return NULL; 981 return NULL;
1046 } 982 }
1047 983
1048
1049 void ActivationFrame::GetDescIndices() { 984 void ActivationFrame::GetDescIndices() {
1050 if (vars_initialized_) { 985 if (vars_initialized_) {
1051 return; 986 return;
1052 } 987 }
1053 GetVarDescriptors(); 988 GetVarDescriptors();
1054 989
1055 TokenPosition activation_token_pos = TokenPos(); 990 TokenPosition activation_token_pos = TokenPos();
1056 if (!activation_token_pos.IsDebugPause() || !live_frame_) { 991 if (!activation_token_pos.IsDebugPause() || !live_frame_) {
1057 // We don't have a token position for this frame, so can't determine 992 // We don't have a token position for this frame, so can't determine
1058 // which variables are visible. 993 // which variables are visible.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 // No duplicate name found. Add the current descriptor index to the 1049 // No duplicate name found. Add the current descriptor index to the
1115 // list of visible variables. 1050 // list of visible variables.
1116 desc_indices_.Add(cur_idx); 1051 desc_indices_.Add(cur_idx);
1117 var_names.Add(&var_name); 1052 var_names.Add(&var_name);
1118 } 1053 }
1119 } 1054 }
1120 } 1055 }
1121 vars_initialized_ = true; 1056 vars_initialized_ = true;
1122 } 1057 }
1123 1058
1124
1125 intptr_t ActivationFrame::NumLocalVariables() { 1059 intptr_t ActivationFrame::NumLocalVariables() {
1126 GetDescIndices(); 1060 GetDescIndices();
1127 return desc_indices_.length(); 1061 return desc_indices_.length();
1128 } 1062 }
1129 1063
1130
1131 DART_FORCE_INLINE static RawObject* GetVariableValue(uword addr) { 1064 DART_FORCE_INLINE static RawObject* GetVariableValue(uword addr) {
1132 return *reinterpret_cast<RawObject**>(addr); 1065 return *reinterpret_cast<RawObject**>(addr);
1133 } 1066 }
1134 1067
1135
1136 RawObject* ActivationFrame::GetParameter(intptr_t index) { 1068 RawObject* ActivationFrame::GetParameter(intptr_t index) {
1137 intptr_t num_parameters = function().num_fixed_parameters(); 1069 intptr_t num_parameters = function().num_fixed_parameters();
1138 ASSERT(0 <= index && index < num_parameters); 1070 ASSERT(0 <= index && index < num_parameters);
1139 1071
1140 if (function().NumOptionalParameters() > 0) { 1072 if (function().NumOptionalParameters() > 0) {
1141 // If the function has optional parameters, the first positional parameter 1073 // If the function has optional parameters, the first positional parameter
1142 // can be in a number of places in the caller's frame depending on how many 1074 // can be in a number of places in the caller's frame depending on how many
1143 // were actually supplied at the call site, but they are copied to a fixed 1075 // were actually supplied at the call site, but they are copied to a fixed
1144 // place in the callee's frame. 1076 // place in the callee's frame.
1145 return GetVariableValue( 1077 return GetVariableValue(
1146 LocalVarAddress(fp(), (kFirstLocalSlotFromFp - index))); 1078 LocalVarAddress(fp(), (kFirstLocalSlotFromFp - index)));
1147 } else { 1079 } else {
1148 intptr_t reverse_index = num_parameters - index; 1080 intptr_t reverse_index = num_parameters - index;
1149 return GetVariableValue(ParamAddress(fp(), reverse_index)); 1081 return GetVariableValue(ParamAddress(fp(), reverse_index));
1150 } 1082 }
1151 } 1083 }
1152 1084
1153
1154 RawObject* ActivationFrame::GetClosure() { 1085 RawObject* ActivationFrame::GetClosure() {
1155 ASSERT(function().IsClosureFunction()); 1086 ASSERT(function().IsClosureFunction());
1156 return GetParameter(0); 1087 return GetParameter(0);
1157 } 1088 }
1158 1089
1159
1160 RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) { 1090 RawObject* ActivationFrame::GetStackVar(intptr_t slot_index) {
1161 if (deopt_frame_.IsNull()) { 1091 if (deopt_frame_.IsNull()) {
1162 return GetVariableValue(LocalVarAddress(fp(), slot_index)); 1092 return GetVariableValue(LocalVarAddress(fp(), slot_index));
1163 } else { 1093 } else {
1164 return deopt_frame_.At(LocalVarIndex(deopt_frame_offset_, slot_index)); 1094 return deopt_frame_.At(LocalVarIndex(deopt_frame_offset_, slot_index));
1165 } 1095 }
1166 } 1096 }
1167 1097
1168
1169 bool ActivationFrame::IsRewindable() const { 1098 bool ActivationFrame::IsRewindable() const {
1170 if (deopt_frame_.IsNull()) { 1099 if (deopt_frame_.IsNull()) {
1171 return true; 1100 return true;
1172 } 1101 }
1173 // TODO(turnidge): This is conservative. It looks at all values in 1102 // TODO(turnidge): This is conservative. It looks at all values in
1174 // the deopt_frame_ even though some of them may correspond to other 1103 // the deopt_frame_ even though some of them may correspond to other
1175 // inlined frames. 1104 // inlined frames.
1176 Object& obj = Object::Handle(); 1105 Object& obj = Object::Handle();
1177 for (int i = 0; i < deopt_frame_.Length(); i++) { 1106 for (int i = 0; i < deopt_frame_.Length(); i++) {
1178 obj = deopt_frame_.At(i); 1107 obj = deopt_frame_.At(i);
1179 if (obj.raw() == Symbols::OptimizedOut().raw()) { 1108 if (obj.raw() == Symbols::OptimizedOut().raw()) {
1180 return false; 1109 return false;
1181 } 1110 }
1182 } 1111 }
1183 return true; 1112 return true;
1184 } 1113 }
1185 1114
1186
1187 void ActivationFrame::PrintContextMismatchError(intptr_t ctx_slot, 1115 void ActivationFrame::PrintContextMismatchError(intptr_t ctx_slot,
1188 intptr_t frame_ctx_level, 1116 intptr_t frame_ctx_level,
1189 intptr_t var_ctx_level) { 1117 intptr_t var_ctx_level) {
1190 OS::PrintErr( 1118 OS::PrintErr(
1191 "-------------------------\n" 1119 "-------------------------\n"
1192 "Encountered context mismatch\n" 1120 "Encountered context mismatch\n"
1193 "\tctx_slot: %" Pd 1121 "\tctx_slot: %" Pd
1194 "\n" 1122 "\n"
1195 "\tframe_ctx_level: %" Pd 1123 "\tframe_ctx_level: %" Pd
1196 "\n" 1124 "\n"
(...skipping 28 matching lines...) Expand all
1225 Thread::Current(), 1153 Thread::Current(),
1226 StackFrameIterator::kNoCrossThreadIteration); 1154 StackFrameIterator::kNoCrossThreadIteration);
1227 StackFrame* frame = iterator.NextFrame(); 1155 StackFrame* frame = iterator.NextFrame();
1228 intptr_t num = 0; 1156 intptr_t num = 0;
1229 while ((frame != NULL)) { 1157 while ((frame != NULL)) {
1230 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); 1158 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
1231 frame = iterator.NextFrame(); 1159 frame = iterator.NextFrame();
1232 } 1160 }
1233 } 1161 }
1234 1162
1235
1236 void ActivationFrame::VariableAt(intptr_t i, 1163 void ActivationFrame::VariableAt(intptr_t i,
1237 String* name, 1164 String* name,
1238 TokenPosition* declaration_token_pos, 1165 TokenPosition* declaration_token_pos,
1239 TokenPosition* visible_start_token_pos, 1166 TokenPosition* visible_start_token_pos,
1240 TokenPosition* visible_end_token_pos, 1167 TokenPosition* visible_end_token_pos,
1241 Object* value) { 1168 Object* value) {
1242 GetDescIndices(); 1169 GetDescIndices();
1243 ASSERT(i < desc_indices_.length()); 1170 ASSERT(i < desc_indices_.length());
1244 intptr_t desc_index = desc_indices_[i]; 1171 intptr_t desc_index = desc_indices_[i];
1245 ASSERT(name != NULL); 1172 ASSERT(name != NULL);
(...skipping 11 matching lines...) Expand all
1257 ASSERT(value != NULL); 1184 ASSERT(value != NULL);
1258 const int8_t kind = var_info.kind(); 1185 const int8_t kind = var_info.kind();
1259 if (kind == RawLocalVarDescriptors::kStackVar) { 1186 if (kind == RawLocalVarDescriptors::kStackVar) {
1260 *value = GetStackVar(var_info.index()); 1187 *value = GetStackVar(var_info.index());
1261 } else { 1188 } else {
1262 ASSERT(kind == RawLocalVarDescriptors::kContextVar); 1189 ASSERT(kind == RawLocalVarDescriptors::kContextVar);
1263 *value = GetContextVar(var_info.scope_id, var_info.index()); 1190 *value = GetContextVar(var_info.scope_id, var_info.index());
1264 } 1191 }
1265 } 1192 }
1266 1193
1267
1268 RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level, 1194 RawObject* ActivationFrame::GetContextVar(intptr_t var_ctx_level,
1269 intptr_t ctx_slot) { 1195 intptr_t ctx_slot) {
1270 const Context& ctx = GetSavedCurrentContext(); 1196 const Context& ctx = GetSavedCurrentContext();
1271 ASSERT(!ctx.IsNull()); 1197 ASSERT(!ctx.IsNull());
1272 1198
1273 // The context level at the PC/token index of this activation frame. 1199 // The context level at the PC/token index of this activation frame.
1274 intptr_t frame_ctx_level = ContextLevel(); 1200 intptr_t frame_ctx_level = ContextLevel();
1275 1201
1276 intptr_t level_diff = frame_ctx_level - var_ctx_level; 1202 intptr_t level_diff = frame_ctx_level - var_ctx_level;
1277 if (level_diff == 0) { 1203 if (level_diff == 0) {
(...skipping 12 matching lines...) Expand all
1290 if (var_ctx.IsNull() || (ctx_slot < 0) || 1216 if (var_ctx.IsNull() || (ctx_slot < 0) ||
1291 (ctx_slot >= var_ctx.num_variables())) { 1217 (ctx_slot >= var_ctx.num_variables())) {
1292 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level); 1218 PrintContextMismatchError(ctx_slot, frame_ctx_level, var_ctx_level);
1293 } 1219 }
1294 ASSERT(!var_ctx.IsNull()); 1220 ASSERT(!var_ctx.IsNull());
1295 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables())); 1221 ASSERT((ctx_slot >= 0) && (ctx_slot < var_ctx.num_variables()));
1296 return var_ctx.At(ctx_slot); 1222 return var_ctx.At(ctx_slot);
1297 } 1223 }
1298 } 1224 }
1299 1225
1300
1301 RawArray* ActivationFrame::GetLocalVariables() { 1226 RawArray* ActivationFrame::GetLocalVariables() {
1302 GetDescIndices(); 1227 GetDescIndices();
1303 intptr_t num_variables = desc_indices_.length(); 1228 intptr_t num_variables = desc_indices_.length();
1304 String& var_name = String::Handle(); 1229 String& var_name = String::Handle();
1305 Object& value = Instance::Handle(); 1230 Object& value = Instance::Handle();
1306 const Array& list = Array::Handle(Array::New(2 * num_variables)); 1231 const Array& list = Array::Handle(Array::New(2 * num_variables));
1307 for (intptr_t i = 0; i < num_variables; i++) { 1232 for (intptr_t i = 0; i < num_variables; i++) {
1308 TokenPosition ignore; 1233 TokenPosition ignore;
1309 VariableAt(i, &var_name, &ignore, &ignore, &ignore, &value); 1234 VariableAt(i, &var_name, &ignore, &ignore, &ignore, &value);
1310 list.SetAt(2 * i, var_name); 1235 list.SetAt(2 * i, var_name);
1311 list.SetAt((2 * i) + 1, value); 1236 list.SetAt((2 * i) + 1, value);
1312 } 1237 }
1313 return list.raw(); 1238 return list.raw();
1314 } 1239 }
1315 1240
1316
1317 RawObject* ActivationFrame::GetReceiver() { 1241 RawObject* ActivationFrame::GetReceiver() {
1318 GetDescIndices(); 1242 GetDescIndices();
1319 intptr_t num_variables = desc_indices_.length(); 1243 intptr_t num_variables = desc_indices_.length();
1320 String& var_name = String::Handle(); 1244 String& var_name = String::Handle();
1321 Instance& value = Instance::Handle(); 1245 Instance& value = Instance::Handle();
1322 for (intptr_t i = 0; i < num_variables; i++) { 1246 for (intptr_t i = 0; i < num_variables; i++) {
1323 TokenPosition ignore; 1247 TokenPosition ignore;
1324 VariableAt(i, &var_name, &ignore, &ignore, &ignore, &value); 1248 VariableAt(i, &var_name, &ignore, &ignore, &ignore, &value);
1325 if (var_name.Equals(Symbols::This())) { 1249 if (var_name.Equals(Symbols::This())) {
1326 return value.raw(); 1250 return value.raw();
1327 } 1251 }
1328 } 1252 }
1329 return Symbols::OptimizedOut().raw(); 1253 return Symbols::OptimizedOut().raw();
1330 } 1254 }
1331 1255
1332
1333 static bool IsSyntheticVariableName(const String& var_name) { 1256 static bool IsSyntheticVariableName(const String& var_name) {
1334 return (var_name.Length() >= 1) && (var_name.CharAt(0) == ':'); 1257 return (var_name.Length() >= 1) && (var_name.CharAt(0) == ':');
1335 } 1258 }
1336 1259
1337
1338 static bool IsPrivateVariableName(const String& var_name) { 1260 static bool IsPrivateVariableName(const String& var_name) {
1339 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_'); 1261 return (var_name.Length() >= 1) && (var_name.CharAt(0) == '_');
1340 } 1262 }
1341 1263
1342
1343 RawObject* ActivationFrame::Evaluate(const String& expr, 1264 RawObject* ActivationFrame::Evaluate(const String& expr,
1344 const GrowableObjectArray& param_names, 1265 const GrowableObjectArray& param_names,
1345 const GrowableObjectArray& param_values) { 1266 const GrowableObjectArray& param_values) {
1346 GetDescIndices(); 1267 GetDescIndices();
1347 String& name = String::Handle(); 1268 String& name = String::Handle();
1348 String& existing_name = String::Handle(); 1269 String& existing_name = String::Handle();
1349 Object& value = Instance::Handle(); 1270 Object& value = Instance::Handle();
1350 intptr_t num_variables = desc_indices_.length(); 1271 intptr_t num_variables = desc_indices_.length();
1351 for (intptr_t i = 0; i < num_variables; i++) { 1272 for (intptr_t i = 0; i < num_variables; i++) {
1352 TokenPosition ignore; 1273 TokenPosition ignore;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 } 1308 }
1388 const Instance& inst = Instance::Cast(receiver); 1309 const Instance& inst = Instance::Cast(receiver);
1389 return inst.Evaluate(method_cls, expr, 1310 return inst.Evaluate(method_cls, expr,
1390 Array::Handle(Array::MakeFixedLength(param_names)), 1311 Array::Handle(Array::MakeFixedLength(param_names)),
1391 Array::Handle(Array::MakeFixedLength(param_values))); 1312 Array::Handle(Array::MakeFixedLength(param_values)));
1392 } 1313 }
1393 UNREACHABLE(); 1314 UNREACHABLE();
1394 return Object::null(); 1315 return Object::null();
1395 } 1316 }
1396 1317
1397
1398 const char* ActivationFrame::ToCString() { 1318 const char* ActivationFrame::ToCString() {
1399 const String& url = String::Handle(SourceUrl()); 1319 const String& url = String::Handle(SourceUrl());
1400 intptr_t line = LineNumber(); 1320 intptr_t line = LineNumber();
1401 const char* func_name = Debugger::QualifiedFunctionName(function()); 1321 const char* func_name = Debugger::QualifiedFunctionName(function());
1402 return Thread::Current()->zone()->PrintToString( 1322 return Thread::Current()->zone()->PrintToString(
1403 "[ Frame pc(0x%" Px ") fp(0x%" Px ") sp(0x%" Px 1323 "[ Frame pc(0x%" Px ") fp(0x%" Px ") sp(0x%" Px
1404 ")\n" 1324 ")\n"
1405 "\tfunction = %s\n" 1325 "\tfunction = %s\n"
1406 "\turl = %s\n" 1326 "\turl = %s\n"
1407 "\tline = %" Pd 1327 "\tline = %" Pd
1408 "\n" 1328 "\n"
1409 "\tcontext = %s\n" 1329 "\tcontext = %s\n"
1410 "\tcontext level = %" Pd " ]\n", 1330 "\tcontext level = %" Pd " ]\n",
1411 pc(), fp(), sp(), func_name, url.ToCString(), line, ctx_.ToCString(), 1331 pc(), fp(), sp(), func_name, url.ToCString(), line, ctx_.ToCString(),
1412 ContextLevel()); 1332 ContextLevel());
1413 } 1333 }
1414 1334
1415
1416 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) { 1335 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) {
1417 if (kind_ == kRegular) { 1336 if (kind_ == kRegular) {
1418 PrintToJSONObjectRegular(jsobj, full); 1337 PrintToJSONObjectRegular(jsobj, full);
1419 } else if (kind_ == kAsyncCausal) { 1338 } else if (kind_ == kAsyncCausal) {
1420 PrintToJSONObjectAsyncCausal(jsobj, full); 1339 PrintToJSONObjectAsyncCausal(jsobj, full);
1421 } else if (kind_ == kAsyncSuspensionMarker) { 1340 } else if (kind_ == kAsyncSuspensionMarker) {
1422 PrintToJSONObjectAsyncSuspensionMarker(jsobj, full); 1341 PrintToJSONObjectAsyncSuspensionMarker(jsobj, full);
1423 } else if (kind_ == kAsyncActivation) { 1342 } else if (kind_ == kAsyncActivation) {
1424 PrintToJSONObjectAsyncActivation(jsobj, full); 1343 PrintToJSONObjectAsyncActivation(jsobj, full);
1425 } else { 1344 } else {
1426 UNIMPLEMENTED(); 1345 UNIMPLEMENTED();
1427 } 1346 }
1428 } 1347 }
1429 1348
1430
1431 void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) { 1349 void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) {
1432 const Script& script = Script::Handle(SourceScript()); 1350 const Script& script = Script::Handle(SourceScript());
1433 jsobj->AddProperty("type", "Frame"); 1351 jsobj->AddProperty("type", "Frame");
1434 jsobj->AddProperty("kind", KindToCString(kind_)); 1352 jsobj->AddProperty("kind", KindToCString(kind_));
1435 const TokenPosition pos = TokenPos().SourcePosition(); 1353 const TokenPosition pos = TokenPos().SourcePosition();
1436 jsobj->AddLocation(script, pos); 1354 jsobj->AddLocation(script, pos);
1437 jsobj->AddProperty("function", function(), !full); 1355 jsobj->AddProperty("function", function(), !full);
1438 jsobj->AddProperty("code", code()); 1356 jsobj->AddProperty("code", code());
1439 if (full) { 1357 if (full) {
1440 // TODO(cutch): The old "full" script usage no longer fits 1358 // TODO(cutch): The old "full" script usage no longer fits
(...skipping 26 matching lines...) Expand all
1467 jsvar.AddProperty("declarationTokenPos", declaration_token_pos); 1385 jsvar.AddProperty("declarationTokenPos", declaration_token_pos);
1468 // When the variable becomes visible to the scope. 1386 // When the variable becomes visible to the scope.
1469 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos); 1387 jsvar.AddProperty("scopeStartTokenPos", visible_start_token_pos);
1470 // When the variable stops being visible to the scope. 1388 // When the variable stops being visible to the scope.
1471 jsvar.AddProperty("scopeEndTokenPos", visible_end_token_pos); 1389 jsvar.AddProperty("scopeEndTokenPos", visible_end_token_pos);
1472 } 1390 }
1473 } 1391 }
1474 } 1392 }
1475 } 1393 }
1476 1394
1477
1478 void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj, 1395 void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj,
1479 bool full) { 1396 bool full) {
1480 jsobj->AddProperty("type", "Frame"); 1397 jsobj->AddProperty("type", "Frame");
1481 jsobj->AddProperty("kind", KindToCString(kind_)); 1398 jsobj->AddProperty("kind", KindToCString(kind_));
1482 const Script& script = Script::Handle(SourceScript()); 1399 const Script& script = Script::Handle(SourceScript());
1483 const TokenPosition pos = TokenPos().SourcePosition(); 1400 const TokenPosition pos = TokenPos().SourcePosition();
1484 jsobj->AddLocation(script, pos); 1401 jsobj->AddLocation(script, pos);
1485 jsobj->AddProperty("function", function(), !full); 1402 jsobj->AddProperty("function", function(), !full);
1486 jsobj->AddProperty("code", code()); 1403 jsobj->AddProperty("code", code());
1487 if (full) { 1404 if (full) {
1488 // TODO(cutch): The old "full" script usage no longer fits 1405 // TODO(cutch): The old "full" script usage no longer fits
1489 // in the world where we pass the script as part of the 1406 // in the world where we pass the script as part of the
1490 // location. 1407 // location.
1491 jsobj->AddProperty("script", script, !full); 1408 jsobj->AddProperty("script", script, !full);
1492 } 1409 }
1493 } 1410 }
1494 1411
1495
1496 void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, 1412 void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj,
1497 bool full) { 1413 bool full) {
1498 jsobj->AddProperty("type", "Frame"); 1414 jsobj->AddProperty("type", "Frame");
1499 jsobj->AddProperty("kind", KindToCString(kind_)); 1415 jsobj->AddProperty("kind", KindToCString(kind_));
1500 jsobj->AddProperty("marker", "AsynchronousSuspension"); 1416 jsobj->AddProperty("marker", "AsynchronousSuspension");
1501 } 1417 }
1502 1418
1503
1504 void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj, 1419 void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj,
1505 bool full) { 1420 bool full) {
1506 jsobj->AddProperty("type", "Frame"); 1421 jsobj->AddProperty("type", "Frame");
1507 jsobj->AddProperty("kind", KindToCString(kind_)); 1422 jsobj->AddProperty("kind", KindToCString(kind_));
1508 const Script& script = Script::Handle(SourceScript()); 1423 const Script& script = Script::Handle(SourceScript());
1509 const TokenPosition pos = TokenPos().SourcePosition(); 1424 const TokenPosition pos = TokenPos().SourcePosition();
1510 jsobj->AddLocation(script, pos); 1425 jsobj->AddLocation(script, pos);
1511 jsobj->AddProperty("function", function(), !full); 1426 jsobj->AddProperty("function", function(), !full);
1512 jsobj->AddProperty("code", code()); 1427 jsobj->AddProperty("code", code());
1513 if (full) { 1428 if (full) {
1514 // TODO(cutch): The old "full" script usage no longer fits 1429 // TODO(cutch): The old "full" script usage no longer fits
1515 // in the world where we pass the script as part of the 1430 // in the world where we pass the script as part of the
1516 // location. 1431 // location.
1517 jsobj->AddProperty("script", script, !full); 1432 jsobj->AddProperty("script", script, !full);
1518 } 1433 }
1519 } 1434 }
1520 1435
1521
1522 static bool IsFunctionVisible(const Function& function) { 1436 static bool IsFunctionVisible(const Function& function) {
1523 return FLAG_show_invisible_frames || function.is_visible(); 1437 return FLAG_show_invisible_frames || function.is_visible();
1524 } 1438 }
1525 1439
1526
1527 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { 1440 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
1528 if (IsFunctionVisible(frame->function())) { 1441 if (IsFunctionVisible(frame->function())) {
1529 trace_.Add(frame); 1442 trace_.Add(frame);
1530 } 1443 }
1531 } 1444 }
1532 1445
1533
1534 void DebuggerStackTrace::AddMarker(ActivationFrame::Kind marker) { 1446 void DebuggerStackTrace::AddMarker(ActivationFrame::Kind marker) {
1535 ASSERT(marker == ActivationFrame::kAsyncSuspensionMarker); 1447 ASSERT(marker == ActivationFrame::kAsyncSuspensionMarker);
1536 trace_.Add(new ActivationFrame(marker)); 1448 trace_.Add(new ActivationFrame(marker));
1537 } 1449 }
1538 1450
1539
1540 void DebuggerStackTrace::AddAsyncCausalFrame(uword pc, const Code& code) { 1451 void DebuggerStackTrace::AddAsyncCausalFrame(uword pc, const Code& code) {
1541 trace_.Add(new ActivationFrame(pc, 0, 0, code, Array::Handle(), 0, 1452 trace_.Add(new ActivationFrame(pc, 0, 0, code, Array::Handle(), 0,
1542 ActivationFrame::kAsyncCausal)); 1453 ActivationFrame::kAsyncCausal));
1543 } 1454 }
1544 1455
1545
1546 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall | 1456 const uint8_t kSafepointKind = RawPcDescriptors::kIcCall |
1547 RawPcDescriptors::kUnoptStaticCall | 1457 RawPcDescriptors::kUnoptStaticCall |
1548 RawPcDescriptors::kRuntimeCall; 1458 RawPcDescriptors::kRuntimeCall;
1549 1459
1550
1551 CodeBreakpoint::CodeBreakpoint(const Code& code, 1460 CodeBreakpoint::CodeBreakpoint(const Code& code,
1552 TokenPosition token_pos, 1461 TokenPosition token_pos,
1553 uword pc, 1462 uword pc,
1554 RawPcDescriptors::Kind kind) 1463 RawPcDescriptors::Kind kind)
1555 : code_(code.raw()), 1464 : code_(code.raw()),
1556 token_pos_(token_pos), 1465 token_pos_(token_pos),
1557 pc_(pc), 1466 pc_(pc),
1558 line_number_(-1), 1467 line_number_(-1),
1559 is_enabled_(false), 1468 is_enabled_(false),
1560 bpt_location_(NULL), 1469 bpt_location_(NULL),
1561 next_(NULL), 1470 next_(NULL),
1562 breakpoint_kind_(kind), 1471 breakpoint_kind_(kind),
1563 #if !defined(TARGET_ARCH_DBC) 1472 #if !defined(TARGET_ARCH_DBC)
1564 saved_value_(Code::null()) 1473 saved_value_(Code::null())
1565 #else 1474 #else
1566 saved_value_(Bytecode::kTrap), 1475 saved_value_(Bytecode::kTrap),
1567 saved_value_fastsmi_(Bytecode::kTrap) 1476 saved_value_fastsmi_(Bytecode::kTrap)
1568 #endif 1477 #endif
1569 { 1478 {
1570 ASSERT(!code.IsNull()); 1479 ASSERT(!code.IsNull());
1571 ASSERT(token_pos_.IsReal()); 1480 ASSERT(token_pos_.IsReal());
1572 ASSERT(pc_ != 0); 1481 ASSERT(pc_ != 0);
1573 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); 1482 ASSERT((breakpoint_kind_ & kSafepointKind) != 0);
1574 } 1483 }
1575 1484
1576
1577 CodeBreakpoint::~CodeBreakpoint() { 1485 CodeBreakpoint::~CodeBreakpoint() {
1578 // Make sure we don't leave patched code behind. 1486 // Make sure we don't leave patched code behind.
1579 ASSERT(!IsEnabled()); 1487 ASSERT(!IsEnabled());
1580 // Poison the data so we catch use after free errors. 1488 // Poison the data so we catch use after free errors.
1581 #ifdef DEBUG 1489 #ifdef DEBUG
1582 code_ = Code::null(); 1490 code_ = Code::null();
1583 pc_ = 0ul; 1491 pc_ = 0ul;
1584 bpt_location_ = NULL; 1492 bpt_location_ = NULL;
1585 next_ = NULL; 1493 next_ = NULL;
1586 breakpoint_kind_ = RawPcDescriptors::kOther; 1494 breakpoint_kind_ = RawPcDescriptors::kOther;
1587 #endif 1495 #endif
1588 } 1496 }
1589 1497
1590
1591 RawFunction* CodeBreakpoint::function() const { 1498 RawFunction* CodeBreakpoint::function() const {
1592 return Code::Handle(code_).function(); 1499 return Code::Handle(code_).function();
1593 } 1500 }
1594 1501
1595
1596 RawScript* CodeBreakpoint::SourceCode() { 1502 RawScript* CodeBreakpoint::SourceCode() {
1597 const Function& func = Function::Handle(this->function()); 1503 const Function& func = Function::Handle(this->function());
1598 return func.script(); 1504 return func.script();
1599 } 1505 }
1600 1506
1601
1602 RawString* CodeBreakpoint::SourceUrl() { 1507 RawString* CodeBreakpoint::SourceUrl() {
1603 const Script& script = Script::Handle(SourceCode()); 1508 const Script& script = Script::Handle(SourceCode());
1604 return script.url(); 1509 return script.url();
1605 } 1510 }
1606 1511
1607
1608 intptr_t CodeBreakpoint::LineNumber() { 1512 intptr_t CodeBreakpoint::LineNumber() {
1609 // Compute line number lazily since it causes scanning of the script. 1513 // Compute line number lazily since it causes scanning of the script.
1610 if (line_number_ < 0) { 1514 if (line_number_ < 0) {
1611 const Script& script = Script::Handle(SourceCode()); 1515 const Script& script = Script::Handle(SourceCode());
1612 script.GetTokenLocation(token_pos_, &line_number_, NULL); 1516 script.GetTokenLocation(token_pos_, &line_number_, NULL);
1613 } 1517 }
1614 return line_number_; 1518 return line_number_;
1615 } 1519 }
1616 1520
1617
1618 void CodeBreakpoint::Enable() { 1521 void CodeBreakpoint::Enable() {
1619 if (!is_enabled_) { 1522 if (!is_enabled_) {
1620 PatchCode(); 1523 PatchCode();
1621 } 1524 }
1622 ASSERT(is_enabled_); 1525 ASSERT(is_enabled_);
1623 } 1526 }
1624 1527
1625
1626 void CodeBreakpoint::Disable() { 1528 void CodeBreakpoint::Disable() {
1627 if (is_enabled_) { 1529 if (is_enabled_) {
1628 RestoreCode(); 1530 RestoreCode();
1629 } 1531 }
1630 ASSERT(!is_enabled_); 1532 ASSERT(!is_enabled_);
1631 } 1533 }
1632 1534
1633
1634 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) { 1535 RemoteObjectCache::RemoteObjectCache(intptr_t initial_size) {
1635 objs_ = 1536 objs_ =
1636 &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New(initial_size)); 1537 &GrowableObjectArray::ZoneHandle(GrowableObjectArray::New(initial_size));
1637 } 1538 }
1638 1539
1639
1640 intptr_t RemoteObjectCache::AddObject(const Object& obj) { 1540 intptr_t RemoteObjectCache::AddObject(const Object& obj) {
1641 intptr_t len = objs_->Length(); 1541 intptr_t len = objs_->Length();
1642 for (intptr_t i = 0; i < len; i++) { 1542 for (intptr_t i = 0; i < len; i++) {
1643 if (objs_->At(i) == obj.raw()) { 1543 if (objs_->At(i) == obj.raw()) {
1644 return i; 1544 return i;
1645 } 1545 }
1646 } 1546 }
1647 objs_->Add(obj); 1547 objs_->Add(obj);
1648 return len; 1548 return len;
1649 } 1549 }
1650 1550
1651
1652 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const { 1551 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const {
1653 ASSERT(IsValidId(obj_id)); 1552 ASSERT(IsValidId(obj_id));
1654 return objs_->At(obj_id); 1553 return objs_->At(obj_id);
1655 } 1554 }
1656 1555
1657
1658 Debugger::Debugger() 1556 Debugger::Debugger()
1659 : isolate_(NULL), 1557 : isolate_(NULL),
1660 isolate_id_(ILLEGAL_ISOLATE_ID), 1558 isolate_id_(ILLEGAL_ISOLATE_ID),
1661 initialized_(false), 1559 initialized_(false),
1662 next_id_(1), 1560 next_id_(1),
1663 latent_locations_(NULL), 1561 latent_locations_(NULL),
1664 breakpoint_locations_(NULL), 1562 breakpoint_locations_(NULL),
1665 code_breakpoints_(NULL), 1563 code_breakpoints_(NULL),
1666 resume_action_(kContinue), 1564 resume_action_(kContinue),
1667 resume_frame_index_(-1), 1565 resume_frame_index_(-1),
1668 post_deopt_frame_index_(-1), 1566 post_deopt_frame_index_(-1),
1669 ignore_breakpoints_(false), 1567 ignore_breakpoints_(false),
1670 pause_event_(NULL), 1568 pause_event_(NULL),
1671 obj_cache_(NULL), 1569 obj_cache_(NULL),
1672 stack_trace_(NULL), 1570 stack_trace_(NULL),
1673 async_causal_stack_trace_(NULL), 1571 async_causal_stack_trace_(NULL),
1674 awaiter_stack_trace_(NULL), 1572 awaiter_stack_trace_(NULL),
1675 stepping_fp_(0), 1573 stepping_fp_(0),
1676 async_stepping_fp_(0), 1574 async_stepping_fp_(0),
1677 top_frame_awaiter_(Object::null()), 1575 top_frame_awaiter_(Object::null()),
1678 skip_next_step_(false), 1576 skip_next_step_(false),
1679 needs_breakpoint_cleanup_(false), 1577 needs_breakpoint_cleanup_(false),
1680 synthetic_async_breakpoint_(NULL), 1578 synthetic_async_breakpoint_(NULL),
1681 exc_pause_info_(kNoPauseOnExceptions) {} 1579 exc_pause_info_(kNoPauseOnExceptions) {}
1682 1580
1683
1684 Debugger::~Debugger() { 1581 Debugger::~Debugger() {
1685 isolate_id_ = ILLEGAL_ISOLATE_ID; 1582 isolate_id_ = ILLEGAL_ISOLATE_ID;
1686 ASSERT(!IsPaused()); 1583 ASSERT(!IsPaused());
1687 ASSERT(latent_locations_ == NULL); 1584 ASSERT(latent_locations_ == NULL);
1688 ASSERT(breakpoint_locations_ == NULL); 1585 ASSERT(breakpoint_locations_ == NULL);
1689 ASSERT(code_breakpoints_ == NULL); 1586 ASSERT(code_breakpoints_ == NULL);
1690 ASSERT(stack_trace_ == NULL); 1587 ASSERT(stack_trace_ == NULL);
1691 ASSERT(async_causal_stack_trace_ == NULL); 1588 ASSERT(async_causal_stack_trace_ == NULL);
1692 ASSERT(obj_cache_ == NULL); 1589 ASSERT(obj_cache_ == NULL);
1693 ASSERT(synthetic_async_breakpoint_ == NULL); 1590 ASSERT(synthetic_async_breakpoint_ == NULL);
1694 } 1591 }
1695 1592
1696
1697 void Debugger::Shutdown() { 1593 void Debugger::Shutdown() {
1698 // TODO(johnmccutchan): Do not create a debugger for isolates that don't need 1594 // TODO(johnmccutchan): Do not create a debugger for isolates that don't need
1699 // them. Then, assert here that isolate_ is not one of those isolates. 1595 // them. Then, assert here that isolate_ is not one of those isolates.
1700 if ((isolate_ == Dart::vm_isolate()) || 1596 if ((isolate_ == Dart::vm_isolate()) ||
1701 ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { 1597 ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
1702 return; 1598 return;
1703 } 1599 }
1704 while (breakpoint_locations_ != NULL) { 1600 while (breakpoint_locations_ != NULL) {
1705 BreakpointLocation* bpt = breakpoint_locations_; 1601 BreakpointLocation* bpt = breakpoint_locations_;
1706 breakpoint_locations_ = breakpoint_locations_->next(); 1602 breakpoint_locations_ = breakpoint_locations_->next();
1707 delete bpt; 1603 delete bpt;
1708 } 1604 }
1709 while (latent_locations_ != NULL) { 1605 while (latent_locations_ != NULL) {
1710 BreakpointLocation* bpt = latent_locations_; 1606 BreakpointLocation* bpt = latent_locations_;
1711 latent_locations_ = latent_locations_->next(); 1607 latent_locations_ = latent_locations_->next();
1712 delete bpt; 1608 delete bpt;
1713 } 1609 }
1714 while (code_breakpoints_ != NULL) { 1610 while (code_breakpoints_ != NULL) {
1715 CodeBreakpoint* bpt = code_breakpoints_; 1611 CodeBreakpoint* bpt = code_breakpoints_;
1716 code_breakpoints_ = code_breakpoints_->next(); 1612 code_breakpoints_ = code_breakpoints_->next();
1717 bpt->Disable(); 1613 bpt->Disable();
1718 delete bpt; 1614 delete bpt;
1719 } 1615 }
1720 if (NeedsIsolateEvents()) { 1616 if (NeedsIsolateEvents()) {
1721 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit); 1617 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
1722 InvokeEventHandler(&event); 1618 InvokeEventHandler(&event);
1723 } 1619 }
1724 } 1620 }
1725 1621
1726
1727 void Debugger::OnIsolateRunnable() {} 1622 void Debugger::OnIsolateRunnable() {}
1728 1623
1729
1730 static RawFunction* ResolveLibraryFunction(const Library& library, 1624 static RawFunction* ResolveLibraryFunction(const Library& library,
1731 const String& fname) { 1625 const String& fname) {
1732 ASSERT(!library.IsNull()); 1626 ASSERT(!library.IsNull());
1733 const Object& object = Object::Handle(library.ResolveName(fname)); 1627 const Object& object = Object::Handle(library.ResolveName(fname));
1734 if (!object.IsNull() && object.IsFunction()) { 1628 if (!object.IsNull() && object.IsFunction()) {
1735 return Function::Cast(object).raw(); 1629 return Function::Cast(object).raw();
1736 } 1630 }
1737 return Function::null(); 1631 return Function::null();
1738 } 1632 }
1739 1633
1740
1741 bool Debugger::SetupStepOverAsyncSuspension(const char** error) { 1634 bool Debugger::SetupStepOverAsyncSuspension(const char** error) {
1742 ActivationFrame* top_frame = TopDartFrame(); 1635 ActivationFrame* top_frame = TopDartFrame();
1743 if (!IsAtAsyncJump(top_frame)) { 1636 if (!IsAtAsyncJump(top_frame)) {
1744 // Not at an async operation. 1637 // Not at an async operation.
1745 if (error) { 1638 if (error) {
1746 *error = "Isolate must be paused at an async suspension point"; 1639 *error = "Isolate must be paused at an async suspension point";
1747 } 1640 }
1748 return false; 1641 return false;
1749 } 1642 }
1750 Object& closure = Object::Handle(top_frame->GetAsyncOperation()); 1643 Object& closure = Object::Handle(top_frame->GetAsyncOperation());
1751 ASSERT(!closure.IsNull()); 1644 ASSERT(!closure.IsNull());
1752 ASSERT(closure.IsInstance()); 1645 ASSERT(closure.IsInstance());
1753 ASSERT(Instance::Cast(closure).IsClosure()); 1646 ASSERT(Instance::Cast(closure).IsClosure());
1754 Breakpoint* bpt = SetBreakpointAtActivation(Instance::Cast(closure), true); 1647 Breakpoint* bpt = SetBreakpointAtActivation(Instance::Cast(closure), true);
1755 if (bpt == NULL) { 1648 if (bpt == NULL) {
1756 // Unable to set the breakpoint. 1649 // Unable to set the breakpoint.
1757 if (error) { 1650 if (error) {
1758 *error = "Unable to set breakpoint at async suspension point"; 1651 *error = "Unable to set breakpoint at async suspension point";
1759 } 1652 }
1760 return false; 1653 return false;
1761 } 1654 }
1762 return true; 1655 return true;
1763 } 1656 }
1764 1657
1765
1766 bool Debugger::SetResumeAction(ResumeAction action, 1658 bool Debugger::SetResumeAction(ResumeAction action,
1767 intptr_t frame_index, 1659 intptr_t frame_index,
1768 const char** error) { 1660 const char** error) {
1769 if (error) { 1661 if (error) {
1770 *error = NULL; 1662 *error = NULL;
1771 } 1663 }
1772 resume_frame_index_ = -1; 1664 resume_frame_index_ = -1;
1773 switch (action) { 1665 switch (action) {
1774 case kStepInto: 1666 case kStepInto:
1775 case kStepOver: 1667 case kStepOver:
1776 case kStepOut: 1668 case kStepOut:
1777 case kContinue: 1669 case kContinue:
1778 resume_action_ = action; 1670 resume_action_ = action;
1779 return true; 1671 return true;
1780 case kStepRewind: 1672 case kStepRewind:
1781 if (!CanRewindFrame(frame_index, error)) { 1673 if (!CanRewindFrame(frame_index, error)) {
1782 return false; 1674 return false;
1783 } 1675 }
1784 resume_action_ = kStepRewind; 1676 resume_action_ = kStepRewind;
1785 resume_frame_index_ = frame_index; 1677 resume_frame_index_ = frame_index;
1786 return true; 1678 return true;
1787 case kStepOverAsyncSuspension: 1679 case kStepOverAsyncSuspension:
1788 return SetupStepOverAsyncSuspension(error); 1680 return SetupStepOverAsyncSuspension(error);
1789 default: 1681 default:
1790 UNREACHABLE(); 1682 UNREACHABLE();
1791 return false; 1683 return false;
1792 } 1684 }
1793 } 1685 }
1794 1686
1795
1796 RawFunction* Debugger::ResolveFunction(const Library& library, 1687 RawFunction* Debugger::ResolveFunction(const Library& library,
1797 const String& class_name, 1688 const String& class_name,
1798 const String& function_name) { 1689 const String& function_name) {
1799 ASSERT(!library.IsNull()); 1690 ASSERT(!library.IsNull());
1800 ASSERT(!class_name.IsNull()); 1691 ASSERT(!class_name.IsNull());
1801 ASSERT(!function_name.IsNull()); 1692 ASSERT(!function_name.IsNull());
1802 if (class_name.Length() == 0) { 1693 if (class_name.Length() == 0) {
1803 return ResolveLibraryFunction(library, function_name); 1694 return ResolveLibraryFunction(library, function_name);
1804 } 1695 }
1805 const Class& cls = Class::Handle(library.LookupClass(class_name)); 1696 const Class& cls = Class::Handle(library.LookupClass(class_name));
1806 Function& function = Function::Handle(); 1697 Function& function = Function::Handle();
1807 if (!cls.IsNull()) { 1698 if (!cls.IsNull()) {
1808 function = cls.LookupStaticFunction(function_name); 1699 function = cls.LookupStaticFunction(function_name);
1809 if (function.IsNull()) { 1700 if (function.IsNull()) {
1810 function = cls.LookupDynamicFunction(function_name); 1701 function = cls.LookupDynamicFunction(function_name);
1811 } 1702 }
1812 } 1703 }
1813 return function.raw(); 1704 return function.raw();
1814 } 1705 }
1815 1706
1816
1817 // Deoptimize all functions in the isolate. 1707 // Deoptimize all functions in the isolate.
1818 // TODO(hausner): Actually we only need to deoptimize those functions 1708 // TODO(hausner): Actually we only need to deoptimize those functions
1819 // that inline the function that contains the newly created breakpoint. 1709 // that inline the function that contains the newly created breakpoint.
1820 // We currently don't have this info so we deoptimize all functions. 1710 // We currently don't have this info so we deoptimize all functions.
1821 void Debugger::DeoptimizeWorld() { 1711 void Debugger::DeoptimizeWorld() {
1822 BackgroundCompiler::Stop(isolate_); 1712 BackgroundCompiler::Stop(isolate_);
1823 DeoptimizeFunctionsOnStack(); 1713 DeoptimizeFunctionsOnStack();
1824 // Iterate over all classes, deoptimize functions. 1714 // Iterate over all classes, deoptimize functions.
1825 // TODO(hausner): Could possibly be combined with RemoveOptimizedCode() 1715 // TODO(hausner): Could possibly be combined with RemoveOptimizedCode()
1826 const ClassTable& class_table = *isolate_->class_table(); 1716 const ClassTable& class_table = *isolate_->class_table();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 const intptr_t num_closures = closures.Length(); 1750 const intptr_t num_closures = closures.Length();
1861 for (intptr_t pos = 0; pos < num_closures; pos++) { 1751 for (intptr_t pos = 0; pos < num_closures; pos++) {
1862 function ^= closures.At(pos); 1752 function ^= closures.At(pos);
1863 ASSERT(!function.IsNull()); 1753 ASSERT(!function.IsNull());
1864 if (function.HasOptimizedCode()) { 1754 if (function.HasOptimizedCode()) {
1865 function.SwitchToUnoptimizedCode(); 1755 function.SwitchToUnoptimizedCode();
1866 } 1756 }
1867 } 1757 }
1868 } 1758 }
1869 1759
1870
1871 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1760 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1872 uword pc, 1761 uword pc,
1873 StackFrame* frame, 1762 StackFrame* frame,
1874 const Code& code, 1763 const Code& code,
1875 const Array& deopt_frame, 1764 const Array& deopt_frame,
1876 intptr_t deopt_frame_offset, 1765 intptr_t deopt_frame_offset,
1877 ActivationFrame::Kind kind) { 1766 ActivationFrame::Kind kind) {
1878 ASSERT(code.ContainsInstructionAt(pc)); 1767 ASSERT(code.ContainsInstructionAt(pc));
1879 ActivationFrame* activation = 1768 ActivationFrame* activation =
1880 new ActivationFrame(pc, frame->fp(), frame->sp(), code, deopt_frame, 1769 new ActivationFrame(pc, frame->fp(), frame->sp(), code, deopt_frame,
1881 deopt_frame_offset, kind); 1770 deopt_frame_offset, kind);
1882 if (FLAG_trace_debugger_stacktrace) { 1771 if (FLAG_trace_debugger_stacktrace) {
1883 const Context& ctx = activation->GetSavedCurrentContext(); 1772 const Context& ctx = activation->GetSavedCurrentContext();
1884 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); 1773 OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString());
1885 } 1774 }
1886 if (FLAG_trace_debugger_stacktrace) { 1775 if (FLAG_trace_debugger_stacktrace) {
1887 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); 1776 OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
1888 } 1777 }
1889 return activation; 1778 return activation;
1890 } 1779 }
1891 1780
1892
1893 RawArray* Debugger::DeoptimizeToArray(Thread* thread, 1781 RawArray* Debugger::DeoptimizeToArray(Thread* thread,
1894 StackFrame* frame, 1782 StackFrame* frame,
1895 const Code& code) { 1783 const Code& code) {
1896 ASSERT(code.is_optimized()); 1784 ASSERT(code.is_optimized());
1897 Isolate* isolate = thread->isolate(); 1785 Isolate* isolate = thread->isolate();
1898 // Create the DeoptContext for this deoptimization. 1786 // Create the DeoptContext for this deoptimization.
1899 DeoptContext* deopt_context = 1787 DeoptContext* deopt_context =
1900 new DeoptContext(frame, code, DeoptContext::kDestIsAllocated, NULL, NULL, 1788 new DeoptContext(frame, code, DeoptContext::kDestIsAllocated, NULL, NULL,
1901 true, false /* deoptimizing_code */); 1789 true, false /* deoptimizing_code */);
1902 isolate->set_deopt_context(deopt_context); 1790 isolate->set_deopt_context(deopt_context);
1903 1791
1904 deopt_context->FillDestFrame(); 1792 deopt_context->FillDestFrame();
1905 deopt_context->MaterializeDeferredObjects(); 1793 deopt_context->MaterializeDeferredObjects();
1906 const Array& dest_frame = 1794 const Array& dest_frame =
1907 Array::Handle(thread->zone(), deopt_context->DestFrameAsArray()); 1795 Array::Handle(thread->zone(), deopt_context->DestFrameAsArray());
1908 1796
1909 isolate->set_deopt_context(NULL); 1797 isolate->set_deopt_context(NULL);
1910 delete deopt_context; 1798 delete deopt_context;
1911 1799
1912 return dest_frame.raw(); 1800 return dest_frame.raw();
1913 } 1801 }
1914 1802
1915
1916 DebuggerStackTrace* Debugger::CollectStackTrace() { 1803 DebuggerStackTrace* Debugger::CollectStackTrace() {
1917 Thread* thread = Thread::Current(); 1804 Thread* thread = Thread::Current();
1918 Zone* zone = thread->zone(); 1805 Zone* zone = thread->zone();
1919 Isolate* isolate = thread->isolate(); 1806 Isolate* isolate = thread->isolate();
1920 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1807 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1921 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 1808 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
1922 Thread::Current(), 1809 Thread::Current(),
1923 StackFrameIterator::kNoCrossThreadIteration); 1810 StackFrameIterator::kNoCrossThreadIteration);
1924 Code& code = Code::Handle(zone); 1811 Code& code = Code::Handle(zone);
1925 Code& inlined_code = Code::Handle(zone); 1812 Code& inlined_code = Code::Handle(zone);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame, 1852 stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame,
1966 *inlined_code, *deopt_frame, 1853 *inlined_code, *deopt_frame,
1967 deopt_frame_offset)); 1854 deopt_frame_offset));
1968 } 1855 }
1969 } else { 1856 } else {
1970 stack_trace->AddActivation(CollectDartFrame( 1857 stack_trace->AddActivation(CollectDartFrame(
1971 isolate, frame->pc(), frame, *code, Object::null_array(), 0)); 1858 isolate, frame->pc(), frame, *code, Object::null_array(), 0));
1972 } 1859 }
1973 } 1860 }
1974 1861
1975
1976 DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() { 1862 DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() {
1977 if (!FLAG_causal_async_stacks) { 1863 if (!FLAG_causal_async_stacks) {
1978 return NULL; 1864 return NULL;
1979 } 1865 }
1980 Thread* thread = Thread::Current(); 1866 Thread* thread = Thread::Current();
1981 Zone* zone = thread->zone(); 1867 Zone* zone = thread->zone();
1982 Isolate* isolate = thread->isolate(); 1868 Isolate* isolate = thread->isolate();
1983 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 1869 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
1984 1870
1985 Code& code = Code::Handle(zone); 1871 Code& code = Code::Handle(zone);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2051 } 1937 }
2052 } 1938 }
2053 } 1939 }
2054 // Follow the link. 1940 // Follow the link.
2055 async_stack_trace = async_stack_trace.async_link(); 1941 async_stack_trace = async_stack_trace.async_link();
2056 } 1942 }
2057 1943
2058 return stack_trace; 1944 return stack_trace;
2059 } 1945 }
2060 1946
2061
2062 DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { 1947 DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() {
2063 if (!FLAG_async_debugger) { 1948 if (!FLAG_async_debugger) {
2064 return NULL; 1949 return NULL;
2065 } 1950 }
2066 // Causal async stacks are not supported in the AOT runtime. 1951 // Causal async stacks are not supported in the AOT runtime.
2067 ASSERT(!FLAG_precompiled_runtime); 1952 ASSERT(!FLAG_precompiled_runtime);
2068 1953
2069 Thread* thread = Thread::Current(); 1954 Thread* thread = Thread::Current();
2070 Zone* zone = thread->zone(); 1955 Zone* zone = thread->zone();
2071 Isolate* isolate = thread->isolate(); 1956 Isolate* isolate = thread->isolate();
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 } 2083 }
2199 } 2084 }
2200 } 2085 }
2201 // Follow the link. 2086 // Follow the link.
2202 async_stack_trace = async_stack_trace.async_link(); 2087 async_stack_trace = async_stack_trace.async_link();
2203 } 2088 }
2204 2089
2205 return stack_trace; 2090 return stack_trace;
2206 } 2091 }
2207 2092
2208
2209 ActivationFrame* Debugger::TopDartFrame() const { 2093 ActivationFrame* Debugger::TopDartFrame() const {
2210 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 2094 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
2211 Thread::Current(), 2095 Thread::Current(),
2212 StackFrameIterator::kNoCrossThreadIteration); 2096 StackFrameIterator::kNoCrossThreadIteration);
2213 StackFrame* frame = iterator.NextFrame(); 2097 StackFrame* frame = iterator.NextFrame();
2214 while ((frame != NULL) && !frame->IsDartFrame()) { 2098 while ((frame != NULL) && !frame->IsDartFrame()) {
2215 frame = iterator.NextFrame(); 2099 frame = iterator.NextFrame();
2216 } 2100 }
2217 Code& code = Code::Handle(frame->LookupDartCode()); 2101 Code& code = Code::Handle(frame->LookupDartCode());
2218 ActivationFrame* activation = new ActivationFrame( 2102 ActivationFrame* activation = new ActivationFrame(
2219 frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0); 2103 frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0);
2220 return activation; 2104 return activation;
2221 } 2105 }
2222 2106
2223
2224 DebuggerStackTrace* Debugger::StackTrace() { 2107 DebuggerStackTrace* Debugger::StackTrace() {
2225 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); 2108 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace();
2226 } 2109 }
2227 2110
2228
2229 DebuggerStackTrace* Debugger::CurrentStackTrace() { 2111 DebuggerStackTrace* Debugger::CurrentStackTrace() {
2230 return CollectStackTrace(); 2112 return CollectStackTrace();
2231 } 2113 }
2232 2114
2233
2234 DebuggerStackTrace* Debugger::AsyncCausalStackTrace() { 2115 DebuggerStackTrace* Debugger::AsyncCausalStackTrace() {
2235 return (async_causal_stack_trace_ != NULL) ? async_causal_stack_trace_ 2116 return (async_causal_stack_trace_ != NULL) ? async_causal_stack_trace_
2236 : CollectAsyncCausalStackTrace(); 2117 : CollectAsyncCausalStackTrace();
2237 } 2118 }
2238 2119
2239
2240 DebuggerStackTrace* Debugger::CurrentAsyncCausalStackTrace() { 2120 DebuggerStackTrace* Debugger::CurrentAsyncCausalStackTrace() {
2241 return CollectAsyncCausalStackTrace(); 2121 return CollectAsyncCausalStackTrace();
2242 } 2122 }
2243 2123
2244
2245 DebuggerStackTrace* Debugger::AwaiterStackTrace() { 2124 DebuggerStackTrace* Debugger::AwaiterStackTrace() {
2246 return (awaiter_stack_trace_ != NULL) ? awaiter_stack_trace_ 2125 return (awaiter_stack_trace_ != NULL) ? awaiter_stack_trace_
2247 : CollectAwaiterReturnStackTrace(); 2126 : CollectAwaiterReturnStackTrace();
2248 } 2127 }
2249 2128
2250
2251 DebuggerStackTrace* Debugger::CurrentAwaiterStackTrace() { 2129 DebuggerStackTrace* Debugger::CurrentAwaiterStackTrace() {
2252 return CollectAwaiterReturnStackTrace(); 2130 return CollectAwaiterReturnStackTrace();
2253 } 2131 }
2254 2132
2255
2256 DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) { 2133 DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) {
2257 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 2134 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
2258 Function& function = Function::Handle(); 2135 Function& function = Function::Handle();
2259 Code& code = Code::Handle(); 2136 Code& code = Code::Handle();
2260 2137
2261 const uword fp = 0; 2138 const uword fp = 0;
2262 const uword sp = 0; 2139 const uword sp = 0;
2263 const Array& deopt_frame = Array::Handle(); 2140 const Array& deopt_frame = Array::Handle();
2264 const intptr_t deopt_frame_offset = -1; 2141 const intptr_t deopt_frame_offset = -1;
2265 2142
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 ActivationFrame* activation = new ActivationFrame( 2175 ActivationFrame* activation = new ActivationFrame(
2299 pc, fp, sp, code, deopt_frame, deopt_frame_offset); 2176 pc, fp, sp, code, deopt_frame, deopt_frame_offset);
2300 stack_trace->AddActivation(activation); 2177 stack_trace->AddActivation(activation);
2301 } 2178 }
2302 } 2179 }
2303 } 2180 }
2304 } 2181 }
2305 return stack_trace; 2182 return stack_trace;
2306 } 2183 }
2307 2184
2308
2309 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) { 2185 void Debugger::SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info) {
2310 ASSERT((pause_info == kNoPauseOnExceptions) || 2186 ASSERT((pause_info == kNoPauseOnExceptions) ||
2311 (pause_info == kPauseOnUnhandledExceptions) || 2187 (pause_info == kPauseOnUnhandledExceptions) ||
2312 (pause_info == kPauseOnAllExceptions)); 2188 (pause_info == kPauseOnAllExceptions));
2313 exc_pause_info_ = pause_info; 2189 exc_pause_info_ = pause_info;
2314 } 2190 }
2315 2191
2316
2317 Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const { 2192 Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() const {
2318 return exc_pause_info_; 2193 return exc_pause_info_;
2319 } 2194 }
2320 2195
2321
2322 bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace, 2196 bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
2323 const Instance& exception) { 2197 const Instance& exception) {
2324 if (exc_pause_info_ == kNoPauseOnExceptions) { 2198 if (exc_pause_info_ == kNoPauseOnExceptions) {
2325 return false; 2199 return false;
2326 } 2200 }
2327 if (exc_pause_info_ == kPauseOnAllExceptions) { 2201 if (exc_pause_info_ == kPauseOnAllExceptions) {
2328 return true; 2202 return true;
2329 } 2203 }
2330 ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions); 2204 ASSERT(exc_pause_info_ == kPauseOnUnhandledExceptions);
2331 ActivationFrame* handler_frame = stack_trace->GetHandlerFrame(exception); 2205 ActivationFrame* handler_frame = stack_trace->GetHandlerFrame(exception);
2332 if (handler_frame == NULL) { 2206 if (handler_frame == NULL) {
2333 // Did not find an exception handler that catches this exception. 2207 // Did not find an exception handler that catches this exception.
2334 // Note that this check is not precise, since we can't check 2208 // Note that this check is not precise, since we can't check
2335 // uninstantiated types, i.e. types containing type parameters. 2209 // uninstantiated types, i.e. types containing type parameters.
2336 // Thus, we may report an exception as unhandled when in fact 2210 // Thus, we may report an exception as unhandled when in fact
2337 // it will be caught once we unwind the stack. 2211 // it will be caught once we unwind the stack.
2338 return true; 2212 return true;
2339 } 2213 }
2340 return false; 2214 return false;
2341 } 2215 }
2342 2216
2343
2344 void Debugger::PauseException(const Instance& exc) { 2217 void Debugger::PauseException(const Instance& exc) {
2345 if (FLAG_stress_async_stacks) { 2218 if (FLAG_stress_async_stacks) {
2346 CollectAwaiterReturnStackTrace(); 2219 CollectAwaiterReturnStackTrace();
2347 } 2220 }
2348 // We ignore this exception event when the VM is executing code invoked 2221 // We ignore this exception event when the VM is executing code invoked
2349 // by the debugger to evaluate variables values, when we see a nested 2222 // by the debugger to evaluate variables values, when we see a nested
2350 // breakpoint or exception event, or if the debugger is not 2223 // breakpoint or exception event, or if the debugger is not
2351 // interested in exception events. 2224 // interested in exception events.
2352 if (ignore_breakpoints_ || IsPaused() || 2225 if (ignore_breakpoints_ || IsPaused() ||
2353 (exc_pause_info_ == kNoPauseOnExceptions)) { 2226 (exc_pause_info_ == kNoPauseOnExceptions)) {
(...skipping 15 matching lines...) Expand all
2369 if (stack_trace->Length() > 0) { 2242 if (stack_trace->Length() > 0) {
2370 event.set_top_frame(stack_trace->FrameAt(0)); 2243 event.set_top_frame(stack_trace->FrameAt(0));
2371 } 2244 }
2372 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), 2245 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
2373 CollectAwaiterReturnStackTrace()); 2246 CollectAwaiterReturnStackTrace());
2374 Pause(&event); 2247 Pause(&event);
2375 HandleSteppingRequest(stack_trace_); // we may get a rewind request 2248 HandleSteppingRequest(stack_trace_); // we may get a rewind request
2376 ClearCachedStackTraces(); 2249 ClearCachedStackTraces();
2377 } 2250 }
2378 2251
2379
2380 static TokenPosition LastTokenOnLine(Zone* zone, 2252 static TokenPosition LastTokenOnLine(Zone* zone,
2381 const TokenStream& tokens, 2253 const TokenStream& tokens,
2382 TokenPosition pos) { 2254 TokenPosition pos) {
2383 TokenStream::Iterator iter(zone, tokens, pos, 2255 TokenStream::Iterator iter(zone, tokens, pos,
2384 TokenStream::Iterator::kAllTokens); 2256 TokenStream::Iterator::kAllTokens);
2385 ASSERT(iter.IsValid()); 2257 ASSERT(iter.IsValid());
2386 TokenPosition last_pos = pos; 2258 TokenPosition last_pos = pos;
2387 while ((iter.CurrentTokenKind() != Token::kNEWLINE) && 2259 while ((iter.CurrentTokenKind() != Token::kNEWLINE) &&
2388 (iter.CurrentTokenKind() != Token::kEOS)) { 2260 (iter.CurrentTokenKind() != Token::kEOS)) {
2389 last_pos = iter.CurrentPosition(); 2261 last_pos = iter.CurrentPosition();
2390 iter.Advance(); 2262 iter.Advance();
2391 } 2263 }
2392 return last_pos; 2264 return last_pos;
2393 } 2265 }
2394 2266
2395
2396 // Returns the best fit token position for a breakpoint. 2267 // Returns the best fit token position for a breakpoint.
2397 // 2268 //
2398 // Takes a range of tokens [requested_token_pos, last_token_pos] and 2269 // Takes a range of tokens [requested_token_pos, last_token_pos] and
2399 // an optional column (requested_column). The range of tokens usually 2270 // an optional column (requested_column). The range of tokens usually
2400 // represents one line of the program text, but can represent a larger 2271 // represents one line of the program text, but can represent a larger
2401 // range on recursive calls. 2272 // range on recursive calls.
2402 // 2273 //
2403 // The best fit is found in two passes. 2274 // The best fit is found in two passes.
2404 // 2275 //
2405 // The first pass finds a candidate token which: 2276 // The first pass finds a candidate token which:
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 // find a safe point in the remaining source code of the function. 2439 // find a safe point in the remaining source code of the function.
2569 // Since we have moved to the next line of the function, we no 2440 // Since we have moved to the next line of the function, we no
2570 // longer are requesting a specific column number. 2441 // longer are requesting a specific column number.
2571 if (last_token_pos < func.end_token_pos()) { 2442 if (last_token_pos < func.end_token_pos()) {
2572 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), 2443 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(),
2573 -1 /* no column */); 2444 -1 /* no column */);
2574 } 2445 }
2575 return TokenPosition::kNoSource; 2446 return TokenPosition::kNoSource;
2576 } 2447 }
2577 2448
2578
2579 void Debugger::MakeCodeBreakpointAt(const Function& func, 2449 void Debugger::MakeCodeBreakpointAt(const Function& func,
2580 BreakpointLocation* loc) { 2450 BreakpointLocation* loc) {
2581 ASSERT(loc->token_pos_.IsReal()); 2451 ASSERT(loc->token_pos_.IsReal());
2582 ASSERT((loc != NULL) && loc->IsResolved()); 2452 ASSERT((loc != NULL) && loc->IsResolved());
2583 ASSERT(!func.HasOptimizedCode()); 2453 ASSERT(!func.HasOptimizedCode());
2584 Code& code = Code::Handle(func.unoptimized_code()); 2454 Code& code = Code::Handle(func.unoptimized_code());
2585 ASSERT(!code.IsNull()); 2455 ASSERT(!code.IsNull());
2586 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 2456 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
2587 uword lowest_pc_offset = kUwordMax; 2457 uword lowest_pc_offset = kUwordMax;
2588 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind; 2458 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind;
(...skipping 18 matching lines...) Expand all
2607 code_bpt = 2477 code_bpt =
2608 new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind); 2478 new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind);
2609 RegisterCodeBreakpoint(code_bpt); 2479 RegisterCodeBreakpoint(code_bpt);
2610 } 2480 }
2611 code_bpt->set_bpt_location(loc); 2481 code_bpt->set_bpt_location(loc);
2612 if (loc->AnyEnabled()) { 2482 if (loc->AnyEnabled()) {
2613 code_bpt->Enable(); 2483 code_bpt->Enable();
2614 } 2484 }
2615 } 2485 }
2616 2486
2617
2618 void Debugger::FindCompiledFunctions(const Script& script, 2487 void Debugger::FindCompiledFunctions(const Script& script,
2619 TokenPosition start_pos, 2488 TokenPosition start_pos,
2620 TokenPosition end_pos, 2489 TokenPosition end_pos,
2621 GrowableObjectArray* function_list) { 2490 GrowableObjectArray* function_list) {
2622 Zone* zone = Thread::Current()->zone(); 2491 Zone* zone = Thread::Current()->zone();
2623 Class& cls = Class::Handle(zone); 2492 Class& cls = Class::Handle(zone);
2624 Array& functions = Array::Handle(zone); 2493 Array& functions = Array::Handle(zone);
2625 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); 2494 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone);
2626 Function& function = Function::Handle(zone); 2495 Function& function = Function::Handle(zone);
2627 2496
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2680 function_list->Add(function); 2549 function_list->Add(function);
2681 } 2550 }
2682 } 2551 }
2683 } 2552 }
2684 } 2553 }
2685 } 2554 }
2686 } 2555 }
2687 } 2556 }
2688 } 2557 }
2689 2558
2690
2691 static void SelectBestFit(Function* best_fit, Function* func) { 2559 static void SelectBestFit(Function* best_fit, Function* func) {
2692 if (best_fit->IsNull()) { 2560 if (best_fit->IsNull()) {
2693 *best_fit = func->raw(); 2561 *best_fit = func->raw();
2694 } else { 2562 } else {
2695 if ((func->token_pos() > best_fit->token_pos()) && 2563 if ((func->token_pos() > best_fit->token_pos()) &&
2696 ((func->end_token_pos() <= best_fit->end_token_pos()))) { 2564 ((func->end_token_pos() <= best_fit->end_token_pos()))) {
2697 *best_fit = func->raw(); 2565 *best_fit = func->raw();
2698 } 2566 }
2699 } 2567 }
2700 } 2568 }
2701 2569
2702
2703 // Returns true if a best fit is found. A best fit can either be a function 2570 // Returns true if a best fit is found. A best fit can either be a function
2704 // or a field. If it is a function, then the best fit function is returned 2571 // or a field. If it is a function, then the best fit function is returned
2705 // in |best_fit|. If a best fit is a field, it means that a latent 2572 // in |best_fit|. If a best fit is a field, it means that a latent
2706 // breakpoint can be set in the range |token_pos| to |last_token_pos|. 2573 // breakpoint can be set in the range |token_pos| to |last_token_pos|.
2707 bool Debugger::FindBestFit(const Script& script, 2574 bool Debugger::FindBestFit(const Script& script,
2708 TokenPosition token_pos, 2575 TokenPosition token_pos,
2709 TokenPosition last_token_pos, 2576 TokenPosition last_token_pos,
2710 Function* best_fit) { 2577 Function* best_fit) {
2711 Zone* zone = Thread::Current()->zone(); 2578 Zone* zone = Thread::Current()->zone();
2712 Class& cls = Class::Handle(zone); 2579 Class& cls = Class::Handle(zone);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 (token_pos <= start && start <= last_token_pos)) { 2667 (token_pos <= start && start <= last_token_pos)) {
2801 return true; 2668 return true;
2802 } 2669 }
2803 } 2670 }
2804 } 2671 }
2805 } 2672 }
2806 } 2673 }
2807 return false; 2674 return false;
2808 } 2675 }
2809 2676
2810
2811 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, 2677 BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
2812 TokenPosition token_pos, 2678 TokenPosition token_pos,
2813 TokenPosition last_token_pos, 2679 TokenPosition last_token_pos,
2814 intptr_t requested_line, 2680 intptr_t requested_line,
2815 intptr_t requested_column) { 2681 intptr_t requested_column) {
2816 Function& func = Function::Handle(); 2682 Function& func = Function::Handle();
2817 if (!FindBestFit(script, token_pos, last_token_pos, &func)) { 2683 if (!FindBestFit(script, token_pos, last_token_pos, &func)) {
2818 return NULL; 2684 return NULL;
2819 } 2685 }
2820 if (!func.IsNull()) { 2686 if (!func.IsNull()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2889 BreakpointLocation* bpt = 2755 BreakpointLocation* bpt =
2890 GetBreakpointLocation(script, token_pos, requested_column); 2756 GetBreakpointLocation(script, token_pos, requested_column);
2891 if (bpt == NULL) { 2757 if (bpt == NULL) {
2892 bpt = new BreakpointLocation(script, token_pos, last_token_pos, 2758 bpt = new BreakpointLocation(script, token_pos, last_token_pos,
2893 requested_line, requested_column); 2759 requested_line, requested_column);
2894 RegisterBreakpointLocation(bpt); 2760 RegisterBreakpointLocation(bpt);
2895 } 2761 }
2896 return bpt; 2762 return bpt;
2897 } 2763 }
2898 2764
2899
2900 // Synchronize the enabled/disabled state of all code breakpoints 2765 // Synchronize the enabled/disabled state of all code breakpoints
2901 // associated with the breakpoint location loc. 2766 // associated with the breakpoint location loc.
2902 void Debugger::SyncBreakpointLocation(BreakpointLocation* loc) { 2767 void Debugger::SyncBreakpointLocation(BreakpointLocation* loc) {
2903 bool any_enabled = loc->AnyEnabled(); 2768 bool any_enabled = loc->AnyEnabled();
2904 2769
2905 CodeBreakpoint* cbpt = code_breakpoints_; 2770 CodeBreakpoint* cbpt = code_breakpoints_;
2906 while (cbpt != NULL) { 2771 while (cbpt != NULL) {
2907 if (loc == cbpt->bpt_location()) { 2772 if (loc == cbpt->bpt_location()) {
2908 if (any_enabled) { 2773 if (any_enabled) {
2909 cbpt->Enable(); 2774 cbpt->Enable();
2910 } else { 2775 } else {
2911 cbpt->Disable(); 2776 cbpt->Disable();
2912 } 2777 }
2913 } 2778 }
2914 cbpt = cbpt->next(); 2779 cbpt = cbpt->next();
2915 } 2780 }
2916 } 2781 }
2917 2782
2918
2919 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) { 2783 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) {
2920 LongJumpScope jump; 2784 LongJumpScope jump;
2921 if (setjmp(*jump.Set()) == 0) { 2785 if (setjmp(*jump.Set()) == 0) {
2922 SetBreakpointAtEntry(target_function, true); 2786 SetBreakpointAtEntry(target_function, true);
2923 return Error::null(); 2787 return Error::null();
2924 } else { 2788 } else {
2925 return Thread::Current()->sticky_error(); 2789 return Thread::Current()->sticky_error();
2926 } 2790 }
2927 } 2791 }
2928 2792
2929
2930 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function, 2793 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
2931 bool single_shot) { 2794 bool single_shot) {
2932 ASSERT(!target_function.IsNull()); 2795 ASSERT(!target_function.IsNull());
2933 if (!target_function.is_debuggable()) { 2796 if (!target_function.is_debuggable()) {
2934 return NULL; 2797 return NULL;
2935 } 2798 }
2936 const Script& script = Script::Handle(target_function.script()); 2799 const Script& script = Script::Handle(target_function.script());
2937 BreakpointLocation* bpt_location = SetBreakpoint( 2800 BreakpointLocation* bpt_location = SetBreakpoint(
2938 script, target_function.token_pos(), target_function.end_token_pos(), -1, 2801 script, target_function.token_pos(), target_function.end_token_pos(), -1,
2939 -1 /* no requested line/col */); 2802 -1 /* no requested line/col */);
2940 if (single_shot) { 2803 if (single_shot) {
2941 return bpt_location->AddSingleShot(this); 2804 return bpt_location->AddSingleShot(this);
2942 } else { 2805 } else {
2943 return bpt_location->AddRepeated(this); 2806 return bpt_location->AddRepeated(this);
2944 } 2807 }
2945 } 2808 }
2946 2809
2947
2948 Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure, 2810 Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure,
2949 bool for_over_await) { 2811 bool for_over_await) {
2950 if (!closure.IsClosure()) { 2812 if (!closure.IsClosure()) {
2951 return NULL; 2813 return NULL;
2952 } 2814 }
2953 const Function& func = Function::Handle(Closure::Cast(closure).function()); 2815 const Function& func = Function::Handle(Closure::Cast(closure).function());
2954 const Script& script = Script::Handle(func.script()); 2816 const Script& script = Script::Handle(func.script());
2955 BreakpointLocation* bpt_location = SetBreakpoint( 2817 BreakpointLocation* bpt_location = SetBreakpoint(
2956 script, func.token_pos(), func.end_token_pos(), -1, -1 /* no line/col */); 2818 script, func.token_pos(), func.end_token_pos(), -1, -1 /* no line/col */);
2957 return bpt_location->AddPerClosure(this, closure, for_over_await); 2819 return bpt_location->AddPerClosure(this, closure, for_over_await);
2958 } 2820 }
2959 2821
2960
2961 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) { 2822 Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) {
2962 if (!closure.IsClosure()) { 2823 if (!closure.IsClosure()) {
2963 return NULL; 2824 return NULL;
2964 } 2825 }
2965 2826
2966 BreakpointLocation* loc = breakpoint_locations_; 2827 BreakpointLocation* loc = breakpoint_locations_;
2967 while (loc != NULL) { 2828 while (loc != NULL) {
2968 Breakpoint* bpt = loc->breakpoints(); 2829 Breakpoint* bpt = loc->breakpoints();
2969 while (bpt != NULL) { 2830 while (bpt != NULL) {
2970 if (bpt->IsPerClosure()) { 2831 if (bpt->IsPerClosure()) {
2971 if (closure.raw() == bpt->closure()) { 2832 if (closure.raw() == bpt->closure()) {
2972 return bpt; 2833 return bpt;
2973 } 2834 }
2974 } 2835 }
2975 bpt = bpt->next(); 2836 bpt = bpt->next();
2976 } 2837 }
2977 loc = loc->next(); 2838 loc = loc->next();
2978 } 2839 }
2979 2840
2980 return NULL; 2841 return NULL;
2981 } 2842 }
2982 2843
2983
2984 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, 2844 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
2985 intptr_t line_number) { 2845 intptr_t line_number) {
2986 // Prevent future tests from calling this function in the wrong 2846 // Prevent future tests from calling this function in the wrong
2987 // execution state. If you hit this assert, consider using 2847 // execution state. If you hit this assert, consider using
2988 // Dart_SetBreakpoint instead. 2848 // Dart_SetBreakpoint instead.
2989 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM); 2849 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2990 2850
2991 BreakpointLocation* loc = 2851 BreakpointLocation* loc =
2992 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */); 2852 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */);
2993 if (loc != NULL) { 2853 if (loc != NULL) {
2994 return loc->AddRepeated(this); 2854 return loc->AddRepeated(this);
2995 } 2855 }
2996 return NULL; 2856 return NULL;
2997 } 2857 }
2998 2858
2999
3000 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url, 2859 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url,
3001 intptr_t line_number, 2860 intptr_t line_number,
3002 intptr_t column_number) { 2861 intptr_t column_number) {
3003 // Prevent future tests from calling this function in the wrong 2862 // Prevent future tests from calling this function in the wrong
3004 // execution state. If you hit this assert, consider using 2863 // execution state. If you hit this assert, consider using
3005 // Dart_SetBreakpoint instead. 2864 // Dart_SetBreakpoint instead.
3006 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM); 2865 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
3007 2866
3008 BreakpointLocation* loc = 2867 BreakpointLocation* loc =
3009 BreakpointLocationAtLineCol(script_url, line_number, column_number); 2868 BreakpointLocationAtLineCol(script_url, line_number, column_number);
3010 if (loc != NULL) { 2869 if (loc != NULL) {
3011 return loc->AddRepeated(this); 2870 return loc->AddRepeated(this);
3012 } 2871 }
3013 return NULL; 2872 return NULL;
3014 } 2873 }
3015 2874
3016
3017 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( 2875 BreakpointLocation* Debugger::BreakpointLocationAtLineCol(
3018 const String& script_url, 2876 const String& script_url,
3019 intptr_t line_number, 2877 intptr_t line_number,
3020 intptr_t column_number) { 2878 intptr_t column_number) {
3021 Zone* zone = Thread::Current()->zone(); 2879 Zone* zone = Thread::Current()->zone();
3022 Library& lib = Library::Handle(zone); 2880 Library& lib = Library::Handle(zone);
3023 Script& script = Script::Handle(zone); 2881 Script& script = Script::Handle(zone);
3024 const GrowableObjectArray& libs = 2882 const GrowableObjectArray& libs =
3025 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); 2883 GrowableObjectArray::Handle(isolate_->object_store()->libraries());
3026 const GrowableObjectArray& scripts = 2884 const GrowableObjectArray& scripts =
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3077 column_number); 2935 column_number);
3078 first_token_idx.Next(); 2936 first_token_idx.Next();
3079 } 2937 }
3080 if ((bpt == NULL) && FLAG_verbose_debug) { 2938 if ((bpt == NULL) && FLAG_verbose_debug) {
3081 OS::Print("No executable code at line %" Pd " in '%s'\n", line_number, 2939 OS::Print("No executable code at line %" Pd " in '%s'\n", line_number,
3082 script_url.ToCString()); 2940 script_url.ToCString());
3083 } 2941 }
3084 return bpt; 2942 return bpt;
3085 } 2943 }
3086 2944
3087
3088 intptr_t Debugger::CacheObject(const Object& obj) { 2945 intptr_t Debugger::CacheObject(const Object& obj) {
3089 ASSERT(obj_cache_ != NULL); 2946 ASSERT(obj_cache_ != NULL);
3090 return obj_cache_->AddObject(obj); 2947 return obj_cache_->AddObject(obj);
3091 } 2948 }
3092 2949
3093
3094 bool Debugger::IsValidObjectId(intptr_t obj_id) { 2950 bool Debugger::IsValidObjectId(intptr_t obj_id) {
3095 ASSERT(obj_cache_ != NULL); 2951 ASSERT(obj_cache_ != NULL);
3096 return obj_cache_->IsValidId(obj_id); 2952 return obj_cache_->IsValidId(obj_id);
3097 } 2953 }
3098 2954
3099
3100 RawObject* Debugger::GetCachedObject(intptr_t obj_id) { 2955 RawObject* Debugger::GetCachedObject(intptr_t obj_id) {
3101 ASSERT(obj_cache_ != NULL); 2956 ASSERT(obj_cache_ != NULL);
3102 return obj_cache_->GetObj(obj_id); 2957 return obj_cache_->GetObj(obj_id);
3103 } 2958 }
3104 2959
3105 // TODO(hausner): Merge some of this functionality with the code in 2960 // TODO(hausner): Merge some of this functionality with the code in
3106 // dart_api_impl.cc. 2961 // dart_api_impl.cc.
3107 RawObject* Debugger::GetInstanceField(const Class& cls, 2962 RawObject* Debugger::GetInstanceField(const Class& cls,
3108 const String& field_name, 2963 const String& field_name,
3109 const Instance& object) { 2964 const Instance& object) {
(...skipping 10 matching lines...) Expand all
3120 const Array& args = Array::Handle(Array::New(1)); 2975 const Array& args = Array::Handle(Array::New(1));
3121 args.SetAt(0, object); 2976 args.SetAt(0, object);
3122 result = DartEntry::InvokeFunction(getter_func, args); 2977 result = DartEntry::InvokeFunction(getter_func, args);
3123 } else { 2978 } else {
3124 result = Thread::Current()->sticky_error(); 2979 result = Thread::Current()->sticky_error();
3125 } 2980 }
3126 ignore_breakpoints_ = saved_ignore_flag; 2981 ignore_breakpoints_ = saved_ignore_flag;
3127 return result.raw(); 2982 return result.raw();
3128 } 2983 }
3129 2984
3130
3131 RawObject* Debugger::GetStaticField(const Class& cls, 2985 RawObject* Debugger::GetStaticField(const Class& cls,
3132 const String& field_name) { 2986 const String& field_name) {
3133 const Field& fld = 2987 const Field& fld =
3134 Field::Handle(cls.LookupStaticFieldAllowPrivate(field_name)); 2988 Field::Handle(cls.LookupStaticFieldAllowPrivate(field_name));
3135 if (!fld.IsNull()) { 2989 if (!fld.IsNull()) {
3136 // Return the value in the field if it has been initialized already. 2990 // Return the value in the field if it has been initialized already.
3137 const Instance& value = Instance::Handle(fld.StaticValue()); 2991 const Instance& value = Instance::Handle(fld.StaticValue());
3138 ASSERT(value.raw() != Object::transition_sentinel().raw()); 2992 ASSERT(value.raw() != Object::transition_sentinel().raw());
3139 if (value.raw() != Object::sentinel().raw()) { 2993 if (value.raw() != Object::sentinel().raw()) {
3140 return value.raw(); 2994 return value.raw();
(...skipping 14 matching lines...) Expand all
3155 LongJumpScope jump; 3009 LongJumpScope jump;
3156 if (setjmp(*jump.Set()) == 0) { 3010 if (setjmp(*jump.Set()) == 0) {
3157 result = DartEntry::InvokeFunction(getter_func, Object::empty_array()); 3011 result = DartEntry::InvokeFunction(getter_func, Object::empty_array());
3158 } else { 3012 } else {
3159 result = Thread::Current()->sticky_error(); 3013 result = Thread::Current()->sticky_error();
3160 } 3014 }
3161 ignore_breakpoints_ = saved_ignore_flag; 3015 ignore_breakpoints_ = saved_ignore_flag;
3162 return result.raw(); 3016 return result.raw();
3163 } 3017 }
3164 3018
3165
3166 RawArray* Debugger::GetInstanceFields(const Instance& obj) { 3019 RawArray* Debugger::GetInstanceFields(const Instance& obj) {
3167 Class& cls = Class::Handle(obj.clazz()); 3020 Class& cls = Class::Handle(obj.clazz());
3168 Array& fields = Array::Handle(); 3021 Array& fields = Array::Handle();
3169 Field& field = Field::Handle(); 3022 Field& field = Field::Handle();
3170 const GrowableObjectArray& field_list = 3023 const GrowableObjectArray& field_list =
3171 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); 3024 GrowableObjectArray::Handle(GrowableObjectArray::New(8));
3172 String& field_name = String::Handle(); 3025 String& field_name = String::Handle();
3173 PassiveObject& field_value = PassiveObject::Handle(); 3026 PassiveObject& field_value = PassiveObject::Handle();
3174 // Iterate over fields in class hierarchy to count all instance fields. 3027 // Iterate over fields in class hierarchy to count all instance fields.
3175 while (!cls.IsNull()) { 3028 while (!cls.IsNull()) {
3176 fields = cls.fields(); 3029 fields = cls.fields();
3177 for (intptr_t i = 0; i < fields.Length(); i++) { 3030 for (intptr_t i = 0; i < fields.Length(); i++) {
3178 field ^= fields.At(i); 3031 field ^= fields.At(i);
3179 if (!field.is_static()) { 3032 if (!field.is_static()) {
3180 field_name = field.name(); 3033 field_name = field.name();
3181 field_list.Add(field_name); 3034 field_list.Add(field_name);
3182 field_value = GetInstanceField(cls, field_name, obj); 3035 field_value = GetInstanceField(cls, field_name, obj);
3183 field_list.Add(field_value); 3036 field_list.Add(field_value);
3184 } 3037 }
3185 } 3038 }
3186 cls = cls.SuperClass(); 3039 cls = cls.SuperClass();
3187 } 3040 }
3188 return Array::MakeFixedLength(field_list); 3041 return Array::MakeFixedLength(field_list);
3189 } 3042 }
3190 3043
3191
3192 RawArray* Debugger::GetStaticFields(const Class& cls) { 3044 RawArray* Debugger::GetStaticFields(const Class& cls) {
3193 const GrowableObjectArray& field_list = 3045 const GrowableObjectArray& field_list =
3194 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); 3046 GrowableObjectArray::Handle(GrowableObjectArray::New(8));
3195 Array& fields = Array::Handle(cls.fields()); 3047 Array& fields = Array::Handle(cls.fields());
3196 Field& field = Field::Handle(); 3048 Field& field = Field::Handle();
3197 String& field_name = String::Handle(); 3049 String& field_name = String::Handle();
3198 PassiveObject& field_value = PassiveObject::Handle(); 3050 PassiveObject& field_value = PassiveObject::Handle();
3199 for (intptr_t i = 0; i < fields.Length(); i++) { 3051 for (intptr_t i = 0; i < fields.Length(); i++) {
3200 field ^= fields.At(i); 3052 field ^= fields.At(i);
3201 if (field.is_static()) { 3053 if (field.is_static()) {
3202 field_name = field.name(); 3054 field_name = field.name();
3203 field_value = GetStaticField(cls, field_name); 3055 field_value = GetStaticField(cls, field_name);
3204 field_list.Add(field_name); 3056 field_list.Add(field_name);
3205 field_list.Add(field_value); 3057 field_list.Add(field_value);
3206 } 3058 }
3207 } 3059 }
3208 return Array::MakeFixedLength(field_list); 3060 return Array::MakeFixedLength(field_list);
3209 } 3061 }
3210 3062
3211
3212 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, 3063 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list,
3213 const Library& lib, 3064 const Library& lib,
3214 const String& prefix, 3065 const String& prefix,
3215 bool include_private_fields) { 3066 bool include_private_fields) {
3216 DictionaryIterator it(lib); 3067 DictionaryIterator it(lib);
3217 Zone* zone = Thread::Current()->zone(); 3068 Zone* zone = Thread::Current()->zone();
3218 Object& entry = Object::Handle(zone); 3069 Object& entry = Object::Handle(zone);
3219 Field& field = Field::Handle(zone); 3070 Field& field = Field::Handle(zone);
3220 String& field_name = String::Handle(zone); 3071 String& field_name = String::Handle(zone);
3221 PassiveObject& field_value = PassiveObject::Handle(zone); 3072 PassiveObject& field_value = PassiveObject::Handle(zone);
(...skipping 18 matching lines...) Expand all
3240 } 3091 }
3241 if (!prefix.IsNull()) { 3092 if (!prefix.IsNull()) {
3242 field_name = String::Concat(prefix, field_name); 3093 field_name = String::Concat(prefix, field_name);
3243 } 3094 }
3244 field_list.Add(field_name); 3095 field_list.Add(field_name);
3245 field_list.Add(field_value); 3096 field_list.Add(field_value);
3246 } 3097 }
3247 } 3098 }
3248 } 3099 }
3249 3100
3250
3251 RawArray* Debugger::GetLibraryFields(const Library& lib) { 3101 RawArray* Debugger::GetLibraryFields(const Library& lib) {
3252 Zone* zone = Thread::Current()->zone(); 3102 Zone* zone = Thread::Current()->zone();
3253 const GrowableObjectArray& field_list = 3103 const GrowableObjectArray& field_list =
3254 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); 3104 GrowableObjectArray::Handle(GrowableObjectArray::New(8));
3255 CollectLibraryFields(field_list, lib, String::Handle(zone), true); 3105 CollectLibraryFields(field_list, lib, String::Handle(zone), true);
3256 return Array::MakeFixedLength(field_list); 3106 return Array::MakeFixedLength(field_list);
3257 } 3107 }
3258 3108
3259
3260 RawArray* Debugger::GetGlobalFields(const Library& lib) { 3109 RawArray* Debugger::GetGlobalFields(const Library& lib) {
3261 Zone* zone = Thread::Current()->zone(); 3110 Zone* zone = Thread::Current()->zone();
3262 const GrowableObjectArray& field_list = 3111 const GrowableObjectArray& field_list =
3263 GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8)); 3112 GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8));
3264 String& prefix_name = String::Handle(zone); 3113 String& prefix_name = String::Handle(zone);
3265 CollectLibraryFields(field_list, lib, prefix_name, true); 3114 CollectLibraryFields(field_list, lib, prefix_name, true);
3266 Library& imported = Library::Handle(zone); 3115 Library& imported = Library::Handle(zone);
3267 intptr_t num_imports = lib.num_imports(); 3116 intptr_t num_imports = lib.num_imports();
3268 for (intptr_t i = 0; i < num_imports; i++) { 3117 for (intptr_t i = 0; i < num_imports; i++) {
3269 imported = lib.ImportLibraryAt(i); 3118 imported = lib.ImportLibraryAt(i);
3270 ASSERT(!imported.IsNull()); 3119 ASSERT(!imported.IsNull());
3271 CollectLibraryFields(field_list, imported, prefix_name, false); 3120 CollectLibraryFields(field_list, imported, prefix_name, false);
3272 } 3121 }
3273 LibraryPrefix& prefix = LibraryPrefix::Handle(zone); 3122 LibraryPrefix& prefix = LibraryPrefix::Handle(zone);
3274 LibraryPrefixIterator it(lib); 3123 LibraryPrefixIterator it(lib);
3275 while (it.HasNext()) { 3124 while (it.HasNext()) {
3276 prefix = it.GetNext(); 3125 prefix = it.GetNext();
3277 prefix_name = prefix.name(); 3126 prefix_name = prefix.name();
3278 ASSERT(!prefix_name.IsNull()); 3127 ASSERT(!prefix_name.IsNull());
3279 prefix_name = String::Concat(prefix_name, Symbols::Dot()); 3128 prefix_name = String::Concat(prefix_name, Symbols::Dot());
3280 for (int32_t i = 0; i < prefix.num_imports(); i++) { 3129 for (int32_t i = 0; i < prefix.num_imports(); i++) {
3281 imported = prefix.GetLibrary(i); 3130 imported = prefix.GetLibrary(i);
3282 CollectLibraryFields(field_list, imported, prefix_name, false); 3131 CollectLibraryFields(field_list, imported, prefix_name, false);
3283 } 3132 }
3284 } 3133 }
3285 return Array::MakeFixedLength(field_list); 3134 return Array::MakeFixedLength(field_list);
3286 } 3135 }
3287 3136
3288
3289 // static 3137 // static
3290 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { 3138 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
3291 ASSERT(visitor != NULL); 3139 ASSERT(visitor != NULL);
3292 BreakpointLocation* bpt = breakpoint_locations_; 3140 BreakpointLocation* bpt = breakpoint_locations_;
3293 while (bpt != NULL) { 3141 while (bpt != NULL) {
3294 bpt->VisitObjectPointers(visitor); 3142 bpt->VisitObjectPointers(visitor);
3295 bpt = bpt->next(); 3143 bpt = bpt->next();
3296 } 3144 }
3297 bpt = latent_locations_; 3145 bpt = latent_locations_;
3298 while (bpt != NULL) { 3146 while (bpt != NULL) {
3299 bpt->VisitObjectPointers(visitor); 3147 bpt->VisitObjectPointers(visitor);
3300 bpt = bpt->next(); 3148 bpt = bpt->next();
3301 } 3149 }
3302 CodeBreakpoint* cbpt = code_breakpoints_; 3150 CodeBreakpoint* cbpt = code_breakpoints_;
3303 while (cbpt != NULL) { 3151 while (cbpt != NULL) {
3304 cbpt->VisitObjectPointers(visitor); 3152 cbpt->VisitObjectPointers(visitor);
3305 cbpt = cbpt->next(); 3153 cbpt = cbpt->next();
3306 } 3154 }
3307 visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_)); 3155 visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_frame_awaiter_));
3308 } 3156 }
3309 3157
3310
3311 // static 3158 // static
3312 void Debugger::SetEventHandler(EventHandler* handler) { 3159 void Debugger::SetEventHandler(EventHandler* handler) {
3313 event_handler_ = handler; 3160 event_handler_ = handler;
3314 } 3161 }
3315 3162
3316
3317 void Debugger::Pause(ServiceEvent* event) { 3163 void Debugger::Pause(ServiceEvent* event) {
3318 ASSERT(event->IsPause()); // Should call InvokeEventHandler instead. 3164 ASSERT(event->IsPause()); // Should call InvokeEventHandler instead.
3319 ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts. 3165 ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts.
3320 ASSERT(!IsPaused()); // No recursive pausing. 3166 ASSERT(!IsPaused()); // No recursive pausing.
3321 ASSERT(obj_cache_ == NULL); 3167 ASSERT(obj_cache_ == NULL);
3322 3168
3323 pause_event_ = event; 3169 pause_event_ = event;
3324 pause_event_->UpdateTimestamp(); 3170 pause_event_->UpdateTimestamp();
3325 obj_cache_ = new RemoteObjectCache(64); 3171 obj_cache_ = new RemoteObjectCache(64);
3326 3172
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 } 3205 }
3360 } 3206 }
3361 3207
3362 if (needs_breakpoint_cleanup_) { 3208 if (needs_breakpoint_cleanup_) {
3363 RemoveUnlinkedCodeBreakpoints(); 3209 RemoveUnlinkedCodeBreakpoints();
3364 } 3210 }
3365 pause_event_ = NULL; 3211 pause_event_ = NULL;
3366 obj_cache_ = NULL; // Zone allocated 3212 obj_cache_ = NULL; // Zone allocated
3367 } 3213 }
3368 3214
3369
3370 void Debugger::EnterSingleStepMode() { 3215 void Debugger::EnterSingleStepMode() {
3371 ResetSteppingFramePointers(); 3216 ResetSteppingFramePointers();
3372 DeoptimizeWorld(); 3217 DeoptimizeWorld();
3373 isolate_->set_single_step(true); 3218 isolate_->set_single_step(true);
3374 } 3219 }
3375 3220
3376
3377 void Debugger::ResetSteppingFramePointers() { 3221 void Debugger::ResetSteppingFramePointers() {
3378 stepping_fp_ = 0; 3222 stepping_fp_ = 0;
3379 async_stepping_fp_ = 0; 3223 async_stepping_fp_ = 0;
3380 } 3224 }
3381 3225
3382
3383 bool Debugger::SteppedForSyntheticAsyncBreakpoint() const { 3226 bool Debugger::SteppedForSyntheticAsyncBreakpoint() const {
3384 return synthetic_async_breakpoint_ != NULL; 3227 return synthetic_async_breakpoint_ != NULL;
3385 } 3228 }
3386 3229
3387
3388 void Debugger::CleanupSyntheticAsyncBreakpoint() { 3230 void Debugger::CleanupSyntheticAsyncBreakpoint() {
3389 if (synthetic_async_breakpoint_ != NULL) { 3231 if (synthetic_async_breakpoint_ != NULL) {
3390 RemoveBreakpoint(synthetic_async_breakpoint_->id()); 3232 RemoveBreakpoint(synthetic_async_breakpoint_->id());
3391 synthetic_async_breakpoint_ = NULL; 3233 synthetic_async_breakpoint_ = NULL;
3392 } 3234 }
3393 } 3235 }
3394 3236
3395
3396 void Debugger::RememberTopFrameAwaiter() { 3237 void Debugger::RememberTopFrameAwaiter() {
3397 if (!FLAG_async_debugger) { 3238 if (!FLAG_async_debugger) {
3398 return; 3239 return;
3399 } 3240 }
3400 if (stack_trace_->Length() > 0) { 3241 if (stack_trace_->Length() > 0) {
3401 top_frame_awaiter_ = stack_trace_->FrameAt(0)->GetAsyncAwaiter(); 3242 top_frame_awaiter_ = stack_trace_->FrameAt(0)->GetAsyncAwaiter();
3402 } else { 3243 } else {
3403 top_frame_awaiter_ = Object::null(); 3244 top_frame_awaiter_ = Object::null();
3404 } 3245 }
3405 } 3246 }
3406 3247
3407
3408 void Debugger::SetAsyncSteppingFramePointer() { 3248 void Debugger::SetAsyncSteppingFramePointer() {
3409 if (!FLAG_async_debugger) { 3249 if (!FLAG_async_debugger) {
3410 return; 3250 return;
3411 } 3251 }
3412 if (stack_trace_->FrameAt(0)->function().IsAsyncClosure() || 3252 if (stack_trace_->FrameAt(0)->function().IsAsyncClosure() ||
3413 stack_trace_->FrameAt(0)->function().IsAsyncGenClosure()) { 3253 stack_trace_->FrameAt(0)->function().IsAsyncGenClosure()) {
3414 async_stepping_fp_ = stack_trace_->FrameAt(0)->fp(); 3254 async_stepping_fp_ = stack_trace_->FrameAt(0)->fp();
3415 } else { 3255 } else {
3416 async_stepping_fp_ = 0; 3256 async_stepping_fp_ = 0;
3417 } 3257 }
3418 } 3258 }
3419 3259
3420
3421 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace, 3260 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
3422 bool skip_next_step) { 3261 bool skip_next_step) {
3423 ResetSteppingFramePointers(); 3262 ResetSteppingFramePointers();
3424 RememberTopFrameAwaiter(); 3263 RememberTopFrameAwaiter();
3425 if (resume_action_ == kStepInto) { 3264 if (resume_action_ == kStepInto) {
3426 // When single stepping, we need to deoptimize because we might be 3265 // When single stepping, we need to deoptimize because we might be
3427 // stepping into optimized code. This happens in particular if 3266 // stepping into optimized code. This happens in particular if
3428 // the isolate has been interrupted, but can happen in other cases 3267 // the isolate has been interrupted, but can happen in other cases
3429 // as well. We need to deoptimize the world in case we are about 3268 // as well. We need to deoptimize the world in case we are about
3430 // to call an optimized function. 3269 // to call an optimized function.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
3488 while ((frame != NULL)) { 3327 while ((frame != NULL)) {
3489 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString()); 3328 OS::PrintErr("#%04" Pd " %s\n", num++, frame->ToCString());
3490 frame = iterator.NextFrame(); 3329 frame = iterator.NextFrame();
3491 } 3330 }
3492 } 3331 }
3493 RewindToFrame(resume_frame_index_); 3332 RewindToFrame(resume_frame_index_);
3494 UNREACHABLE(); 3333 UNREACHABLE();
3495 } 3334 }
3496 } 3335 }
3497 3336
3498
3499 void Debugger::CacheStackTraces(DebuggerStackTrace* stack_trace, 3337 void Debugger::CacheStackTraces(DebuggerStackTrace* stack_trace,
3500 DebuggerStackTrace* async_causal_stack_trace, 3338 DebuggerStackTrace* async_causal_stack_trace,
3501 DebuggerStackTrace* awaiter_stack_trace) { 3339 DebuggerStackTrace* awaiter_stack_trace) {
3502 ASSERT(stack_trace_ == NULL); 3340 ASSERT(stack_trace_ == NULL);
3503 stack_trace_ = stack_trace; 3341 stack_trace_ = stack_trace;
3504 ASSERT(async_causal_stack_trace_ == NULL); 3342 ASSERT(async_causal_stack_trace_ == NULL);
3505 async_causal_stack_trace_ = async_causal_stack_trace; 3343 async_causal_stack_trace_ = async_causal_stack_trace;
3506 ASSERT(awaiter_stack_trace_ == NULL); 3344 ASSERT(awaiter_stack_trace_ == NULL);
3507 awaiter_stack_trace_ = awaiter_stack_trace; 3345 awaiter_stack_trace_ = awaiter_stack_trace;
3508 } 3346 }
3509 3347
3510
3511 void Debugger::ClearCachedStackTraces() { 3348 void Debugger::ClearCachedStackTraces() {
3512 stack_trace_ = NULL; 3349 stack_trace_ = NULL;
3513 async_causal_stack_trace_ = NULL; 3350 async_causal_stack_trace_ = NULL;
3514 awaiter_stack_trace_ = NULL; 3351 awaiter_stack_trace_ = NULL;
3515 } 3352 }
3516 3353
3517
3518 static intptr_t FindNextRewindFrameIndex(DebuggerStackTrace* stack, 3354 static intptr_t FindNextRewindFrameIndex(DebuggerStackTrace* stack,
3519 intptr_t frame_index) { 3355 intptr_t frame_index) {
3520 for (intptr_t i = frame_index + 1; i < stack->Length(); i++) { 3356 for (intptr_t i = frame_index + 1; i < stack->Length(); i++) {
3521 ActivationFrame* frame = stack->FrameAt(i); 3357 ActivationFrame* frame = stack->FrameAt(i);
3522 if (frame->IsRewindable()) { 3358 if (frame->IsRewindable()) {
3523 return i; 3359 return i;
3524 } 3360 }
3525 } 3361 }
3526 return -1; 3362 return -1;
3527 } 3363 }
3528 3364
3529
3530 // Can the top frame be rewound? 3365 // Can the top frame be rewound?
3531 bool Debugger::CanRewindFrame(intptr_t frame_index, const char** error) const { 3366 bool Debugger::CanRewindFrame(intptr_t frame_index, const char** error) const {
3532 // check rewind pc is found 3367 // check rewind pc is found
3533 DebuggerStackTrace* stack = Isolate::Current()->debugger()->StackTrace(); 3368 DebuggerStackTrace* stack = Isolate::Current()->debugger()->StackTrace();
3534 intptr_t num_frames = stack->Length(); 3369 intptr_t num_frames = stack->Length();
3535 if (frame_index < 1 || frame_index >= num_frames) { 3370 if (frame_index < 1 || frame_index >= num_frames) {
3536 if (error) { 3371 if (error) {
3537 *error = Thread::Current()->zone()->PrintToString( 3372 *error = Thread::Current()->zone()->PrintToString(
3538 "Frame must be in bounds [1..%" Pd 3373 "Frame must be in bounds [1..%" Pd
3539 "]: " 3374 "]: "
(...skipping 21 matching lines...) Expand all
3561 "optimizations. " 3396 "optimizations. "
3562 "Run the vm with --no-prune-dead-locals to disallow these " 3397 "Run the vm with --no-prune-dead-locals to disallow these "
3563 "optimizations.", 3398 "optimizations.",
3564 frame_index); 3399 frame_index);
3565 } 3400 }
3566 return false; 3401 return false;
3567 } 3402 }
3568 return true; 3403 return true;
3569 } 3404 }
3570 3405
3571
3572 // Given a return address pc, find the "rewind" pc, which is the pc 3406 // Given a return address pc, find the "rewind" pc, which is the pc
3573 // before the corresponding call. 3407 // before the corresponding call.
3574 static uword LookupRewindPc(const Code& code, uword pc) { 3408 static uword LookupRewindPc(const Code& code, uword pc) {
3575 ASSERT(!code.is_optimized()); 3409 ASSERT(!code.is_optimized());
3576 ASSERT(code.ContainsInstructionAt(pc)); 3410 ASSERT(code.ContainsInstructionAt(pc));
3577 3411
3578 uword pc_offset = pc - code.PayloadStart(); 3412 uword pc_offset = pc - code.PayloadStart();
3579 const PcDescriptors& descriptors = 3413 const PcDescriptors& descriptors =
3580 PcDescriptors::Handle(code.pc_descriptors()); 3414 PcDescriptors::Handle(code.pc_descriptors());
3581 PcDescriptors::Iterator iter( 3415 PcDescriptors::Iterator iter(
3582 descriptors, RawPcDescriptors::kRewind | RawPcDescriptors::kIcCall | 3416 descriptors, RawPcDescriptors::kRewind | RawPcDescriptors::kIcCall |
3583 RawPcDescriptors::kUnoptStaticCall); 3417 RawPcDescriptors::kUnoptStaticCall);
3584 intptr_t rewind_deopt_id = -1; 3418 intptr_t rewind_deopt_id = -1;
3585 uword rewind_pc = 0; 3419 uword rewind_pc = 0;
3586 while (iter.MoveNext()) { 3420 while (iter.MoveNext()) {
3587 if (iter.Kind() == RawPcDescriptors::kRewind) { 3421 if (iter.Kind() == RawPcDescriptors::kRewind) {
3588 // Remember the last rewind so we don't need to iterator twice. 3422 // Remember the last rewind so we don't need to iterator twice.
3589 rewind_pc = code.PayloadStart() + iter.PcOffset(); 3423 rewind_pc = code.PayloadStart() + iter.PcOffset();
3590 rewind_deopt_id = iter.DeoptId(); 3424 rewind_deopt_id = iter.DeoptId();
3591 } 3425 }
3592 if ((pc_offset == iter.PcOffset()) && (iter.DeoptId() == rewind_deopt_id)) { 3426 if ((pc_offset == iter.PcOffset()) && (iter.DeoptId() == rewind_deopt_id)) {
3593 return rewind_pc; 3427 return rewind_pc;
3594 } 3428 }
3595 } 3429 }
3596 return 0; 3430 return 0;
3597 } 3431 }
3598 3432
3599
3600 void Debugger::RewindToFrame(intptr_t frame_index) { 3433 void Debugger::RewindToFrame(intptr_t frame_index) {
3601 Thread* thread = Thread::Current(); 3434 Thread* thread = Thread::Current();
3602 Zone* zone = thread->zone(); 3435 Zone* zone = thread->zone();
3603 Code& code = Code::Handle(zone); 3436 Code& code = Code::Handle(zone);
3604 Function& function = Function::Handle(zone); 3437 Function& function = Function::Handle(zone);
3605 3438
3606 // Find the requested frame. 3439 // Find the requested frame.
3607 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 3440 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
3608 Thread::Current(), 3441 Thread::Current(),
3609 StackFrameIterator::kNoCrossThreadIteration); 3442 StackFrameIterator::kNoCrossThreadIteration);
(...skipping 24 matching lines...) Expand all
3634 RewindToUnoptimizedFrame(frame, code); 3467 RewindToUnoptimizedFrame(frame, code);
3635 UNREACHABLE(); 3468 UNREACHABLE();
3636 } 3469 }
3637 current_frame++; 3470 current_frame++;
3638 } 3471 }
3639 } 3472 }
3640 } 3473 }
3641 UNIMPLEMENTED(); 3474 UNIMPLEMENTED();
3642 } 3475 }
3643 3476
3644
3645 void Debugger::RewindToUnoptimizedFrame(StackFrame* frame, const Code& code) { 3477 void Debugger::RewindToUnoptimizedFrame(StackFrame* frame, const Code& code) {
3646 // We will be jumping out of the debugger rather than exiting this 3478 // We will be jumping out of the debugger rather than exiting this
3647 // function, so prepare the debugger state. 3479 // function, so prepare the debugger state.
3648 ClearCachedStackTraces(); 3480 ClearCachedStackTraces();
3649 resume_action_ = kContinue; 3481 resume_action_ = kContinue;
3650 resume_frame_index_ = -1; 3482 resume_frame_index_ = -1;
3651 EnterSingleStepMode(); 3483 EnterSingleStepMode();
3652 3484
3653 uword rewind_pc = LookupRewindPc(code, frame->pc()); 3485 uword rewind_pc = LookupRewindPc(code, frame->pc());
3654 if (FLAG_trace_rewind && rewind_pc == 0) { 3486 if (FLAG_trace_rewind && rewind_pc == 0) {
3655 OS::PrintErr("Unable to find rewind pc for pc(%" Px ")\n", frame->pc()); 3487 OS::PrintErr("Unable to find rewind pc for pc(%" Px ")\n", frame->pc());
3656 } 3488 }
3657 ASSERT(rewind_pc != 0); 3489 ASSERT(rewind_pc != 0);
3658 if (FLAG_trace_rewind) { 3490 if (FLAG_trace_rewind) {
3659 OS::PrintErr( 3491 OS::PrintErr(
3660 "===============================\n" 3492 "===============================\n"
3661 "Rewinding to unoptimized frame:\n" 3493 "Rewinding to unoptimized frame:\n"
3662 " rewind_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px 3494 " rewind_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px
3663 ")\n" 3495 ")\n"
3664 "===============================\n", 3496 "===============================\n",
3665 rewind_pc, frame->sp(), frame->fp()); 3497 rewind_pc, frame->sp(), frame->fp());
3666 } 3498 }
3667 Exceptions::JumpToFrame(Thread::Current(), rewind_pc, frame->sp(), 3499 Exceptions::JumpToFrame(Thread::Current(), rewind_pc, frame->sp(),
3668 frame->fp(), true /* clear lazy deopt at target */); 3500 frame->fp(), true /* clear lazy deopt at target */);
3669 UNREACHABLE(); 3501 UNREACHABLE();
3670 } 3502 }
3671 3503
3672
3673 void Debugger::RewindToOptimizedFrame(StackFrame* frame, 3504 void Debugger::RewindToOptimizedFrame(StackFrame* frame,
3674 const Code& optimized_code, 3505 const Code& optimized_code,
3675 intptr_t sub_index) { 3506 intptr_t sub_index) {
3676 post_deopt_frame_index_ = sub_index; 3507 post_deopt_frame_index_ = sub_index;
3677 3508
3678 // We will be jumping out of the debugger rather than exiting this 3509 // We will be jumping out of the debugger rather than exiting this
3679 // function, so prepare the debugger state. 3510 // function, so prepare the debugger state.
3680 ClearCachedStackTraces(); 3511 ClearCachedStackTraces();
3681 resume_action_ = kContinue; 3512 resume_action_ = kContinue;
3682 resume_frame_index_ = -1; 3513 resume_frame_index_ = -1;
3683 EnterSingleStepMode(); 3514 EnterSingleStepMode();
3684 3515
3685 if (FLAG_trace_rewind) { 3516 if (FLAG_trace_rewind) {
3686 OS::PrintErr( 3517 OS::PrintErr(
3687 "===============================\n" 3518 "===============================\n"
3688 "Deoptimizing frame for rewind:\n" 3519 "Deoptimizing frame for rewind:\n"
3689 " deopt_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px 3520 " deopt_pc(0x%" Px ") sp(0x%" Px ") fp(0x%" Px
3690 ")\n" 3521 ")\n"
3691 "===============================\n", 3522 "===============================\n",
3692 frame->pc(), frame->sp(), frame->fp()); 3523 frame->pc(), frame->sp(), frame->fp());
3693 } 3524 }
3694 Thread* thread = Thread::Current(); 3525 Thread* thread = Thread::Current();
3695 thread->set_resume_pc(frame->pc()); 3526 thread->set_resume_pc(frame->pc());
3696 uword deopt_stub_pc = StubCode::DeoptForRewind_entry()->EntryPoint(); 3527 uword deopt_stub_pc = StubCode::DeoptForRewind_entry()->EntryPoint();
3697 Exceptions::JumpToFrame(thread, deopt_stub_pc, frame->sp(), frame->fp(), 3528 Exceptions::JumpToFrame(thread, deopt_stub_pc, frame->sp(), frame->fp(),
3698 true /* clear lazy deopt at target */); 3529 true /* clear lazy deopt at target */);
3699 UNREACHABLE(); 3530 UNREACHABLE();
3700 } 3531 }
3701 3532
3702
3703 void Debugger::RewindPostDeopt() { 3533 void Debugger::RewindPostDeopt() {
3704 intptr_t rewind_frame = post_deopt_frame_index_; 3534 intptr_t rewind_frame = post_deopt_frame_index_;
3705 post_deopt_frame_index_ = -1; 3535 post_deopt_frame_index_ = -1;
3706 if (FLAG_trace_rewind) { 3536 if (FLAG_trace_rewind) {
3707 OS::PrintErr("Post deopt, jumping to frame %" Pd "\n", rewind_frame); 3537 OS::PrintErr("Post deopt, jumping to frame %" Pd "\n", rewind_frame);
3708 OS::PrintErr( 3538 OS::PrintErr(
3709 "-------------------------\n" 3539 "-------------------------\n"
3710 "All frames...\n\n"); 3540 "All frames...\n\n");
3711 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, 3541 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames,
3712 Thread::Current(), 3542 Thread::Current(),
(...skipping 22 matching lines...) Expand all
3735 ASSERT(!code.is_optimized()); 3565 ASSERT(!code.is_optimized());
3736 if (current_frame == rewind_frame) { 3566 if (current_frame == rewind_frame) {
3737 RewindToUnoptimizedFrame(frame, code); 3567 RewindToUnoptimizedFrame(frame, code);
3738 UNREACHABLE(); 3568 UNREACHABLE();
3739 } 3569 }
3740 current_frame++; 3570 current_frame++;
3741 } 3571 }
3742 } 3572 }
3743 } 3573 }
3744 3574
3745
3746 // static 3575 // static
3747 bool Debugger::IsDebuggable(const Function& func) { 3576 bool Debugger::IsDebuggable(const Function& func) {
3748 if (!func.is_debuggable()) { 3577 if (!func.is_debuggable()) {
3749 return false; 3578 return false;
3750 } 3579 }
3751 const Class& cls = Class::Handle(func.Owner()); 3580 const Class& cls = Class::Handle(func.Owner());
3752 const Library& lib = Library::Handle(cls.library()); 3581 const Library& lib = Library::Handle(cls.library());
3753 return lib.IsDebuggable(); 3582 return lib.IsDebuggable();
3754 } 3583 }
3755 3584
3756
3757 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) { 3585 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt) {
3758 resume_action_ = kContinue; 3586 resume_action_ = kContinue;
3759 ResetSteppingFramePointers(); 3587 ResetSteppingFramePointers();
3760 isolate_->set_single_step(false); 3588 isolate_->set_single_step(false);
3761 ASSERT(!IsPaused()); 3589 ASSERT(!IsPaused());
3762 ASSERT(obj_cache_ == NULL); 3590 ASSERT(obj_cache_ == NULL);
3763 if ((bpt != NULL) && bpt->IsSingleShot()) { 3591 if ((bpt != NULL) && bpt->IsSingleShot()) {
3764 RemoveBreakpoint(bpt->id()); 3592 RemoveBreakpoint(bpt->id());
3765 bpt = NULL; 3593 bpt = NULL;
3766 } 3594 }
3767 3595
3768 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint); 3596 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint);
3769 event.set_top_frame(top_frame); 3597 event.set_top_frame(top_frame);
3770 event.set_breakpoint(bpt); 3598 event.set_breakpoint(bpt);
3771 event.set_at_async_jump(IsAtAsyncJump(top_frame)); 3599 event.set_at_async_jump(IsAtAsyncJump(top_frame));
3772 Pause(&event); 3600 Pause(&event);
3773 } 3601 }
3774 3602
3775
3776 bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) { 3603 bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
3777 Zone* zone = Thread::Current()->zone(); 3604 Zone* zone = Thread::Current()->zone();
3778 Object& closure_or_null = 3605 Object& closure_or_null =
3779 Object::Handle(zone, top_frame->GetAsyncOperation()); 3606 Object::Handle(zone, top_frame->GetAsyncOperation());
3780 if (!closure_or_null.IsNull()) { 3607 if (!closure_or_null.IsNull()) {
3781 ASSERT(closure_or_null.IsInstance()); 3608 ASSERT(closure_or_null.IsInstance());
3782 ASSERT(Instance::Cast(closure_or_null).IsClosure()); 3609 ASSERT(Instance::Cast(closure_or_null).IsClosure());
3783 const Script& script = Script::Handle(zone, top_frame->SourceScript()); 3610 const Script& script = Script::Handle(zone, top_frame->SourceScript());
3784 if (script.kind() == RawScript::kKernelTag) { 3611 if (script.kind() == RawScript::kKernelTag) {
3785 // Are we at a yield point (previous await)? 3612 // Are we at a yield point (previous await)?
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3870 ASSERT(!HasActiveBreakpoint(frame->pc())); 3697 ASSERT(!HasActiveBreakpoint(frame->pc()));
3871 3698
3872 if (FLAG_verbose_debug) { 3699 if (FLAG_verbose_debug) {
3873 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", 3700 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n",
3874 String::Handle(frame->SourceUrl()).ToCString(), 3701 String::Handle(frame->SourceUrl()).ToCString(),
3875 frame->LineNumber(), 3702 frame->LineNumber(),
3876 String::Handle(frame->QualifiedFunctionName()).ToCString(), 3703 String::Handle(frame->QualifiedFunctionName()).ToCString(),
3877 frame->TokenPos().ToCString()); 3704 frame->TokenPos().ToCString());
3878 } 3705 }
3879 3706
3880
3881 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(), 3707 CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(),
3882 CollectAwaiterReturnStackTrace()); 3708 CollectAwaiterReturnStackTrace());
3883 if (SteppedForSyntheticAsyncBreakpoint()) { 3709 if (SteppedForSyntheticAsyncBreakpoint()) {
3884 CleanupSyntheticAsyncBreakpoint(); 3710 CleanupSyntheticAsyncBreakpoint();
3885 } 3711 }
3886 SignalPausedEvent(frame, NULL); 3712 SignalPausedEvent(frame, NULL);
3887 HandleSteppingRequest(stack_trace_); 3713 HandleSteppingRequest(stack_trace_);
3888 ClearCachedStackTraces(); 3714 ClearCachedStackTraces();
3889 3715
3890 // If any error occurred while in the debug message loop, return it here. 3716 // If any error occurred while in the debug message loop, return it here.
3891 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 3717 const Error& error = Error::Handle(Thread::Current()->sticky_error());
3892 Thread::Current()->clear_sticky_error(); 3718 Thread::Current()->clear_sticky_error();
3893 return error.raw(); 3719 return error.raw();
3894 } 3720 }
3895 3721
3896
3897 RawError* Debugger::PauseBreakpoint() { 3722 RawError* Debugger::PauseBreakpoint() {
3898 // We ignore this breakpoint when the VM is executing code invoked 3723 // We ignore this breakpoint when the VM is executing code invoked
3899 // by the debugger to evaluate variables values, or when we see a nested 3724 // by the debugger to evaluate variables values, or when we see a nested
3900 // breakpoint or exception event. 3725 // breakpoint or exception event.
3901 if (ignore_breakpoints_ || IsPaused()) { 3726 if (ignore_breakpoints_ || IsPaused()) {
3902 return Error::null(); 3727 return Error::null();
3903 } 3728 }
3904 DebuggerStackTrace* stack_trace = CollectStackTrace(); 3729 DebuggerStackTrace* stack_trace = CollectStackTrace();
3905 ASSERT(stack_trace->Length() > 0); 3730 ASSERT(stack_trace->Length() > 0);
3906 ActivationFrame* top_frame = stack_trace->FrameAt(0); 3731 ActivationFrame* top_frame = stack_trace->FrameAt(0);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3959 // point will be at the exact same pc. Skip it. 3784 // point will be at the exact same pc. Skip it.
3960 HandleSteppingRequest(stack_trace_, true /* skip next step */); 3785 HandleSteppingRequest(stack_trace_, true /* skip next step */);
3961 ClearCachedStackTraces(); 3786 ClearCachedStackTraces();
3962 3787
3963 // If any error occurred while in the debug message loop, return it here. 3788 // If any error occurred while in the debug message loop, return it here.
3964 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 3789 const Error& error = Error::Handle(Thread::Current()->sticky_error());
3965 Thread::Current()->clear_sticky_error(); 3790 Thread::Current()->clear_sticky_error();
3966 return error.raw(); 3791 return error.raw();
3967 } 3792 }
3968 3793
3969
3970 Breakpoint* Debugger::FindHitBreakpoint(BreakpointLocation* location, 3794 Breakpoint* Debugger::FindHitBreakpoint(BreakpointLocation* location,
3971 ActivationFrame* top_frame) { 3795 ActivationFrame* top_frame) {
3972 if (location == NULL) { 3796 if (location == NULL) {
3973 return NULL; 3797 return NULL;
3974 } 3798 }
3975 // There may be more than one applicable breakpoint at this location, but we 3799 // There may be more than one applicable breakpoint at this location, but we
3976 // will report only one as reached. If there is a single-shot breakpoint, we 3800 // will report only one as reached. If there is a single-shot breakpoint, we
3977 // favor it; then a closure-specific breakpoint ; then an general breakpoint. 3801 // favor it; then a closure-specific breakpoint ; then an general breakpoint.
3978 3802
3979 // First check for a single-shot breakpoint. 3803 // First check for a single-shot breakpoint.
(...skipping 24 matching lines...) Expand all
4004 while (bpt != NULL) { 3828 while (bpt != NULL) {
4005 if (bpt->IsRepeated()) { 3829 if (bpt->IsRepeated()) {
4006 return bpt; 3830 return bpt;
4007 } 3831 }
4008 bpt = bpt->next(); 3832 bpt = bpt->next();
4009 } 3833 }
4010 3834
4011 return NULL; 3835 return NULL;
4012 } 3836 }
4013 3837
4014
4015 void Debugger::PauseDeveloper(const String& msg) { 3838 void Debugger::PauseDeveloper(const String& msg) {
4016 // We ignore this breakpoint when the VM is executing code invoked 3839 // We ignore this breakpoint when the VM is executing code invoked
4017 // by the debugger to evaluate variables values, or when we see a nested 3840 // by the debugger to evaluate variables values, or when we see a nested
4018 // breakpoint or exception event. 3841 // breakpoint or exception event.
4019 if (ignore_breakpoints_ || IsPaused()) { 3842 if (ignore_breakpoints_ || IsPaused()) {
4020 return; 3843 return;
4021 } 3844 }
4022 3845
4023 DebuggerStackTrace* stack_trace = CollectStackTrace(); 3846 DebuggerStackTrace* stack_trace = CollectStackTrace();
4024 ASSERT(stack_trace->Length() > 0); 3847 ASSERT(stack_trace->Length() > 0);
4025 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), 3848 CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(),
4026 CollectAwaiterReturnStackTrace()); 3849 CollectAwaiterReturnStackTrace());
4027 // TODO(johnmccutchan): Send |msg| to Observatory. 3850 // TODO(johnmccutchan): Send |msg| to Observatory.
4028 3851
4029 // We are in the native call to Developer_debugger. the developer 3852 // We are in the native call to Developer_debugger. the developer
4030 // gets a better experience by not seeing this call. To accomplish 3853 // gets a better experience by not seeing this call. To accomplish
4031 // this, we continue execution until the call exits (step out). 3854 // this, we continue execution until the call exits (step out).
4032 SetResumeAction(kStepOut); 3855 SetResumeAction(kStepOut);
4033 HandleSteppingRequest(stack_trace_); 3856 HandleSteppingRequest(stack_trace_);
4034 ClearCachedStackTraces(); 3857 ClearCachedStackTraces();
4035 } 3858 }
4036 3859
4037
4038 void Debugger::Initialize(Isolate* isolate) { 3860 void Debugger::Initialize(Isolate* isolate) {
4039 if (initialized_) { 3861 if (initialized_) {
4040 return; 3862 return;
4041 } 3863 }
4042 isolate_ = isolate; 3864 isolate_ = isolate;
4043 3865
4044 // Use the isolate's control port as the isolate_id for debugging. 3866 // Use the isolate's control port as the isolate_id for debugging.
4045 // This port will be used as a unique ID to represent the isolate in 3867 // This port will be used as a unique ID to represent the isolate in
4046 // the debugger embedder api. 3868 // the debugger embedder api.
4047 isolate_id_ = isolate_->main_port(); 3869 isolate_id_ = isolate_->main_port();
4048 initialized_ = true; 3870 initialized_ = true;
4049 } 3871 }
4050 3872
4051
4052 void Debugger::NotifyIsolateCreated() { 3873 void Debugger::NotifyIsolateCreated() {
4053 if (NeedsIsolateEvents()) { 3874 if (NeedsIsolateEvents()) {
4054 ServiceEvent event(isolate_, ServiceEvent::kIsolateStart); 3875 ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
4055 InvokeEventHandler(&event); 3876 InvokeEventHandler(&event);
4056 } 3877 }
4057 } 3878 }
4058 3879
4059
4060 // Return innermost closure contained in 'function' that contains 3880 // Return innermost closure contained in 'function' that contains
4061 // the given token position. 3881 // the given token position.
4062 RawFunction* Debugger::FindInnermostClosure(const Function& function, 3882 RawFunction* Debugger::FindInnermostClosure(const Function& function,
4063 TokenPosition token_pos) { 3883 TokenPosition token_pos) {
4064 Zone* zone = Thread::Current()->zone(); 3884 Zone* zone = Thread::Current()->zone();
4065 const Script& outer_origin = Script::Handle(zone, function.script()); 3885 const Script& outer_origin = Script::Handle(zone, function.script());
4066 const GrowableObjectArray& closures = GrowableObjectArray::Handle( 3886 const GrowableObjectArray& closures = GrowableObjectArray::Handle(
4067 zone, Isolate::Current()->object_store()->closure_functions()); 3887 zone, Isolate::Current()->object_store()->closure_functions());
4068 const intptr_t num_closures = closures.Length(); 3888 const intptr_t num_closures = closures.Length();
4069 Function& closure = Function::Handle(zone); 3889 Function& closure = Function::Handle(zone);
4070 Function& best_fit = Function::Handle(zone); 3890 Function& best_fit = Function::Handle(zone);
4071 for (intptr_t i = 0; i < num_closures; i++) { 3891 for (intptr_t i = 0; i < num_closures; i++) {
4072 closure ^= closures.At(i); 3892 closure ^= closures.At(i);
4073 if ((function.token_pos() < closure.token_pos()) && 3893 if ((function.token_pos() < closure.token_pos()) &&
4074 (closure.end_token_pos() < function.end_token_pos()) && 3894 (closure.end_token_pos() < function.end_token_pos()) &&
4075 (closure.token_pos() <= token_pos) && 3895 (closure.token_pos() <= token_pos) &&
4076 (token_pos <= closure.end_token_pos()) && 3896 (token_pos <= closure.end_token_pos()) &&
4077 (closure.script() == outer_origin.raw())) { 3897 (closure.script() == outer_origin.raw())) {
4078 SelectBestFit(&best_fit, &closure); 3898 SelectBestFit(&best_fit, &closure);
4079 } 3899 }
4080 } 3900 }
4081 return best_fit.raw(); 3901 return best_fit.raw();
4082 } 3902 }
4083 3903
4084
4085 void Debugger::NotifyCompilation(const Function& func) { 3904 void Debugger::NotifyCompilation(const Function& func) {
4086 if (breakpoint_locations_ == NULL) { 3905 if (breakpoint_locations_ == NULL) {
4087 // Return with minimal overhead if there are no breakpoints. 3906 // Return with minimal overhead if there are no breakpoints.
4088 return; 3907 return;
4089 } 3908 }
4090 if (!func.is_debuggable()) { 3909 if (!func.is_debuggable()) {
4091 // Nothing to do if the function is not debuggable. If there is 3910 // Nothing to do if the function is not debuggable. If there is
4092 // a pending breakpoint in an inner function (that is debuggable), 3911 // a pending breakpoint in an inner function (that is debuggable),
4093 // we'll resolve the breakpoint when the inner function is compiled. 3912 // we'll resolve the breakpoint when the inner function is compiled.
4094 return; 3913 return;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4167 func.IsClosureFunction() ? "closure" : "function", 3986 func.IsClosureFunction() ? "closure" : "function",
4168 String::Handle(func.name()).ToCString()); 3987 String::Handle(func.name()).ToCString());
4169 bpt = bpt->next(); 3988 bpt = bpt->next();
4170 } 3989 }
4171 } 3990 }
4172 MakeCodeBreakpointAt(func, loc); 3991 MakeCodeBreakpointAt(func, loc);
4173 } 3992 }
4174 } 3993 }
4175 } 3994 }
4176 3995
4177
4178 void Debugger::NotifyDoneLoading() { 3996 void Debugger::NotifyDoneLoading() {
4179 if (latent_locations_ == NULL) { 3997 if (latent_locations_ == NULL) {
4180 // Common, fast path. 3998 // Common, fast path.
4181 return; 3999 return;
4182 } 4000 }
4183 Zone* zone = Thread::Current()->zone(); 4001 Zone* zone = Thread::Current()->zone();
4184 Library& lib = Library::Handle(zone); 4002 Library& lib = Library::Handle(zone);
4185 Script& script = Script::Handle(zone); 4003 Script& script = Script::Handle(zone);
4186 String& url = String::Handle(zone); 4004 String& url = String::Handle(zone);
4187 BreakpointLocation* loc = latent_locations_; 4005 BreakpointLocation* loc = latent_locations_;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4283 "%" Pd " with url '%s'\n", 4101 "%" Pd " with url '%s'\n",
4284 bpt->id(), url.ToCString()); 4102 bpt->id(), url.ToCString());
4285 bpt = bpt->next(); 4103 bpt = bpt->next();
4286 } 4104 }
4287 } 4105 }
4288 loc = loc->next(); 4106 loc = loc->next();
4289 } 4107 }
4290 } 4108 }
4291 } 4109 }
4292 4110
4293
4294 // TODO(hausner): Could potentially make this faster by checking 4111 // TODO(hausner): Could potentially make this faster by checking
4295 // whether the call target at pc is a debugger stub. 4112 // whether the call target at pc is a debugger stub.
4296 bool Debugger::HasActiveBreakpoint(uword pc) { 4113 bool Debugger::HasActiveBreakpoint(uword pc) {
4297 CodeBreakpoint* bpt = GetCodeBreakpoint(pc); 4114 CodeBreakpoint* bpt = GetCodeBreakpoint(pc);
4298 return (bpt != NULL) && (bpt->IsEnabled()); 4115 return (bpt != NULL) && (bpt->IsEnabled());
4299 } 4116 }
4300 4117
4301
4302 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) { 4118 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) {
4303 CodeBreakpoint* bpt = code_breakpoints_; 4119 CodeBreakpoint* bpt = code_breakpoints_;
4304 while (bpt != NULL) { 4120 while (bpt != NULL) {
4305 if (bpt->pc() == breakpoint_address) { 4121 if (bpt->pc() == breakpoint_address) {
4306 return bpt; 4122 return bpt;
4307 } 4123 }
4308 bpt = bpt->next(); 4124 bpt = bpt->next();
4309 } 4125 }
4310 return NULL; 4126 return NULL;
4311 } 4127 }
4312 4128
4313
4314 RawCode* Debugger::GetPatchedStubAddress(uword breakpoint_address) { 4129 RawCode* Debugger::GetPatchedStubAddress(uword breakpoint_address) {
4315 CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address); 4130 CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address);
4316 if (bpt != NULL) { 4131 if (bpt != NULL) {
4317 return bpt->OrigStubAddress(); 4132 return bpt->OrigStubAddress();
4318 } 4133 }
4319 UNREACHABLE(); 4134 UNREACHABLE();
4320 return Code::null(); 4135 return Code::null();
4321 } 4136 }
4322 4137
4323
4324 // Remove and delete the source breakpoint bpt and its associated 4138 // Remove and delete the source breakpoint bpt and its associated
4325 // code breakpoints. 4139 // code breakpoints.
4326 void Debugger::RemoveBreakpoint(intptr_t bp_id) { 4140 void Debugger::RemoveBreakpoint(intptr_t bp_id) {
4327 if (RemoveBreakpointFromTheList(bp_id, &breakpoint_locations_)) { 4141 if (RemoveBreakpointFromTheList(bp_id, &breakpoint_locations_)) {
4328 return; 4142 return;
4329 } 4143 }
4330 RemoveBreakpointFromTheList(bp_id, &latent_locations_); 4144 RemoveBreakpointFromTheList(bp_id, &latent_locations_);
4331 } 4145 }
4332 4146
4333
4334 // Remove and delete the source breakpoint bpt and its associated 4147 // Remove and delete the source breakpoint bpt and its associated
4335 // code breakpoints. Returns true, if breakpoint was found and removed, 4148 // code breakpoints. Returns true, if breakpoint was found and removed,
4336 // returns false, if breakpoint was not found. 4149 // returns false, if breakpoint was not found.
4337 bool Debugger::RemoveBreakpointFromTheList(intptr_t bp_id, 4150 bool Debugger::RemoveBreakpointFromTheList(intptr_t bp_id,
4338 BreakpointLocation** list) { 4151 BreakpointLocation** list) {
4339 BreakpointLocation* prev_loc = NULL; 4152 BreakpointLocation* prev_loc = NULL;
4340 BreakpointLocation* curr_loc = *list; 4153 BreakpointLocation* curr_loc = *list;
4341 while (curr_loc != NULL) { 4154 while (curr_loc != NULL) {
4342 Breakpoint* prev_bpt = NULL; 4155 Breakpoint* prev_bpt = NULL;
4343 Breakpoint* curr_bpt = curr_loc->breakpoints(); 4156 Breakpoint* curr_bpt = curr_loc->breakpoints();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4393 prev_bpt = curr_bpt; 4206 prev_bpt = curr_bpt;
4394 curr_bpt = curr_bpt->next(); 4207 curr_bpt = curr_bpt->next();
4395 } 4208 }
4396 prev_loc = curr_loc; 4209 prev_loc = curr_loc;
4397 curr_loc = curr_loc->next(); 4210 curr_loc = curr_loc->next();
4398 } 4211 }
4399 // breakpoint with bp_id does not exist, nothing to do. 4212 // breakpoint with bp_id does not exist, nothing to do.
4400 return false; 4213 return false;
4401 } 4214 }
4402 4215
4403
4404 // Unlink code breakpoints from the given breakpoint location. 4216 // Unlink code breakpoints from the given breakpoint location.
4405 // They will later be deleted when control returns from the pause event 4217 // They will later be deleted when control returns from the pause event
4406 // callback. Also, disable the breakpoint so it no longer fires if it 4218 // callback. Also, disable the breakpoint so it no longer fires if it
4407 // should be hit before it gets deleted. 4219 // should be hit before it gets deleted.
4408 void Debugger::UnlinkCodeBreakpoints(BreakpointLocation* bpt_location) { 4220 void Debugger::UnlinkCodeBreakpoints(BreakpointLocation* bpt_location) {
4409 ASSERT(bpt_location != NULL); 4221 ASSERT(bpt_location != NULL);
4410 CodeBreakpoint* curr_bpt = code_breakpoints_; 4222 CodeBreakpoint* curr_bpt = code_breakpoints_;
4411 while (curr_bpt != NULL) { 4223 while (curr_bpt != NULL) {
4412 if (curr_bpt->bpt_location() == bpt_location) { 4224 if (curr_bpt->bpt_location() == bpt_location) {
4413 curr_bpt->Disable(); 4225 curr_bpt->Disable();
4414 curr_bpt->set_bpt_location(NULL); 4226 curr_bpt->set_bpt_location(NULL);
4415 needs_breakpoint_cleanup_ = true; 4227 needs_breakpoint_cleanup_ = true;
4416 } 4228 }
4417 curr_bpt = curr_bpt->next(); 4229 curr_bpt = curr_bpt->next();
4418 } 4230 }
4419 } 4231 }
4420 4232
4421
4422 // Remove and delete unlinked code breakpoints, i.e. breakpoints that 4233 // Remove and delete unlinked code breakpoints, i.e. breakpoints that
4423 // are not associated with a breakpoint location. 4234 // are not associated with a breakpoint location.
4424 void Debugger::RemoveUnlinkedCodeBreakpoints() { 4235 void Debugger::RemoveUnlinkedCodeBreakpoints() {
4425 CodeBreakpoint* prev_bpt = NULL; 4236 CodeBreakpoint* prev_bpt = NULL;
4426 CodeBreakpoint* curr_bpt = code_breakpoints_; 4237 CodeBreakpoint* curr_bpt = code_breakpoints_;
4427 while (curr_bpt != NULL) { 4238 while (curr_bpt != NULL) {
4428 if (curr_bpt->bpt_location() == NULL) { 4239 if (curr_bpt->bpt_location() == NULL) {
4429 if (prev_bpt == NULL) { 4240 if (prev_bpt == NULL) {
4430 code_breakpoints_ = code_breakpoints_->next(); 4241 code_breakpoints_ = code_breakpoints_->next();
4431 } else { 4242 } else {
4432 prev_bpt->set_next(curr_bpt->next()); 4243 prev_bpt->set_next(curr_bpt->next());
4433 } 4244 }
4434 CodeBreakpoint* temp_bpt = curr_bpt; 4245 CodeBreakpoint* temp_bpt = curr_bpt;
4435 curr_bpt = curr_bpt->next(); 4246 curr_bpt = curr_bpt->next();
4436 temp_bpt->Disable(); 4247 temp_bpt->Disable();
4437 delete temp_bpt; 4248 delete temp_bpt;
4438 } else { 4249 } else {
4439 prev_bpt = curr_bpt; 4250 prev_bpt = curr_bpt;
4440 curr_bpt = curr_bpt->next(); 4251 curr_bpt = curr_bpt->next();
4441 } 4252 }
4442 } 4253 }
4443 needs_breakpoint_cleanup_ = false; 4254 needs_breakpoint_cleanup_ = false;
4444 } 4255 }
4445 4256
4446
4447 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script, 4257 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script,
4448 TokenPosition token_pos, 4258 TokenPosition token_pos,
4449 intptr_t requested_column) { 4259 intptr_t requested_column) {
4450 BreakpointLocation* bpt = breakpoint_locations_; 4260 BreakpointLocation* bpt = breakpoint_locations_;
4451 while (bpt != NULL) { 4261 while (bpt != NULL) {
4452 if ((bpt->script_ == script.raw()) && (bpt->token_pos_ == token_pos) && 4262 if ((bpt->script_ == script.raw()) && (bpt->token_pos_ == token_pos) &&
4453 (bpt->requested_column_number_ == requested_column)) { 4263 (bpt->requested_column_number_ == requested_column)) {
4454 return bpt; 4264 return bpt;
4455 } 4265 }
4456 bpt = bpt->next(); 4266 bpt = bpt->next();
4457 } 4267 }
4458 return NULL; 4268 return NULL;
4459 } 4269 }
4460 4270
4461
4462 Breakpoint* Debugger::GetBreakpointById(intptr_t id) { 4271 Breakpoint* Debugger::GetBreakpointById(intptr_t id) {
4463 Breakpoint* bpt = GetBreakpointByIdInTheList(id, breakpoint_locations_); 4272 Breakpoint* bpt = GetBreakpointByIdInTheList(id, breakpoint_locations_);
4464 if (bpt != NULL) { 4273 if (bpt != NULL) {
4465 return bpt; 4274 return bpt;
4466 } 4275 }
4467 return GetBreakpointByIdInTheList(id, latent_locations_); 4276 return GetBreakpointByIdInTheList(id, latent_locations_);
4468 } 4277 }
4469 4278
4470
4471 Breakpoint* Debugger::GetBreakpointByIdInTheList(intptr_t id, 4279 Breakpoint* Debugger::GetBreakpointByIdInTheList(intptr_t id,
4472 BreakpointLocation* list) { 4280 BreakpointLocation* list) {
4473 BreakpointLocation* loc = list; 4281 BreakpointLocation* loc = list;
4474 while (loc != NULL) { 4282 while (loc != NULL) {
4475 Breakpoint* bpt = loc->breakpoints(); 4283 Breakpoint* bpt = loc->breakpoints();
4476 while (bpt != NULL) { 4284 while (bpt != NULL) {
4477 if (bpt->id() == id) { 4285 if (bpt->id() == id) {
4478 return bpt; 4286 return bpt;
4479 } 4287 }
4480 bpt = bpt->next(); 4288 bpt = bpt->next();
4481 } 4289 }
4482 loc = loc->next(); 4290 loc = loc->next();
4483 } 4291 }
4484 return NULL; 4292 return NULL;
4485 } 4293 }
4486 4294
4487
4488 void Debugger::MaybeAsyncStepInto(const Closure& async_op) { 4295 void Debugger::MaybeAsyncStepInto(const Closure& async_op) {
4489 if (FLAG_async_debugger && IsSingleStepping()) { 4296 if (FLAG_async_debugger && IsSingleStepping()) {
4490 // We are single stepping, set a breakpoint on the closure activation 4297 // We are single stepping, set a breakpoint on the closure activation
4491 // and resume execution so we can hit the breakpoint. 4298 // and resume execution so we can hit the breakpoint.
4492 AsyncStepInto(async_op); 4299 AsyncStepInto(async_op);
4493 } 4300 }
4494 } 4301 }
4495 4302
4496
4497 void Debugger::AsyncStepInto(const Closure& async_op) { 4303 void Debugger::AsyncStepInto(const Closure& async_op) {
4498 SetBreakpointAtActivation(async_op, true); 4304 SetBreakpointAtActivation(async_op, true);
4499 Continue(); 4305 Continue();
4500 } 4306 }
4501 4307
4502
4503 void Debugger::Continue() { 4308 void Debugger::Continue() {
4504 SetResumeAction(kContinue); 4309 SetResumeAction(kContinue);
4505 stepping_fp_ = 0; 4310 stepping_fp_ = 0;
4506 async_stepping_fp_ = 0; 4311 async_stepping_fp_ = 0;
4507 isolate_->set_single_step(false); 4312 isolate_->set_single_step(false);
4508 } 4313 }
4509 4314
4510
4511 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, 4315 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url,
4512 intptr_t line, 4316 intptr_t line,
4513 intptr_t column) { 4317 intptr_t column) {
4514 BreakpointLocation* bpt = latent_locations_; 4318 BreakpointLocation* bpt = latent_locations_;
4515 String& bpt_url = String::Handle(); 4319 String& bpt_url = String::Handle();
4516 while (bpt != NULL) { 4320 while (bpt != NULL) {
4517 bpt_url = bpt->url(); 4321 bpt_url = bpt->url();
4518 if (bpt_url.Equals(url) && (bpt->requested_line_number() == line) && 4322 if (bpt_url.Equals(url) && (bpt->requested_line_number() == line) &&
4519 (bpt->requested_column_number() == column)) { 4323 (bpt->requested_column_number() == column)) {
4520 return bpt; 4324 return bpt;
4521 } 4325 }
4522 bpt = bpt->next(); 4326 bpt = bpt->next();
4523 } 4327 }
4524 // No breakpoint for this location requested. Allocate new one. 4328 // No breakpoint for this location requested. Allocate new one.
4525 bpt = new BreakpointLocation(url, line, column); 4329 bpt = new BreakpointLocation(url, line, column);
4526 bpt->set_next(latent_locations_); 4330 bpt->set_next(latent_locations_);
4527 latent_locations_ = bpt; 4331 latent_locations_ = bpt;
4528 return bpt; 4332 return bpt;
4529 } 4333 }
4530 4334
4531
4532 void Debugger::RegisterBreakpointLocation(BreakpointLocation* bpt) { 4335 void Debugger::RegisterBreakpointLocation(BreakpointLocation* bpt) {
4533 ASSERT(bpt->next() == NULL); 4336 ASSERT(bpt->next() == NULL);
4534 bpt->set_next(breakpoint_locations_); 4337 bpt->set_next(breakpoint_locations_);
4535 breakpoint_locations_ = bpt; 4338 breakpoint_locations_ = bpt;
4536 } 4339 }
4537 4340
4538
4539 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 4341 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
4540 ASSERT(bpt->next() == NULL); 4342 ASSERT(bpt->next() == NULL);
4541 bpt->set_next(code_breakpoints_); 4343 bpt->set_next(code_breakpoints_);
4542 code_breakpoints_ = bpt; 4344 code_breakpoints_ = bpt;
4543 } 4345 }
4544 4346
4545 #endif // !PRODUCT 4347 #endif // !PRODUCT
4546 4348
4547 } // namespace dart 4349 } // 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