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

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

Issue 1146173003: Per-closure breakpoints; restructure breakpoint implementation to keep a list of conditions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_DEBUGGER_H_ 5 #ifndef VM_DEBUGGER_H_
6 #define VM_DEBUGGER_H_ 6 #define VM_DEBUGGER_H_
7 7
8 #include "include/dart_debugger_api.h" 8 #include "include/dart_debugger_api.h"
9 9
10 #include "vm/object.h" 10 #include "vm/object.h"
11 #include "vm/port.h" 11 #include "vm/port.h"
12 12
13 namespace dart { 13 namespace dart {
14 14
15 class CodeBreakpoint; 15 class CodeBreakpoint;
16 class Isolate; 16 class Isolate;
17 class JSONArray; 17 class JSONArray;
18 class JSONStream; 18 class JSONStream;
19 class ObjectPointerVisitor; 19 class ObjectPointerVisitor;
20 class RemoteObjectCache; 20 class RemoteObjectCache;
21 class SourceBreakpoint; 21 class SourceBreakpoint;
22 class StackFrame; 22 class StackFrame;
23 23
24 // SourceBreakpoint represents a user-specified breakpoint location in 24 // A user-defined breakpoint, which either fires once, for a particular closure,
25 // Dart source. There may be more than one CodeBreakpoint object per 25 // or always. The API's notion of a breakpoint corresponds to this object.
26 // SourceBreakpoint. 26 class BreakpointCondition {
hausner 2015/05/21 18:23:55 I am struggling with the name. Maybe we just call
rmacnak 2015/05/21 21:59:35 Done.
27 public:
28 BreakpointCondition(intptr_t id, SourceBreakpoint* src_bpt)
29 : id_(id),
30 kind_(BreakpointCondition::kNone),
31 next_(NULL),
32 closure_(Instance::null()),
33 src_bpt_(src_bpt) {}
34
35 intptr_t id() const { return id_; }
36 BreakpointCondition* next() const { return next_; }
37 void set_next(BreakpointCondition* n) { next_ = n; }
38
39 SourceBreakpoint* src_bpt() const { return src_bpt_; }
40 void set_src_bpt(SourceBreakpoint* new_src_bpt);
41
42 bool IsRepeated() const { return kind_ == kRepeated; }
43 bool IsSingleShot() const { return kind_ == kSingleShot; }
44 bool IsPerClosure() const { return kind_ == kPerClosure; }
45 RawInstance* closure() const { return closure_; }
46
47 void SetIsRepeated() {
48 ASSERT(kind_ == kNone);
49 kind_ = kRepeated;
50 }
51
52 void SetIsSingleShot() {
53 ASSERT(kind_ == kNone);
54 kind_ = kSingleShot;
55 }
56
57 void SetIsPerClosure(const Instance& closure) {
58 ASSERT(kind_ == kNone);
59 kind_ = kPerClosure;
60 closure_ = closure.raw();
61 }
62
63 void PrintJSON(JSONStream* stream);
64
65 private:
66 void VisitObjectPointers(ObjectPointerVisitor* visitor);
67
68 enum ConditionKind {
69 kNone,
70 kRepeated,
hausner 2015/05/21 18:23:55 What if you want to set a one-shopt breakpoint in
71 kSingleShot,
72 kPerClosure,
73 };
74
75 intptr_t id_;
76 ConditionKind kind_;
77 BreakpointCondition* next_;
78 RawInstance* closure_;
79 SourceBreakpoint* src_bpt_;
80
81 friend class SourceBreakpoint;
82 DISALLOW_COPY_AND_ASSIGN(BreakpointCondition);
83 };
84
85
86 // SourceBreakpoint represents a collection of breakpoint conditions at the same
87 // token position in Dart source. There may be more than one CodeBreakpoint
88 // object per SourceBreakpoint.
27 // An unresolved breakpoint is one where the underlying code has not 89 // An unresolved breakpoint is one where the underlying code has not
28 // been compiled yet. Since the code has not been compiled, we don't know 90 // been compiled yet. Since the code has not been compiled, we don't know
29 // the definitive source location yet. The requested source location may 91 // the definitive source location yet. The requested source location may
30 // change when the underlying code gets compiled. 92 // change when the underlying code gets compiled.
31 // A latent breakpoint represents a breakpoint location in Dart source 93 // A latent breakpoint represents a breakpoint location in Dart source
32 // that is not loaded in the VM when the breakpoint is requested. 94 // that is not loaded in the VM when the breakpoint is requested.
33 // When a script with matching url is loaded, a latent breakpoint 95 // When a script with matching url is loaded, a latent breakpoint
34 // becomes an unresolved breakpoint. 96 // becomes an unresolved breakpoint.
35 class SourceBreakpoint { 97 class SourceBreakpoint {
36 public: 98 public:
37 // Create a new unresolved breakpoint. 99 // Create a new unresolved breakpoint.
38 SourceBreakpoint(intptr_t id, 100 SourceBreakpoint(const Script& script,
39 const Script& script,
40 intptr_t token_pos, 101 intptr_t token_pos,
41 intptr_t end_token_pos); 102 intptr_t end_token_pos);
42 // Create a new latent breakpoint. 103 // Create a new latent breakpoint.
43 SourceBreakpoint(intptr_t id, 104 SourceBreakpoint(const String& url,
44 const String& url,
45 intptr_t line_number); 105 intptr_t line_number);
46 106
107 ~SourceBreakpoint() {
108 BreakpointCondition* cond = conditions();
hausner 2015/05/21 18:23:55 Does the body for the destructor need to be inline
rmacnak 2015/05/21 21:59:35 No, moved to cc.
109 while (cond != NULL) {
110 BreakpointCondition* temp = cond;
111 cond = cond->next();
112 delete temp;
113 }
114 }
115
47 RawFunction* function() const { return function_; } 116 RawFunction* function() const { return function_; }
48 intptr_t token_pos() const { return token_pos_; } 117 intptr_t token_pos() const { return token_pos_; }
49 intptr_t end_token_pos() const { return end_token_pos_; } 118 intptr_t end_token_pos() const { return end_token_pos_; }
50 intptr_t id() const { return id_; }
51 119
52 RawScript* script() const { return script_; } 120 RawScript* script() const { return script_; }
53 RawString* url() const { return url_; } 121 RawString* url() const { return url_; }
54 intptr_t LineNumber(); 122 intptr_t LineNumber();
55 123
56 void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos); 124 void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos);
57 125
126 BreakpointCondition* AddRepeated(Debugger* dbg);
127 BreakpointCondition* AddSingleShot(Debugger* dbg);
128 BreakpointCondition* AddPerClosure(Debugger* dbg, const Instance& closure);
129
58 void Enable(); 130 void Enable();
hausner 2015/05/21 18:23:55 The enabled/disabled property should be part of th
rmacnak 2015/05/21 21:59:35 Actually, no one calls Disable(), so deleted this.
59 void Disable(); 131 void Disable();
60 bool IsEnabled() const { return is_enabled_; } 132 bool IsEnabled() const { return is_enabled_; }
61 bool IsResolved() const { return is_resolved_; } 133 bool IsResolved() const { return is_resolved_; }
62 bool IsLatent() const { return token_pos_ < 0; } 134 bool IsLatent() const { return token_pos_ < 0; }
63 135
64 bool IsOneShot() const { return is_one_shot_; }
65 void SetIsOneShot() { is_one_shot_ = true; }
66
67 void PrintJSON(JSONStream* stream);
68
69 private: 136 private:
70 void VisitObjectPointers(ObjectPointerVisitor* visitor); 137 void VisitObjectPointers(ObjectPointerVisitor* visitor);
71 138
72 void SetResolved(const Function& func, intptr_t token_pos); 139 void SetResolved(const Function& func, intptr_t token_pos);
140
141 SourceBreakpoint* next() const { return this->next_; }
73 void set_next(SourceBreakpoint* value) { next_ = value; } 142 void set_next(SourceBreakpoint* value) { next_ = value; }
74 SourceBreakpoint* next() const { return this->next_; }
75 143
76 const intptr_t id_; 144 BreakpointCondition* conditions() const { return this->conditions_; }
145 void set_conditions(BreakpointCondition* c) { this->conditions_ = c; }
146
77 RawScript* script_; 147 RawScript* script_;
78 RawString* url_; 148 RawString* url_;
79 intptr_t token_pos_; 149 intptr_t token_pos_;
80 intptr_t end_token_pos_; 150 intptr_t end_token_pos_;
81 bool is_resolved_; 151 bool is_resolved_;
82 bool is_enabled_; 152 bool is_enabled_;
83 bool is_one_shot_;
84 SourceBreakpoint* next_; 153 SourceBreakpoint* next_;
154 BreakpointCondition* conditions_;
85 155
86 // Valid for resolved breakpoints: 156 // Valid for resolved breakpoints:
87 RawFunction* function_; 157 RawFunction* function_;
88 intptr_t line_number_; 158 intptr_t line_number_;
89 159
90 friend class Debugger; 160 friend class Debugger;
91 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint); 161 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint);
92 }; 162 };
93 163
94 164
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 257
188 intptr_t NumLocalVariables(); 258 intptr_t NumLocalVariables();
189 259
190 void VariableAt(intptr_t i, 260 void VariableAt(intptr_t i,
191 String* name, 261 String* name,
192 intptr_t* token_pos, 262 intptr_t* token_pos,
193 intptr_t* end_pos, 263 intptr_t* end_pos,
194 Object* value); 264 Object* value);
195 265
196 RawArray* GetLocalVariables(); 266 RawArray* GetLocalVariables();
267 RawObject* GetParameter(intptr_t index);
268 RawObject* GetClosure();
197 RawObject* GetReceiver(); 269 RawObject* GetReceiver();
198 270
199 const Context& GetSavedCurrentContext(); 271 const Context& GetSavedCurrentContext();
200 272
201 RawObject* Evaluate(const String& expr); 273 RawObject* Evaluate(const String& expr);
202 274
203 // Print the activation frame into |jsobj|. if |full| is false, script 275 // Print the activation frame into |jsobj|. if |full| is false, script
204 // and local variable objects are only references. if |full| is true, 276 // and local variable objects are only references. if |full| is true,
205 // the complete script, function, and, local variable objects are included. 277 // the complete script, function, and, local variable objects are included.
206 void PrintToJSONObject(JSONObject* jsobj, bool full = false); 278 void PrintToJSONObject(JSONObject* jsobj, bool full = false);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 380
309 ActivationFrame* top_frame() const { 381 ActivationFrame* top_frame() const {
310 ASSERT(IsPauseEvent()); 382 ASSERT(IsPauseEvent());
311 return top_frame_; 383 return top_frame_;
312 } 384 }
313 void set_top_frame(ActivationFrame* frame) { 385 void set_top_frame(ActivationFrame* frame) {
314 ASSERT(IsPauseEvent()); 386 ASSERT(IsPauseEvent());
315 top_frame_ = frame; 387 top_frame_ = frame;
316 } 388 }
317 389
318 SourceBreakpoint* breakpoint() const { 390 BreakpointCondition* breakpoint() const {
319 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); 391 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
320 return breakpoint_; 392 return breakpoint_;
321 } 393 }
322 void set_breakpoint(SourceBreakpoint* bpt) { 394 void set_breakpoint(BreakpointCondition* bpt) {
323 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); 395 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved);
324 breakpoint_ = bpt; 396 breakpoint_ = bpt;
325 } 397 }
326 398
327 const Object* exception() const { 399 const Object* exception() const {
328 ASSERT(type_ == kExceptionThrown); 400 ASSERT(type_ == kExceptionThrown);
329 return exception_; 401 return exception_;
330 } 402 }
331 void set_exception(const Object* exception) { 403 void set_exception(const Object* exception) {
332 ASSERT(type_ == kExceptionThrown); 404 ASSERT(type_ == kExceptionThrown);
333 exception_ = exception; 405 exception_ = exception;
334 } 406 }
335 407
336 Dart_Port isolate_id() const { 408 Dart_Port isolate_id() const {
337 return isolate_->main_port(); 409 return isolate_->main_port();
338 } 410 }
339 411
340 private: 412 private:
341 Isolate* isolate_; 413 Isolate* isolate_;
342 EventType type_; 414 EventType type_;
343 ActivationFrame* top_frame_; 415 ActivationFrame* top_frame_;
344 SourceBreakpoint* breakpoint_; 416 BreakpointCondition* breakpoint_;
345 const Object* exception_; 417 const Object* exception_;
346 }; 418 };
347 419
348 420
349 class Debugger { 421 class Debugger {
350 public: 422 public:
351 typedef void EventHandler(DebuggerEvent* event); 423 typedef void EventHandler(DebuggerEvent* event);
352 424
353 Debugger(); 425 Debugger();
354 ~Debugger(); 426 ~Debugger();
355 427
356 void Initialize(Isolate* isolate); 428 void Initialize(Isolate* isolate);
357 void NotifyIsolateCreated(); 429 void NotifyIsolateCreated();
358 void Shutdown(); 430 void Shutdown();
359 431
360 void NotifyCompilation(const Function& func); 432 void NotifyCompilation(const Function& func);
361 void NotifyDoneLoading(); 433 void NotifyDoneLoading();
362 434
363 RawFunction* ResolveFunction(const Library& library, 435 RawFunction* ResolveFunction(const Library& library,
364 const String& class_name, 436 const String& class_name,
365 const String& function_name); 437 const String& function_name);
366 438
367 // Set breakpoint at closest location to function entry. 439 // Set breakpoint at closest location to function entry.
368 SourceBreakpoint* SetBreakpointAtEntry(const Function& target_function); 440 BreakpointCondition* SetBreakpointAtEntry(const Function& target_function,
441 bool single_shot);
442 BreakpointCondition* SetBreakpointAtActivation(const Instance& closure);
369 443
370 // TODO(turnidge): script_url may no longer be specific enough. 444 // TODO(turnidge): script_url may no longer be specific enough.
371 SourceBreakpoint* SetBreakpointAtLine(const String& script_url, 445 BreakpointCondition* SetBreakpointAtLine(const String& script_url,
372 intptr_t line_number); 446 intptr_t line_number);
373 RawError* OneTimeBreakAtEntry(const Function& target_function); 447 RawError* OneTimeBreakAtEntry(const Function& target_function);
374 448
449 SourceBreakpoint* SourceBreakpointAtLine(const String& script_url,
450 intptr_t line_number);
451
452
375 void RemoveBreakpoint(intptr_t bp_id); 453 void RemoveBreakpoint(intptr_t bp_id);
376 SourceBreakpoint* GetBreakpointById(intptr_t id); 454 BreakpointCondition* GetBreakpointById(intptr_t id);
377 455
378 void SetStepOver(); 456 void SetStepOver();
379 void SetSingleStep(); 457 void SetSingleStep();
380 void SetStepOut(); 458 void SetStepOut();
381 bool IsStepping() const { return resume_action_ != kContinue; } 459 bool IsStepping() const { return resume_action_ != kContinue; }
382 460
383 bool IsPaused() const { return pause_event_ != NULL; } 461 bool IsPaused() const { return pause_event_ != NULL; }
384 462
385 // Indicates why the debugger is currently paused. If the debugger 463 // Indicates why the debugger is currently paused. If the debugger
386 // is not paused, this returns NULL. Note that the debugger can be 464 // is not paused, this returns NULL. Note that the debugger can be
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 static ActivationFrame* CollectDartFrame(Isolate* isolate, 575 static ActivationFrame* CollectDartFrame(Isolate* isolate,
498 uword pc, 576 uword pc,
499 StackFrame* frame, 577 StackFrame* frame,
500 const Code& code, 578 const Code& code,
501 const Array& deopt_frame, 579 const Array& deopt_frame,
502 intptr_t deopt_frame_offset); 580 intptr_t deopt_frame_offset);
503 static RawArray* DeoptimizeToArray(Isolate* isolate, 581 static RawArray* DeoptimizeToArray(Isolate* isolate,
504 StackFrame* frame, 582 StackFrame* frame,
505 const Code& code); 583 const Code& code);
506 static DebuggerStackTrace* CollectStackTrace(); 584 static DebuggerStackTrace* CollectStackTrace();
507 void SignalBpResolved(SourceBreakpoint *bpt); 585 void SignalBpResolved(BreakpointCondition *bpt);
508 void SignalPausedEvent(ActivationFrame* top_frame, 586 void SignalPausedEvent(ActivationFrame* top_frame,
509 SourceBreakpoint* bpt); 587 BreakpointCondition* bpt);
510 588
511 intptr_t nextId() { return next_id_++; } 589 intptr_t nextId() { return next_id_++; }
512 590
513 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, 591 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
514 const Instance& exc); 592 const Instance& exc);
515 593
516 void CollectLibraryFields(const GrowableObjectArray& field_list, 594 void CollectLibraryFields(const GrowableObjectArray& field_list,
517 const Library& lib, 595 const Library& lib,
518 const String& prefix, 596 const String& prefix,
519 bool include_private_fields); 597 bool include_private_fields);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 644
567 friend class Isolate; 645 friend class Isolate;
568 friend class SourceBreakpoint; 646 friend class SourceBreakpoint;
569 DISALLOW_COPY_AND_ASSIGN(Debugger); 647 DISALLOW_COPY_AND_ASSIGN(Debugger);
570 }; 648 };
571 649
572 650
573 } // namespace dart 651 } // namespace dart
574 652
575 #endif // VM_DEBUGGER_H_ 653 #endif // VM_DEBUGGER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698