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