Home | History | Annotate | Download | only in src
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_DEBUG_H_
      6 #define V8_DEBUG_H_
      7 
      8 #include "src/allocation.h"
      9 #include "src/arguments.h"
     10 #include "src/assembler.h"
     11 #include "src/execution.h"
     12 #include "src/factory.h"
     13 #include "src/flags.h"
     14 #include "src/frames-inl.h"
     15 #include "src/hashmap.h"
     16 #include "src/liveedit.h"
     17 #include "src/platform.h"
     18 #include "src/string-stream.h"
     19 #include "src/v8threads.h"
     20 
     21 #include "include/v8-debug.h"
     22 
     23 namespace v8 {
     24 namespace internal {
     25 
     26 
     27 // Forward declarations.
     28 class DebugScope;
     29 
     30 
     31 // Step actions. NOTE: These values are in macros.py as well.
     32 enum StepAction {
     33   StepNone = -1,  // Stepping not prepared.
     34   StepOut = 0,   // Step out of the current function.
     35   StepNext = 1,  // Step to the next statement in the current function.
     36   StepIn = 2,    // Step into new functions invoked or the next statement
     37                  // in the current function.
     38   StepMin = 3,   // Perform a minimum step in the current function.
     39   StepInMin = 4  // Step into new functions invoked or perform a minimum step
     40                  // in the current function.
     41 };
     42 
     43 
     44 // Type of exception break. NOTE: These values are in macros.py as well.
     45 enum ExceptionBreakType {
     46   BreakException = 0,
     47   BreakUncaughtException = 1
     48 };
     49 
     50 
     51 // Type of exception break. NOTE: These values are in macros.py as well.
     52 enum BreakLocatorType {
     53   ALL_BREAK_LOCATIONS = 0,
     54   SOURCE_BREAK_LOCATIONS = 1
     55 };
     56 
     57 
     58 // The different types of breakpoint position alignments.
     59 // Must match Debug.BreakPositionAlignment in debug-debugger.js
     60 enum BreakPositionAlignment {
     61   STATEMENT_ALIGNED = 0,
     62   BREAK_POSITION_ALIGNED = 1
     63 };
     64 
     65 
     66 // Class for iterating through the break points in a function and changing
     67 // them.
     68 class BreakLocationIterator {
     69  public:
     70   explicit BreakLocationIterator(Handle<DebugInfo> debug_info,
     71                                  BreakLocatorType type);
     72   virtual ~BreakLocationIterator();
     73 
     74   void Next();
     75   void Next(int count);
     76   void FindBreakLocationFromAddress(Address pc);
     77   void FindBreakLocationFromPosition(int position,
     78       BreakPositionAlignment alignment);
     79   void Reset();
     80   bool Done() const;
     81   void SetBreakPoint(Handle<Object> break_point_object);
     82   void ClearBreakPoint(Handle<Object> break_point_object);
     83   void SetOneShot();
     84   void ClearOneShot();
     85   bool IsStepInLocation(Isolate* isolate);
     86   void PrepareStepIn(Isolate* isolate);
     87   bool IsExit() const;
     88   bool HasBreakPoint();
     89   bool IsDebugBreak();
     90   Object* BreakPointObjects();
     91   void ClearAllDebugBreak();
     92 
     93 
     94   inline int code_position() {
     95     return static_cast<int>(pc() - debug_info_->code()->entry());
     96   }
     97   inline int break_point() { return break_point_; }
     98   inline int position() { return position_; }
     99   inline int statement_position() { return statement_position_; }
    100   inline Address pc() { return reloc_iterator_->rinfo()->pc(); }
    101   inline Code* code() { return debug_info_->code(); }
    102   inline RelocInfo* rinfo() { return reloc_iterator_->rinfo(); }
    103   inline RelocInfo::Mode rmode() const {
    104     return reloc_iterator_->rinfo()->rmode();
    105   }
    106   inline RelocInfo* original_rinfo() {
    107     return reloc_iterator_original_->rinfo();
    108   }
    109   inline RelocInfo::Mode original_rmode() const {
    110     return reloc_iterator_original_->rinfo()->rmode();
    111   }
    112 
    113   bool IsDebuggerStatement();
    114 
    115  protected:
    116   bool RinfoDone() const;
    117   void RinfoNext();
    118 
    119   BreakLocatorType type_;
    120   int break_point_;
    121   int position_;
    122   int statement_position_;
    123   Handle<DebugInfo> debug_info_;
    124   RelocIterator* reloc_iterator_;
    125   RelocIterator* reloc_iterator_original_;
    126 
    127  private:
    128   void SetDebugBreak();
    129   void ClearDebugBreak();
    130 
    131   void SetDebugBreakAtIC();
    132   void ClearDebugBreakAtIC();
    133 
    134   bool IsDebugBreakAtReturn();
    135   void SetDebugBreakAtReturn();
    136   void ClearDebugBreakAtReturn();
    137 
    138   bool IsDebugBreakSlot();
    139   bool IsDebugBreakAtSlot();
    140   void SetDebugBreakAtSlot();
    141   void ClearDebugBreakAtSlot();
    142 
    143   DISALLOW_COPY_AND_ASSIGN(BreakLocationIterator);
    144 };
    145 
    146 
    147 // Cache of all script objects in the heap. When a script is added a weak handle
    148 // to it is created and that weak handle is stored in the cache. The weak handle
    149 // callback takes care of removing the script from the cache. The key used in
    150 // the cache is the script id.
    151 class ScriptCache : private HashMap {
    152  public:
    153   explicit ScriptCache(Isolate* isolate);
    154   virtual ~ScriptCache() { Clear(); }
    155 
    156   // Add script to the cache.
    157   void Add(Handle<Script> script);
    158 
    159   // Return the scripts in the cache.
    160   Handle<FixedArray> GetScripts();
    161 
    162   // Generate debugger events for collected scripts.
    163   void ProcessCollectedScripts();
    164 
    165  private:
    166   // Calculate the hash value from the key (script id).
    167   static uint32_t Hash(int key) {
    168     return ComputeIntegerHash(key, v8::internal::kZeroHashSeed);
    169   }
    170 
    171   // Clear the cache releasing all the weak handles.
    172   void Clear();
    173 
    174   // Weak handle callback for scripts in the cache.
    175   static void HandleWeakScript(
    176       const v8::WeakCallbackData<v8::Value, void>& data);
    177 
    178   Isolate* isolate_;
    179   // List used during GC to temporarily store id's of collected scripts.
    180   List<int> collected_scripts_;
    181 };
    182 
    183 
    184 // Linked list holding debug info objects. The debug info objects are kept as
    185 // weak handles to avoid a debug info object to keep a function alive.
    186 class DebugInfoListNode {
    187  public:
    188   explicit DebugInfoListNode(DebugInfo* debug_info);
    189   virtual ~DebugInfoListNode();
    190 
    191   DebugInfoListNode* next() { return next_; }
    192   void set_next(DebugInfoListNode* next) { next_ = next; }
    193   Handle<DebugInfo> debug_info() { return debug_info_; }
    194 
    195  private:
    196   // Global (weak) handle to the debug info object.
    197   Handle<DebugInfo> debug_info_;
    198 
    199   // Next pointer for linked list.
    200   DebugInfoListNode* next_;
    201 };
    202 
    203 
    204 
    205 // Message delivered to the message handler callback. This is either a debugger
    206 // event or the response to a command.
    207 class MessageImpl: public v8::Debug::Message {
    208  public:
    209   // Create a message object for a debug event.
    210   static MessageImpl NewEvent(DebugEvent event,
    211                               bool running,
    212                               Handle<JSObject> exec_state,
    213                               Handle<JSObject> event_data);
    214 
    215   // Create a message object for the response to a debug command.
    216   static MessageImpl NewResponse(DebugEvent event,
    217                                  bool running,
    218                                  Handle<JSObject> exec_state,
    219                                  Handle<JSObject> event_data,
    220                                  Handle<String> response_json,
    221                                  v8::Debug::ClientData* client_data);
    222 
    223   // Implementation of interface v8::Debug::Message.
    224   virtual bool IsEvent() const;
    225   virtual bool IsResponse() const;
    226   virtual DebugEvent GetEvent() const;
    227   virtual bool WillStartRunning() const;
    228   virtual v8::Handle<v8::Object> GetExecutionState() const;
    229   virtual v8::Handle<v8::Object> GetEventData() const;
    230   virtual v8::Handle<v8::String> GetJSON() const;
    231   virtual v8::Handle<v8::Context> GetEventContext() const;
    232   virtual v8::Debug::ClientData* GetClientData() const;
    233   virtual v8::Isolate* GetIsolate() const;
    234 
    235  private:
    236   MessageImpl(bool is_event,
    237               DebugEvent event,
    238               bool running,
    239               Handle<JSObject> exec_state,
    240               Handle<JSObject> event_data,
    241               Handle<String> response_json,
    242               v8::Debug::ClientData* client_data);
    243 
    244   bool is_event_;  // Does this message represent a debug event?
    245   DebugEvent event_;  // Debug event causing the break.
    246   bool running_;  // Will the VM start running after this event?
    247   Handle<JSObject> exec_state_;  // Current execution state.
    248   Handle<JSObject> event_data_;  // Data associated with the event.
    249   Handle<String> response_json_;  // Response JSON if message holds a response.
    250   v8::Debug::ClientData* client_data_;  // Client data passed with the request.
    251 };
    252 
    253 
    254 // Details of the debug event delivered to the debug event listener.
    255 class EventDetailsImpl : public v8::Debug::EventDetails {
    256  public:
    257   EventDetailsImpl(DebugEvent event,
    258                    Handle<JSObject> exec_state,
    259                    Handle<JSObject> event_data,
    260                    Handle<Object> callback_data,
    261                    v8::Debug::ClientData* client_data);
    262   virtual DebugEvent GetEvent() const;
    263   virtual v8::Handle<v8::Object> GetExecutionState() const;
    264   virtual v8::Handle<v8::Object> GetEventData() const;
    265   virtual v8::Handle<v8::Context> GetEventContext() const;
    266   virtual v8::Handle<v8::Value> GetCallbackData() const;
    267   virtual v8::Debug::ClientData* GetClientData() const;
    268  private:
    269   DebugEvent event_;  // Debug event causing the break.
    270   Handle<JSObject> exec_state_;         // Current execution state.
    271   Handle<JSObject> event_data_;         // Data associated with the event.
    272   Handle<Object> callback_data_;        // User data passed with the callback
    273                                         // when it was registered.
    274   v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand.
    275 };
    276 
    277 
    278 // Message send by user to v8 debugger or debugger output message.
    279 // In addition to command text it may contain a pointer to some user data
    280 // which are expected to be passed along with the command reponse to message
    281 // handler.
    282 class CommandMessage {
    283  public:
    284   static CommandMessage New(const Vector<uint16_t>& command,
    285                             v8::Debug::ClientData* data);
    286   CommandMessage();
    287 
    288   // Deletes user data and disposes of the text.
    289   void Dispose();
    290   Vector<uint16_t> text() const { return text_; }
    291   v8::Debug::ClientData* client_data() const { return client_data_; }
    292  private:
    293   CommandMessage(const Vector<uint16_t>& text,
    294                  v8::Debug::ClientData* data);
    295 
    296   Vector<uint16_t> text_;
    297   v8::Debug::ClientData* client_data_;
    298 };
    299 
    300 
    301 // A Queue of CommandMessage objects.  A thread-safe version is
    302 // LockingCommandMessageQueue, based on this class.
    303 class CommandMessageQueue BASE_EMBEDDED {
    304  public:
    305   explicit CommandMessageQueue(int size);
    306   ~CommandMessageQueue();
    307   bool IsEmpty() const { return start_ == end_; }
    308   CommandMessage Get();
    309   void Put(const CommandMessage& message);
    310   void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().
    311  private:
    312   // Doubles the size of the message queue, and copies the messages.
    313   void Expand();
    314 
    315   CommandMessage* messages_;
    316   int start_;
    317   int end_;
    318   int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
    319 };
    320 
    321 
    322 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
    323 // messages.  The message data is not managed by LockingCommandMessageQueue.
    324 // Pointers to the data are passed in and out. Implemented by adding a
    325 // Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
    326 class LockingCommandMessageQueue BASE_EMBEDDED {
    327  public:
    328   LockingCommandMessageQueue(Logger* logger, int size);
    329   bool IsEmpty() const;
    330   CommandMessage Get();
    331   void Put(const CommandMessage& message);
    332   void Clear();
    333  private:
    334   Logger* logger_;
    335   CommandMessageQueue queue_;
    336   mutable Mutex mutex_;
    337   DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
    338 };
    339 
    340 
    341 class PromiseOnStack {
    342  public:
    343   PromiseOnStack(Isolate* isolate,
    344                  PromiseOnStack* prev,
    345                  Handle<JSFunction> getter);
    346   ~PromiseOnStack();
    347   StackHandler* handler() { return handler_; }
    348   Handle<JSFunction> getter() { return getter_; }
    349   PromiseOnStack* prev() { return prev_; }
    350  private:
    351   Isolate* isolate_;
    352   StackHandler* handler_;
    353   Handle<JSFunction> getter_;
    354   PromiseOnStack* prev_;
    355 };
    356 
    357 
    358 // This class contains the debugger support. The main purpose is to handle
    359 // setting break points in the code.
    360 //
    361 // This class controls the debug info for all functions which currently have
    362 // active breakpoints in them. This debug info is held in the heap root object
    363 // debug_info which is a FixedArray. Each entry in this list is of class
    364 // DebugInfo.
    365 class Debug {
    366  public:
    367   enum AfterCompileFlags {
    368     NO_AFTER_COMPILE_FLAGS,
    369     SEND_WHEN_DEBUGGING
    370   };
    371 
    372   // Debug event triggers.
    373   void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
    374   void OnException(Handle<Object> exception, bool uncaught);
    375   void OnBeforeCompile(Handle<Script> script);
    376   void OnAfterCompile(Handle<Script> script,
    377                       AfterCompileFlags after_compile_flags);
    378   void OnScriptCollected(int id);
    379 
    380   // API facing.
    381   void SetEventListener(Handle<Object> callback, Handle<Object> data);
    382   void SetMessageHandler(v8::Debug::MessageHandler handler);
    383   void EnqueueCommandMessage(Vector<const uint16_t> command,
    384                              v8::Debug::ClientData* client_data = NULL);
    385   // Enqueue a debugger command to the command queue for event listeners.
    386   void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
    387   MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
    388                                            Handle<Object> data);
    389   Handle<Context> GetDebugContext();
    390   void HandleDebugBreak();
    391   void ProcessDebugMessages(bool debug_command_only);
    392 
    393   // Internal logic
    394   bool Load();
    395   void Break(Arguments args, JavaScriptFrame*);
    396   void SetAfterBreakTarget(JavaScriptFrame* frame);
    397 
    398   // Scripts handling.
    399   Handle<FixedArray> GetLoadedScripts();
    400 
    401   // Break point handling.
    402   bool SetBreakPoint(Handle<JSFunction> function,
    403                      Handle<Object> break_point_object,
    404                      int* source_position);
    405   bool SetBreakPointForScript(Handle<Script> script,
    406                               Handle<Object> break_point_object,
    407                               int* source_position,
    408                               BreakPositionAlignment alignment);
    409   void ClearBreakPoint(Handle<Object> break_point_object);
    410   void ClearAllBreakPoints();
    411   void FloodWithOneShot(Handle<JSFunction> function);
    412   void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
    413   void FloodHandlerWithOneShot();
    414   void ChangeBreakOnException(ExceptionBreakType type, bool enable);
    415   bool IsBreakOnException(ExceptionBreakType type);
    416 
    417   // Stepping handling.
    418   void PrepareStep(StepAction step_action,
    419                    int step_count,
    420                    StackFrame::Id frame_id);
    421   void ClearStepping();
    422   void ClearStepOut();
    423   bool IsStepping() { return thread_local_.step_count_ > 0; }
    424   bool StepNextContinue(BreakLocationIterator* break_location_iterator,
    425                         JavaScriptFrame* frame);
    426   bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
    427   void HandleStepIn(Handle<JSFunction> function,
    428                     Handle<Object> holder,
    429                     Address fp,
    430                     bool is_constructor);
    431   bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
    432 
    433   // Purge all code objects that have no debug break slots.
    434   void PrepareForBreakPoints();
    435 
    436   // Returns whether the operation succeeded. Compilation can only be triggered
    437   // if a valid closure is passed as the second argument, otherwise the shared
    438   // function needs to be compiled already.
    439   bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
    440                        Handle<JSFunction> function);
    441   static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
    442   static bool HasDebugInfo(Handle<SharedFunctionInfo> shared);
    443 
    444   // This function is used in FunctionNameUsing* tests.
    445   Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position);
    446 
    447   // Returns true if the current stub call is patched to call the debugger.
    448   static bool IsDebugBreak(Address addr);
    449   // Returns true if the current return statement has been patched to be
    450   // a debugger breakpoint.
    451   static bool IsDebugBreakAtReturn(RelocInfo* rinfo);
    452 
    453   static Handle<Object> GetSourceBreakLocations(
    454       Handle<SharedFunctionInfo> shared,
    455       BreakPositionAlignment position_aligment);
    456 
    457   // Check whether a global object is the debug global object.
    458   bool IsDebugGlobal(GlobalObject* global);
    459 
    460   // Check whether this frame is just about to return.
    461   bool IsBreakAtReturn(JavaScriptFrame* frame);
    462 
    463   // Promise handling.
    464   void PromiseHandlePrologue(Handle<JSFunction> promise_getter);
    465   void PromiseHandleEpilogue();
    466 
    467   // Support for LiveEdit
    468   void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
    469                              LiveEdit::FrameDropMode mode,
    470                              Object** restarter_frame_function_pointer);
    471 
    472   // Passed to MakeWeak.
    473   static void HandleWeakDebugInfo(
    474       const v8::WeakCallbackData<v8::Value, void>& data);
    475 
    476   // Threading support.
    477   char* ArchiveDebug(char* to);
    478   char* RestoreDebug(char* from);
    479   static int ArchiveSpacePerThread();
    480   void FreeThreadResources() { }
    481 
    482   // Record function from which eval was called.
    483   static void RecordEvalCaller(Handle<Script> script);
    484 
    485   // Garbage collection notifications.
    486   void AfterGarbageCollection();
    487 
    488   // Flags and states.
    489   DebugScope* debugger_entry() { return thread_local_.current_debug_scope_; }
    490   inline Handle<Context> debug_context() { return debug_context_; }
    491   void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
    492   bool live_edit_enabled() const {
    493     return FLAG_enable_liveedit && live_edit_enabled_ ;
    494   }
    495 
    496   inline bool is_active() const { return is_active_; }
    497   inline bool is_loaded() const { return !debug_context_.is_null(); }
    498   inline bool has_break_points() const { return has_break_points_; }
    499   inline bool in_debug_scope() const {
    500     return thread_local_.current_debug_scope_ != NULL;
    501   }
    502   void set_disable_break(bool v) { break_disabled_ = v; }
    503 
    504   StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; }
    505   int break_id() { return thread_local_.break_id_; }
    506 
    507   // Support for embedding into generated code.
    508   Address after_break_target_address() {
    509     return reinterpret_cast<Address>(&after_break_target_);
    510   }
    511 
    512   Address restarter_frame_function_pointer_address() {
    513     Object*** address = &thread_local_.restarter_frame_function_pointer_;
    514     return reinterpret_cast<Address>(address);
    515   }
    516 
    517   Address step_in_fp_addr() {
    518     return reinterpret_cast<Address>(&thread_local_.step_into_fp_);
    519   }
    520 
    521  private:
    522   explicit Debug(Isolate* isolate);
    523 
    524   void UpdateState();
    525   void Unload();
    526   void SetNextBreakId() {
    527     thread_local_.break_id_ = ++thread_local_.break_count_;
    528   }
    529 
    530   // Check whether there are commands in the command queue.
    531   inline bool has_commands() const { return !command_queue_.IsEmpty(); }
    532   inline bool ignore_events() const { return is_suppressed_ || !is_active_; }
    533 
    534   // Constructors for debug event objects.
    535   MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
    536       const char* constructor_name,
    537       int argc,
    538       Handle<Object> argv[]);
    539   MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
    540   MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
    541       Handle<Object> break_points_hit);
    542   MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
    543       Handle<Object> exception,
    544       bool uncaught,
    545       Handle<Object> promise);
    546   MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
    547       Handle<Script> script, bool before);
    548   MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
    549 
    550   // Mirror cache handling.
    551   void ClearMirrorCache();
    552 
    553   // Returns a promise if it does not have a reject handler.
    554   Handle<Object> GetPromiseForUncaughtException();
    555 
    556   void CallEventCallback(v8::DebugEvent event,
    557                          Handle<Object> exec_state,
    558                          Handle<Object> event_data,
    559                          v8::Debug::ClientData* client_data);
    560   void ProcessDebugEvent(v8::DebugEvent event,
    561                          Handle<JSObject> event_data,
    562                          bool auto_continue);
    563   void NotifyMessageHandler(v8::DebugEvent event,
    564                             Handle<JSObject> exec_state,
    565                             Handle<JSObject> event_data,
    566                             bool auto_continue);
    567   void InvokeMessageHandler(MessageImpl message);
    568 
    569   static bool CompileDebuggerScript(Isolate* isolate, int index);
    570   void ClearOneShot();
    571   void ActivateStepIn(StackFrame* frame);
    572   void ClearStepIn();
    573   void ActivateStepOut(StackFrame* frame);
    574   void ClearStepNext();
    575   // Returns whether the compile succeeded.
    576   void RemoveDebugInfo(Handle<DebugInfo> debug_info);
    577   Handle<Object> CheckBreakPoints(Handle<Object> break_point);
    578   bool CheckBreakPoint(Handle<Object> break_point_object);
    579 
    580   inline void AssertDebugContext() {
    581     ASSERT(isolate_->context() == *debug_context());
    582     ASSERT(in_debug_scope());
    583   }
    584 
    585   void ThreadInit();
    586 
    587   // Global handles.
    588   Handle<Context> debug_context_;
    589   Handle<Object> event_listener_;
    590   Handle<Object> event_listener_data_;
    591 
    592   v8::Debug::MessageHandler message_handler_;
    593 
    594   static const int kQueueInitialSize = 4;
    595   Semaphore command_received_;  // Signaled for each command received.
    596   LockingCommandMessageQueue command_queue_;
    597   LockingCommandMessageQueue event_command_queue_;
    598 
    599   bool is_active_;
    600   bool is_suppressed_;
    601   bool live_edit_enabled_;
    602   bool has_break_points_;
    603   bool break_disabled_;
    604   bool break_on_exception_;
    605   bool break_on_uncaught_exception_;
    606 
    607   ScriptCache* script_cache_;  // Cache of all scripts in the heap.
    608   DebugInfoListNode* debug_info_list_;  // List of active debug info objects.
    609 
    610   // Storage location for jump when exiting debug break calls.
    611   // Note that this address is not GC safe.  It should be computed immediately
    612   // before returning to the DebugBreakCallHelper.
    613   Address after_break_target_;
    614 
    615   // Per-thread data.
    616   class ThreadLocal {
    617    public:
    618     // Top debugger entry.
    619     DebugScope* current_debug_scope_;
    620 
    621     // Counter for generating next break id.
    622     int break_count_;
    623 
    624     // Current break id.
    625     int break_id_;
    626 
    627     // Frame id for the frame of the current break.
    628     StackFrame::Id break_frame_id_;
    629 
    630     // Step action for last step performed.
    631     StepAction last_step_action_;
    632 
    633     // Source statement position from last step next action.
    634     int last_statement_position_;
    635 
    636     // Number of steps left to perform before debug event.
    637     int step_count_;
    638 
    639     // Frame pointer from last step next action.
    640     Address last_fp_;
    641 
    642     // Number of queued steps left to perform before debug event.
    643     int queued_step_count_;
    644 
    645     // Frame pointer for frame from which step in was performed.
    646     Address step_into_fp_;
    647 
    648     // Frame pointer for the frame where debugger should be called when current
    649     // step out action is completed.
    650     Address step_out_fp_;
    651 
    652     // Stores the way how LiveEdit has patched the stack. It is used when
    653     // debugger returns control back to user script.
    654     LiveEdit::FrameDropMode frame_drop_mode_;
    655 
    656     // When restarter frame is on stack, stores the address
    657     // of the pointer to function being restarted. Otherwise (most of the time)
    658     // stores NULL. This pointer is used with 'step in' implementation.
    659     Object** restarter_frame_function_pointer_;
    660 
    661     // When a promise is being resolved, we may want to trigger a debug event
    662     // if we catch a throw.  For this purpose we remember the try-catch
    663     // handler address that would catch the exception.  We also hold onto a
    664     // closure that returns a promise if the exception is considered uncaught.
    665     // Due to the possibility of reentry we use a linked list.
    666     PromiseOnStack* promise_on_stack_;
    667   };
    668 
    669   // Storage location for registers when handling debug break calls
    670   ThreadLocal thread_local_;
    671 
    672   Isolate* isolate_;
    673 
    674   friend class Isolate;
    675   friend class DebugScope;
    676   friend class DisableBreak;
    677   friend class LiveEdit;
    678   friend class SuppressDebug;
    679 
    680   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
    681   friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc
    682 
    683   DISALLOW_COPY_AND_ASSIGN(Debug);
    684 };
    685 
    686 
    687 DECLARE_RUNTIME_FUNCTION(Debug_Break);
    688 
    689 
    690 // This scope is used to load and enter the debug context and create a new
    691 // break state.  Leaving the scope will restore the previous state.
    692 // On failure to load, FailedToEnter returns true.
    693 class DebugScope BASE_EMBEDDED {
    694  public:
    695   explicit DebugScope(Debug* debug);
    696   ~DebugScope();
    697 
    698   // Check whether loading was successful.
    699   inline bool failed() { return failed_; }
    700 
    701   // Get the active context from before entering the debugger.
    702   inline Handle<Context> GetContext() { return save_.context(); }
    703 
    704  private:
    705   Isolate* isolate() { return debug_->isolate_; }
    706 
    707   Debug* debug_;
    708   DebugScope* prev_;               // Previous scope if entered recursively.
    709   StackFrame::Id break_frame_id_;  // Previous break frame id.
    710   int break_id_;                   // Previous break id.
    711   bool failed_;                    // Did the debug context fail to load?
    712   SaveContext save_;               // Saves previous context.
    713 };
    714 
    715 
    716 // Stack allocated class for disabling break.
    717 class DisableBreak BASE_EMBEDDED {
    718  public:
    719   explicit DisableBreak(Debug* debug, bool disable_break)
    720     : debug_(debug), old_state_(debug->break_disabled_) {
    721     debug_->break_disabled_ = disable_break;
    722   }
    723   ~DisableBreak() { debug_->break_disabled_ = old_state_; }
    724 
    725  private:
    726   Debug* debug_;
    727   bool old_state_;
    728   DISALLOW_COPY_AND_ASSIGN(DisableBreak);
    729 };
    730 
    731 
    732 class SuppressDebug BASE_EMBEDDED {
    733  public:
    734   explicit SuppressDebug(Debug* debug)
    735       : debug_(debug), old_state_(debug->is_suppressed_) {
    736     debug_->is_suppressed_ = true;
    737   }
    738   ~SuppressDebug() { debug_->is_suppressed_ = old_state_; }
    739 
    740  private:
    741   Debug* debug_;
    742   bool old_state_;
    743   DISALLOW_COPY_AND_ASSIGN(SuppressDebug);
    744 };
    745 
    746 
    747 // Code generator routines.
    748 class DebugCodegen : public AllStatic {
    749  public:
    750   static void GenerateSlot(MacroAssembler* masm);
    751   static void GenerateCallICStubDebugBreak(MacroAssembler* masm);
    752   static void GenerateLoadICDebugBreak(MacroAssembler* masm);
    753   static void GenerateStoreICDebugBreak(MacroAssembler* masm);
    754   static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
    755   static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
    756   static void GenerateCompareNilICDebugBreak(MacroAssembler* masm);
    757   static void GenerateReturnDebugBreak(MacroAssembler* masm);
    758   static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
    759   static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
    760   static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
    761   static void GenerateSlotDebugBreak(MacroAssembler* masm);
    762   static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
    763 
    764   // FrameDropper is a code replacement for a JavaScript frame with possibly
    765   // several frames above.
    766   // There is no calling conventions here, because it never actually gets
    767   // called, it only gets returned to.
    768   static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
    769 };
    770 
    771 
    772 } }  // namespace v8::internal
    773 
    774 #endif  // V8_DEBUG_H_
    775