OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_DEBUG_H_ | 5 #ifndef V8_DEBUG_H_ |
6 #define V8_DEBUG_H_ | 6 #define V8_DEBUG_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/assembler.h" | 10 #include "src/assembler.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 | 59 |
60 | 60 |
61 // The different types of breakpoint position alignments. | 61 // The different types of breakpoint position alignments. |
62 // Must match Debug.BreakPositionAlignment in debug-debugger.js | 62 // Must match Debug.BreakPositionAlignment in debug-debugger.js |
63 enum BreakPositionAlignment { | 63 enum BreakPositionAlignment { |
64 STATEMENT_ALIGNED = 0, | 64 STATEMENT_ALIGNED = 0, |
65 BREAK_POSITION_ALIGNED = 1 | 65 BREAK_POSITION_ALIGNED = 1 |
66 }; | 66 }; |
67 | 67 |
68 | 68 |
69 // Class for iterating through the break points in a function and changing | 69 class BreakLocation { |
70 // them. | |
71 class BreakLocationIterator { | |
72 public: | 70 public: |
73 explicit BreakLocationIterator(Handle<DebugInfo> debug_info, | 71 // Find the break point at the supplied address, or the closest one before |
74 BreakLocatorType type); | 72 // the address. |
75 virtual ~BreakLocationIterator(); | 73 static BreakLocation FromAddress(Handle<DebugInfo> debug_info, |
| 74 BreakLocatorType type, Address pc); |
76 | 75 |
77 void Next(); | 76 static void FromAddressSameStatement(Handle<DebugInfo> debug_info, |
78 void Next(int count); | 77 BreakLocatorType type, Address pc, |
79 void FindBreakLocationFromAddress(Address pc); | 78 List<BreakLocation>* result_out); |
80 void FindBreakLocationFromPosition(int position, | 79 |
81 BreakPositionAlignment alignment); | 80 static BreakLocation FromPosition(Handle<DebugInfo> debug_info, |
82 void Reset(); | 81 BreakLocatorType type, int position, |
83 bool Done() const; | 82 BreakPositionAlignment alignment); |
| 83 |
| 84 bool IsDebugBreak() const; |
| 85 inline bool IsExit() const { return RelocInfo::IsJSReturn(rmode_); } |
| 86 inline bool IsConstructCall() const { |
| 87 return RelocInfo::IsConstructCall(rmode_); |
| 88 } |
| 89 inline bool IsCodeTarget() const { return RelocInfo::IsCodeTarget(rmode_); } |
| 90 |
| 91 Handle<Code> CodeTarget() const; |
| 92 Handle<Code> OriginalCodeTarget() const; |
| 93 |
| 94 bool IsStepInLocation() const; |
| 95 inline bool HasBreakPoint() const { |
| 96 return debug_info_->HasBreakPoint(pc_offset_); |
| 97 } |
| 98 |
| 99 Handle<Object> BreakPointObjects() const; |
| 100 |
84 void SetBreakPoint(Handle<Object> break_point_object); | 101 void SetBreakPoint(Handle<Object> break_point_object); |
85 void ClearBreakPoint(Handle<Object> break_point_object); | 102 void ClearBreakPoint(Handle<Object> break_point_object); |
| 103 |
86 void SetOneShot(); | 104 void SetOneShot(); |
87 void ClearOneShot(); | 105 void ClearOneShot(); |
88 bool IsStepInLocation(Isolate* isolate); | |
89 bool IsExit() const; | |
90 bool HasBreakPoint(); | |
91 bool IsDebugBreak(); | |
92 Object* BreakPointObjects(); | |
93 void ClearAllDebugBreak(); | |
94 | 106 |
95 | 107 inline RelocInfo rinfo() const { |
96 inline int code_position() { | 108 return RelocInfo(pc(), rmode(), data_, code()); |
97 return static_cast<int>(pc() - debug_info_->code()->entry()); | |
98 } | |
99 inline int break_point() { return break_point_; } | |
100 inline int position() { return position_; } | |
101 inline int statement_position() { return statement_position_; } | |
102 inline Address pc() { return reloc_iterator_->rinfo()->pc(); } | |
103 inline Code* code() { return debug_info_->code(); } | |
104 inline RelocInfo* rinfo() { return reloc_iterator_->rinfo(); } | |
105 inline RelocInfo::Mode rmode() const { | |
106 return reloc_iterator_->rinfo()->rmode(); | |
107 } | |
108 inline RelocInfo* original_rinfo() { | |
109 return reloc_iterator_original_->rinfo(); | |
110 } | |
111 inline RelocInfo::Mode original_rmode() const { | |
112 return reloc_iterator_original_->rinfo()->rmode(); | |
113 } | 109 } |
114 | 110 |
115 bool IsDebuggerStatement(); | 111 inline RelocInfo original_rinfo() const { |
| 112 return RelocInfo(original_pc(), original_rmode(), original_data_, |
| 113 original_code()); |
| 114 } |
116 | 115 |
117 protected: | 116 inline int position() const { return position_; } |
118 bool RinfoDone() const; | 117 inline int statement_position() const { return statement_position_; } |
119 void RinfoNext(); | |
120 | 118 |
121 BreakLocatorType type_; | 119 inline Address pc() const { return code()->entry() + pc_offset_; } |
122 int break_point_; | 120 inline Address original_pc() const { |
| 121 return original_code()->entry() + original_pc_offset_; |
| 122 } |
| 123 |
| 124 inline RelocInfo::Mode rmode() const { return rmode_; } |
| 125 inline RelocInfo::Mode original_rmode() const { return original_rmode_; } |
| 126 |
| 127 inline Code* code() const { return debug_info_->code(); } |
| 128 inline Code* original_code() const { return debug_info_->original_code(); } |
| 129 |
| 130 private: |
| 131 BreakLocation(Handle<DebugInfo> debug_info, RelocInfo* rinfo, |
| 132 RelocInfo* original_rinfo, int position, int statement_position) |
| 133 : debug_info_(debug_info), |
| 134 pc_offset_(static_cast<int>(rinfo->pc() - debug_info->code()->entry())), |
| 135 original_pc_offset_(static_cast<int>( |
| 136 original_rinfo->pc() - debug_info->original_code()->entry())), |
| 137 rmode_(rinfo->rmode()), |
| 138 original_rmode_(original_rinfo->rmode()), |
| 139 data_(rinfo->data()), |
| 140 original_data_(original_rinfo->data()), |
| 141 position_(position), |
| 142 statement_position_(statement_position) {} |
| 143 |
| 144 class Iterator { |
| 145 public: |
| 146 Iterator(Handle<DebugInfo> debug_info, BreakLocatorType type); |
| 147 |
| 148 BreakLocation GetBreakLocation() { |
| 149 return BreakLocation(debug_info_, rinfo(), original_rinfo(), position(), |
| 150 statement_position()); |
| 151 } |
| 152 |
| 153 inline bool Done() const { return RinfoDone(); } |
| 154 void Next(); |
| 155 |
| 156 void SkipTo(int count) { |
| 157 while (count-- > 0) Next(); |
| 158 } |
| 159 |
| 160 inline RelocInfo::Mode rmode() { return reloc_iterator_.rinfo()->rmode(); } |
| 161 inline RelocInfo::Mode original_rmode() { |
| 162 return reloc_iterator_.rinfo()->rmode(); |
| 163 } |
| 164 |
| 165 inline RelocInfo* rinfo() { return reloc_iterator_.rinfo(); } |
| 166 inline RelocInfo* original_rinfo() { |
| 167 return reloc_iterator_original_.rinfo(); |
| 168 } |
| 169 |
| 170 inline Address pc() { return rinfo()->pc(); } |
| 171 inline Address original_pc() { return original_rinfo()->pc(); } |
| 172 |
| 173 int break_index() const { return break_index_; } |
| 174 |
| 175 inline int position() const { return position_; } |
| 176 inline int statement_position() const { return statement_position_; } |
| 177 |
| 178 private: |
| 179 bool RinfoDone() const; |
| 180 void RinfoNext(); |
| 181 |
| 182 Handle<DebugInfo> debug_info_; |
| 183 BreakLocatorType type_; |
| 184 RelocIterator reloc_iterator_; |
| 185 RelocIterator reloc_iterator_original_; |
| 186 int break_index_; |
| 187 int position_; |
| 188 int statement_position_; |
| 189 |
| 190 DisallowHeapAllocation no_gc_; |
| 191 |
| 192 DISALLOW_COPY_AND_ASSIGN(Iterator); |
| 193 }; |
| 194 |
| 195 friend class Debug; |
| 196 |
| 197 static int BreakIndexFromAddress(Handle<DebugInfo> debug_info, |
| 198 BreakLocatorType type, Address pc); |
| 199 |
| 200 void ClearDebugBreak(); |
| 201 void RestoreFromOriginal(int length_in_bytes); |
| 202 |
| 203 void SetDebugBreak(); |
| 204 void SetDebugBreakAtReturn(); |
| 205 void SetDebugBreakAtSlot(); |
| 206 void SetDebugBreakAtIC(); |
| 207 |
| 208 inline bool IsDebuggerStatement() const { |
| 209 return RelocInfo::IsDebuggerStatement(rmode_); |
| 210 } |
| 211 inline bool IsDebugBreakSlot() const { |
| 212 return RelocInfo::IsDebugBreakSlot(rmode_); |
| 213 } |
| 214 |
| 215 Handle<DebugInfo> debug_info_; |
| 216 int pc_offset_; |
| 217 int original_pc_offset_; |
| 218 RelocInfo::Mode rmode_; |
| 219 RelocInfo::Mode original_rmode_; |
| 220 intptr_t data_; |
| 221 intptr_t original_data_; |
123 int position_; | 222 int position_; |
124 int statement_position_; | 223 int statement_position_; |
125 Handle<DebugInfo> debug_info_; | |
126 RelocIterator* reloc_iterator_; | |
127 RelocIterator* reloc_iterator_original_; | |
128 | |
129 private: | |
130 void SetDebugBreak(); | |
131 void ClearDebugBreak(); | |
132 | |
133 void SetDebugBreakAtIC(); | |
134 void ClearDebugBreakAtIC(); | |
135 | |
136 bool IsDebugBreakAtReturn(); | |
137 void SetDebugBreakAtReturn(); | |
138 void ClearDebugBreakAtReturn(); | |
139 | |
140 bool IsDebugBreakSlot(); | |
141 bool IsDebugBreakAtSlot(); | |
142 void SetDebugBreakAtSlot(); | |
143 void ClearDebugBreakAtSlot(); | |
144 | |
145 DISALLOW_COPY_AND_ASSIGN(BreakLocationIterator); | |
146 }; | 224 }; |
147 | 225 |
148 | 226 |
149 // Cache of all script objects in the heap. When a script is added a weak handle | 227 // Cache of all script objects in the heap. When a script is added a weak handle |
150 // to it is created and that weak handle is stored in the cache. The weak handle | 228 // to it is created and that weak handle is stored in the cache. The weak handle |
151 // callback takes care of removing the script from the cache. The key used in | 229 // callback takes care of removing the script from the cache. The key used in |
152 // the cache is the script id. | 230 // the cache is the script id. |
153 class ScriptCache : private HashMap { | 231 class ScriptCache : private HashMap { |
154 public: | 232 public: |
155 explicit ScriptCache(Isolate* isolate); | 233 explicit ScriptCache(Isolate* isolate); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 void ChangeBreakOnException(ExceptionBreakType type, bool enable); | 474 void ChangeBreakOnException(ExceptionBreakType type, bool enable); |
397 bool IsBreakOnException(ExceptionBreakType type); | 475 bool IsBreakOnException(ExceptionBreakType type); |
398 | 476 |
399 // Stepping handling. | 477 // Stepping handling. |
400 void PrepareStep(StepAction step_action, | 478 void PrepareStep(StepAction step_action, |
401 int step_count, | 479 int step_count, |
402 StackFrame::Id frame_id); | 480 StackFrame::Id frame_id); |
403 void ClearStepping(); | 481 void ClearStepping(); |
404 void ClearStepOut(); | 482 void ClearStepOut(); |
405 bool IsStepping() { return thread_local_.step_count_ > 0; } | 483 bool IsStepping() { return thread_local_.step_count_ > 0; } |
406 bool StepNextContinue(BreakLocationIterator* break_location_iterator, | 484 bool StepNextContinue(BreakLocation* location, JavaScriptFrame* frame); |
407 JavaScriptFrame* frame); | |
408 bool StepInActive() { return thread_local_.step_into_fp_ != 0; } | 485 bool StepInActive() { return thread_local_.step_into_fp_ != 0; } |
409 void HandleStepIn(Handle<Object> function_obj, Handle<Object> holder, | 486 void HandleStepIn(Handle<Object> function_obj, Handle<Object> holder, |
410 Address fp, bool is_constructor); | 487 Address fp, bool is_constructor); |
411 bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } | 488 bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } |
412 | 489 |
413 // Purge all code objects that have no debug break slots. | 490 // Purge all code objects that have no debug break slots. |
414 void PrepareForBreakPoints(); | 491 void PrepareForBreakPoints(); |
415 | 492 |
416 // Returns whether the operation succeeded. Compilation can only be triggered | 493 // Returns whether the operation succeeded. Compilation can only be triggered |
417 // if a valid closure is passed as the second argument, otherwise the shared | 494 // if a valid closure is passed as the second argument, otherwise the shared |
418 // function needs to be compiled already. | 495 // function needs to be compiled already. |
419 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | 496 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
420 Handle<JSFunction> function); | 497 Handle<JSFunction> function); |
421 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); | 498 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); |
422 static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); | 499 static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); |
423 | 500 |
424 // This function is used in FunctionNameUsing* tests. | 501 // This function is used in FunctionNameUsing* tests. |
425 Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position); | 502 Handle<Object> FindSharedFunctionInfoInScript(Handle<Script> script, |
| 503 int position); |
426 | 504 |
427 // Returns true if the current stub call is patched to call the debugger. | 505 // Returns true if the current stub call is patched to call the debugger. |
428 static bool IsDebugBreak(Address addr); | 506 static bool IsDebugBreak(Address addr); |
429 // Returns true if the current return statement has been patched to be | |
430 // a debugger breakpoint. | |
431 static bool IsDebugBreakAtReturn(RelocInfo* rinfo); | |
432 | 507 |
433 static Handle<Object> GetSourceBreakLocations( | 508 static Handle<Object> GetSourceBreakLocations( |
434 Handle<SharedFunctionInfo> shared, | 509 Handle<SharedFunctionInfo> shared, |
435 BreakPositionAlignment position_aligment); | 510 BreakPositionAlignment position_aligment); |
436 | 511 |
437 // Check whether a global object is the debug global object. | 512 // Check whether a global object is the debug global object. |
438 bool IsDebugGlobal(GlobalObject* global); | 513 bool IsDebugGlobal(GlobalObject* global); |
439 | 514 |
440 // Check whether this frame is just about to return. | 515 // Check whether this frame is just about to return. |
441 bool IsBreakAtReturn(JavaScriptFrame* frame); | 516 bool IsBreakAtReturn(JavaScriptFrame* frame); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 // several frames above. | 841 // several frames above. |
767 // There is no calling conventions here, because it never actually gets | 842 // There is no calling conventions here, because it never actually gets |
768 // called, it only gets returned to. | 843 // called, it only gets returned to. |
769 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); | 844 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); |
770 }; | 845 }; |
771 | 846 |
772 | 847 |
773 } } // namespace v8::internal | 848 } } // namespace v8::internal |
774 | 849 |
775 #endif // V8_DEBUG_H_ | 850 #endif // V8_DEBUG_H_ |
OLD | NEW |