Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_DEBUG_H_
     29 #define V8_DEBUG_H_
     30 
     31 #include "allocation.h"
     32 #include "arguments.h"
     33 #include "assembler.h"
     34 #include "debug-agent.h"
     35 #include "execution.h"
     36 #include "factory.h"
     37 #include "flags.h"
     38 #include "frames-inl.h"
     39 #include "hashmap.h"
     40 #include "platform.h"
     41 #include "string-stream.h"
     42 #include "v8threads.h"
     43 
     44 #ifdef ENABLE_DEBUGGER_SUPPORT
     45 #include "../include/v8-debug.h"
     46 
     47 namespace v8 {
     48 namespace internal {
     49 
     50 
     51 // Forward declarations.
     52 class EnterDebugger;
     53 
     54 
     55 // Step actions. NOTE: These values are in macros.py as well.
     56 enum StepAction {
     57   StepNone = -1,  // Stepping not prepared.
     58   StepOut = 0,   // Step out of the current function.
     59   StepNext = 1,  // Step to the next statement in the current function.
     60   StepIn = 2,    // Step into new functions invoked or the next statement
     61                  // in the current function.
     62   StepMin = 3,   // Perform a minimum step in the current function.
     63   StepInMin = 4  // Step into new functions invoked or perform a minimum step
     64                  // in the current function.
     65 };
     66 
     67 
     68 // Type of exception break. NOTE: These values are in macros.py as well.
     69 enum ExceptionBreakType {
     70   BreakException = 0,
     71   BreakUncaughtException = 1
     72 };
     73 
     74 
     75 // Type of exception break. NOTE: These values are in macros.py as well.
     76 enum BreakLocatorType {
     77   ALL_BREAK_LOCATIONS = 0,
     78   SOURCE_BREAK_LOCATIONS = 1
     79 };
     80 
     81 
     82 // Class for iterating through the break points in a function and changing
     83 // them.
     84 class BreakLocationIterator {
     85  public:
     86   explicit BreakLocationIterator(Handle<DebugInfo> debug_info,
     87                                  BreakLocatorType type);
     88   virtual ~BreakLocationIterator();
     89 
     90   void Next();
     91   void Next(int count);
     92   void FindBreakLocationFromAddress(Address pc);
     93   void FindBreakLocationFromPosition(int position);
     94   void Reset();
     95   bool Done() const;
     96   void SetBreakPoint(Handle<Object> break_point_object);
     97   void ClearBreakPoint(Handle<Object> break_point_object);
     98   void SetOneShot();
     99   void ClearOneShot();
    100   void PrepareStepIn();
    101   bool IsExit() const;
    102   bool HasBreakPoint();
    103   bool IsDebugBreak();
    104   Object* BreakPointObjects();
    105   void ClearAllDebugBreak();
    106 
    107 
    108   inline int code_position() {
    109     return static_cast<int>(pc() - debug_info_->code()->entry());
    110   }
    111   inline int break_point() { return break_point_; }
    112   inline int position() { return position_; }
    113   inline int statement_position() { return statement_position_; }
    114   inline Address pc() { return reloc_iterator_->rinfo()->pc(); }
    115   inline Code* code() { return debug_info_->code(); }
    116   inline RelocInfo* rinfo() { return reloc_iterator_->rinfo(); }
    117   inline RelocInfo::Mode rmode() const {
    118     return reloc_iterator_->rinfo()->rmode();
    119   }
    120   inline RelocInfo* original_rinfo() {
    121     return reloc_iterator_original_->rinfo();
    122   }
    123   inline RelocInfo::Mode original_rmode() const {
    124     return reloc_iterator_original_->rinfo()->rmode();
    125   }
    126 
    127   bool IsDebuggerStatement();
    128 
    129  protected:
    130   bool RinfoDone() const;
    131   void RinfoNext();
    132 
    133   BreakLocatorType type_;
    134   int break_point_;
    135   int position_;
    136   int statement_position_;
    137   Handle<DebugInfo> debug_info_;
    138   RelocIterator* reloc_iterator_;
    139   RelocIterator* reloc_iterator_original_;
    140 
    141  private:
    142   void SetDebugBreak();
    143   void ClearDebugBreak();
    144 
    145   void SetDebugBreakAtIC();
    146   void ClearDebugBreakAtIC();
    147 
    148   bool IsDebugBreakAtReturn();
    149   void SetDebugBreakAtReturn();
    150   void ClearDebugBreakAtReturn();
    151 
    152   bool IsDebugBreakSlot();
    153   bool IsDebugBreakAtSlot();
    154   void SetDebugBreakAtSlot();
    155   void ClearDebugBreakAtSlot();
    156 
    157   DISALLOW_COPY_AND_ASSIGN(BreakLocationIterator);
    158 };
    159 
    160 
    161 // Cache of all script objects in the heap. When a script is added a weak handle
    162 // to it is created and that weak handle is stored in the cache. The weak handle
    163 // callback takes care of removing the script from the cache. The key used in
    164 // the cache is the script id.
    165 class ScriptCache : private HashMap {
    166  public:
    167   ScriptCache() : HashMap(ScriptMatch), collected_scripts_(10) {}
    168   virtual ~ScriptCache() { Clear(); }
    169 
    170   // Add script to the cache.
    171   void Add(Handle<Script> script);
    172 
    173   // Return the scripts in the cache.
    174   Handle<FixedArray> GetScripts();
    175 
    176   // Generate debugger events for collected scripts.
    177   void ProcessCollectedScripts();
    178 
    179  private:
    180   // Calculate the hash value from the key (script id).
    181   static uint32_t Hash(int key) {
    182     return ComputeIntegerHash(key, v8::internal::kZeroHashSeed);
    183   }
    184 
    185   // Scripts match if their keys (script id) match.
    186   static bool ScriptMatch(void* key1, void* key2) { return key1 == key2; }
    187 
    188   // Clear the cache releasing all the weak handles.
    189   void Clear();
    190 
    191   // Weak handle callback for scripts in the cache.
    192   static void HandleWeakScript(v8::Persistent<v8::Value> obj, void* data);
    193 
    194   // List used during GC to temporarily store id's of collected scripts.
    195   List<int> collected_scripts_;
    196 };
    197 
    198 
    199 // Linked list holding debug info objects. The debug info objects are kept as
    200 // weak handles to avoid a debug info object to keep a function alive.
    201 class DebugInfoListNode {
    202  public:
    203   explicit DebugInfoListNode(DebugInfo* debug_info);
    204   virtual ~DebugInfoListNode();
    205 
    206   DebugInfoListNode* next() { return next_; }
    207   void set_next(DebugInfoListNode* next) { next_ = next; }
    208   Handle<DebugInfo> debug_info() { return debug_info_; }
    209 
    210  private:
    211   // Global (weak) handle to the debug info object.
    212   Handle<DebugInfo> debug_info_;
    213 
    214   // Next pointer for linked list.
    215   DebugInfoListNode* next_;
    216 };
    217 
    218 // This class contains the debugger support. The main purpose is to handle
    219 // setting break points in the code.
    220 //
    221 // This class controls the debug info for all functions which currently have
    222 // active breakpoints in them. This debug info is held in the heap root object
    223 // debug_info which is a FixedArray. Each entry in this list is of class
    224 // DebugInfo.
    225 class Debug {
    226  public:
    227   void SetUp(bool create_heap_objects);
    228   bool Load();
    229   void Unload();
    230   bool IsLoaded() { return !debug_context_.is_null(); }
    231   bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
    232   void PreemptionWhileInDebugger();
    233   void Iterate(ObjectVisitor* v);
    234 
    235   Object* Break(Arguments args);
    236   void SetBreakPoint(Handle<SharedFunctionInfo> shared,
    237                      Handle<Object> break_point_object,
    238                      int* source_position);
    239   void ClearBreakPoint(Handle<Object> break_point_object);
    240   void ClearAllBreakPoints();
    241   void FloodWithOneShot(Handle<SharedFunctionInfo> shared);
    242   void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
    243   void FloodHandlerWithOneShot();
    244   void ChangeBreakOnException(ExceptionBreakType type, bool enable);
    245   bool IsBreakOnException(ExceptionBreakType type);
    246   void PrepareStep(StepAction step_action, int step_count);
    247   void ClearStepping();
    248   bool StepNextContinue(BreakLocationIterator* break_location_iterator,
    249                         JavaScriptFrame* frame);
    250   static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
    251   static bool HasDebugInfo(Handle<SharedFunctionInfo> shared);
    252 
    253   void PrepareForBreakPoints();
    254 
    255   // Returns whether the operation succeeded.
    256   bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
    257 
    258   // Returns true if the current stub call is patched to call the debugger.
    259   static bool IsDebugBreak(Address addr);
    260   // Returns true if the current return statement has been patched to be
    261   // a debugger breakpoint.
    262   static bool IsDebugBreakAtReturn(RelocInfo* rinfo);
    263 
    264   // Check whether a code stub with the specified major key is a possible break
    265   // point location.
    266   static bool IsSourceBreakStub(Code* code);
    267   static bool IsBreakStub(Code* code);
    268 
    269   // Find the builtin to use for invoking the debug break
    270   static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode);
    271 
    272   static Handle<Object> GetSourceBreakLocations(
    273       Handle<SharedFunctionInfo> shared);
    274 
    275   // Getter for the debug_context.
    276   inline Handle<Context> debug_context() { return debug_context_; }
    277 
    278   // Check whether a global object is the debug global object.
    279   bool IsDebugGlobal(GlobalObject* global);
    280 
    281   // Check whether this frame is just about to return.
    282   bool IsBreakAtReturn(JavaScriptFrame* frame);
    283 
    284   // Fast check to see if any break points are active.
    285   inline bool has_break_points() { return has_break_points_; }
    286 
    287   void NewBreak(StackFrame::Id break_frame_id);
    288   void SetBreak(StackFrame::Id break_frame_id, int break_id);
    289   StackFrame::Id break_frame_id() {
    290     return thread_local_.break_frame_id_;
    291   }
    292   int break_id() { return thread_local_.break_id_; }
    293 
    294   bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
    295   void HandleStepIn(Handle<JSFunction> function,
    296                     Handle<Object> holder,
    297                     Address fp,
    298                     bool is_constructor);
    299   Address step_in_fp() { return thread_local_.step_into_fp_; }
    300   Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; }
    301 
    302   bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
    303   Address step_out_fp() { return thread_local_.step_out_fp_; }
    304 
    305   EnterDebugger* debugger_entry() {
    306     return thread_local_.debugger_entry_;
    307   }
    308   void set_debugger_entry(EnterDebugger* entry) {
    309     thread_local_.debugger_entry_ = entry;
    310   }
    311 
    312   // Check whether any of the specified interrupts are pending.
    313   bool is_interrupt_pending(InterruptFlag what) {
    314     return (thread_local_.pending_interrupts_ & what) != 0;
    315   }
    316 
    317   // Set specified interrupts as pending.
    318   void set_interrupts_pending(InterruptFlag what) {
    319     thread_local_.pending_interrupts_ |= what;
    320   }
    321 
    322   // Clear specified interrupts from pending.
    323   void clear_interrupt_pending(InterruptFlag what) {
    324     thread_local_.pending_interrupts_ &= ~static_cast<int>(what);
    325   }
    326 
    327   // Getter and setter for the disable break state.
    328   bool disable_break() { return disable_break_; }
    329   void set_disable_break(bool disable_break) {
    330     disable_break_ = disable_break;
    331   }
    332 
    333   // Getters for the current exception break state.
    334   bool break_on_exception() { return break_on_exception_; }
    335   bool break_on_uncaught_exception() {
    336     return break_on_uncaught_exception_;
    337   }
    338 
    339   enum AddressId {
    340     k_after_break_target_address,
    341     k_debug_break_return_address,
    342     k_debug_break_slot_address,
    343     k_restarter_frame_function_pointer
    344   };
    345 
    346   // Support for setting the address to jump to when returning from break point.
    347   Address* after_break_target_address() {
    348     return reinterpret_cast<Address*>(&thread_local_.after_break_target_);
    349   }
    350   Address* restarter_frame_function_pointer_address() {
    351     Object*** address = &thread_local_.restarter_frame_function_pointer_;
    352     return reinterpret_cast<Address*>(address);
    353   }
    354 
    355   // Support for saving/restoring registers when handling debug break calls.
    356   Object** register_address(int r) {
    357     return &registers_[r];
    358   }
    359 
    360   // Access to the debug break on return code.
    361   Code* debug_break_return() { return debug_break_return_; }
    362   Code** debug_break_return_address() {
    363     return &debug_break_return_;
    364   }
    365 
    366   // Access to the debug break in debug break slot code.
    367   Code* debug_break_slot() { return debug_break_slot_; }
    368   Code** debug_break_slot_address() {
    369     return &debug_break_slot_;
    370   }
    371 
    372   static const int kEstimatedNofDebugInfoEntries = 16;
    373   static const int kEstimatedNofBreakPointsInFunction = 16;
    374 
    375   // Passed to MakeWeak.
    376   static void HandleWeakDebugInfo(v8::Persistent<v8::Value> obj, void* data);
    377 
    378   friend class Debugger;
    379   friend Handle<FixedArray> GetDebuggedFunctions();  // In test-debug.cc
    380   friend void CheckDebuggerUnloaded(bool check_functions);  // In test-debug.cc
    381 
    382   // Threading support.
    383   char* ArchiveDebug(char* to);
    384   char* RestoreDebug(char* from);
    385   static int ArchiveSpacePerThread();
    386   void FreeThreadResources() { }
    387 
    388   // Mirror cache handling.
    389   void ClearMirrorCache();
    390 
    391   // Script cache handling.
    392   void CreateScriptCache();
    393   void DestroyScriptCache();
    394   void AddScriptToScriptCache(Handle<Script> script);
    395   Handle<FixedArray> GetLoadedScripts();
    396 
    397   // Garbage collection notifications.
    398   void AfterGarbageCollection();
    399 
    400   // Code generator routines.
    401   static void GenerateSlot(MacroAssembler* masm);
    402   static void GenerateLoadICDebugBreak(MacroAssembler* masm);
    403   static void GenerateStoreICDebugBreak(MacroAssembler* masm);
    404   static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
    405   static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
    406   static void GenerateReturnDebugBreak(MacroAssembler* masm);
    407   static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
    408   static void GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm);
    409   static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
    410   static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
    411   static void GenerateSlotDebugBreak(MacroAssembler* masm);
    412   static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
    413 
    414   // FrameDropper is a code replacement for a JavaScript frame with possibly
    415   // several frames above.
    416   // There is no calling conventions here, because it never actually gets
    417   // called, it only gets returned to.
    418   static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
    419 
    420   // Called from stub-cache.cc.
    421   static void GenerateCallICDebugBreak(MacroAssembler* masm);
    422 
    423   // Describes how exactly a frame has been dropped from stack.
    424   enum FrameDropMode {
    425     // No frame has been dropped.
    426     FRAMES_UNTOUCHED,
    427     // The top JS frame had been calling IC stub. IC stub mustn't be called now.
    428     FRAME_DROPPED_IN_IC_CALL,
    429     // The top JS frame had been calling debug break slot stub. Patch the
    430     // address this stub jumps to in the end.
    431     FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
    432     // The top JS frame had been calling some C++ function. The return address
    433     // gets patched automatically.
    434     FRAME_DROPPED_IN_DIRECT_CALL,
    435     FRAME_DROPPED_IN_RETURN_CALL
    436   };
    437 
    438   void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id,
    439                                     FrameDropMode mode,
    440                                     Object** restarter_frame_function_pointer);
    441 
    442   // Initializes an artificial stack frame. The data it contains is used for:
    443   //  a. successful work of frame dropper code which eventually gets control,
    444   //  b. being compatible with regular stack structure for various stack
    445   //     iterators.
    446   // Returns address of stack allocated pointer to restarted function,
    447   // the value that is called 'restarter_frame_function_pointer'. The value
    448   // at this address (possibly updated by GC) may be used later when preparing
    449   // 'step in' operation.
    450   static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
    451                                          Handle<Code> code);
    452 
    453   static const int kFrameDropperFrameSize;
    454 
    455   // Architecture-specific constant.
    456   static const bool kFrameDropperSupported;
    457 
    458  private:
    459   explicit Debug(Isolate* isolate);
    460   ~Debug();
    461 
    462   static bool CompileDebuggerScript(int index);
    463   void ClearOneShot();
    464   void ActivateStepIn(StackFrame* frame);
    465   void ClearStepIn();
    466   void ActivateStepOut(StackFrame* frame);
    467   void ClearStepOut();
    468   void ClearStepNext();
    469   // Returns whether the compile succeeded.
    470   void RemoveDebugInfo(Handle<DebugInfo> debug_info);
    471   void SetAfterBreakTarget(JavaScriptFrame* frame);
    472   Handle<Object> CheckBreakPoints(Handle<Object> break_point);
    473   bool CheckBreakPoint(Handle<Object> break_point_object);
    474 
    475   // Global handle to debug context where all the debugger JavaScript code is
    476   // loaded.
    477   Handle<Context> debug_context_;
    478 
    479   // Boolean state indicating whether any break points are set.
    480   bool has_break_points_;
    481 
    482   // Cache of all scripts in the heap.
    483   ScriptCache* script_cache_;
    484 
    485   // List of active debug info objects.
    486   DebugInfoListNode* debug_info_list_;
    487 
    488   bool disable_break_;
    489   bool break_on_exception_;
    490   bool break_on_uncaught_exception_;
    491 
    492   // Per-thread data.
    493   class ThreadLocal {
    494    public:
    495     // Counter for generating next break id.
    496     int break_count_;
    497 
    498     // Current break id.
    499     int break_id_;
    500 
    501     // Frame id for the frame of the current break.
    502     StackFrame::Id break_frame_id_;
    503 
    504     // Step action for last step performed.
    505     StepAction last_step_action_;
    506 
    507     // Source statement position from last step next action.
    508     int last_statement_position_;
    509 
    510     // Number of steps left to perform before debug event.
    511     int step_count_;
    512 
    513     // Frame pointer from last step next action.
    514     Address last_fp_;
    515 
    516     // Number of queued steps left to perform before debug event.
    517     int queued_step_count_;
    518 
    519     // Frame pointer for frame from which step in was performed.
    520     Address step_into_fp_;
    521 
    522     // Frame pointer for the frame where debugger should be called when current
    523     // step out action is completed.
    524     Address step_out_fp_;
    525 
    526     // Storage location for jump when exiting debug break calls.
    527     Address after_break_target_;
    528 
    529     // Stores the way how LiveEdit has patched the stack. It is used when
    530     // debugger returns control back to user script.
    531     FrameDropMode frame_drop_mode_;
    532 
    533     // Top debugger entry.
    534     EnterDebugger* debugger_entry_;
    535 
    536     // Pending interrupts scheduled while debugging.
    537     int pending_interrupts_;
    538 
    539     // When restarter frame is on stack, stores the address
    540     // of the pointer to function being restarted. Otherwise (most of the time)
    541     // stores NULL. This pointer is used with 'step in' implementation.
    542     Object** restarter_frame_function_pointer_;
    543   };
    544 
    545   // Storage location for registers when handling debug break calls
    546   JSCallerSavedBuffer registers_;
    547   ThreadLocal thread_local_;
    548   void ThreadInit();
    549 
    550   // Code to call for handling debug break on return.
    551   Code* debug_break_return_;
    552 
    553   // Code to call for handling debug break in debug break slots.
    554   Code* debug_break_slot_;
    555 
    556   Isolate* isolate_;
    557 
    558   friend class Isolate;
    559 
    560   DISALLOW_COPY_AND_ASSIGN(Debug);
    561 };
    562 
    563 
    564 DECLARE_RUNTIME_FUNCTION(Object*, Debug_Break);
    565 
    566 
    567 // Message delivered to the message handler callback. This is either a debugger
    568 // event or the response to a command.
    569 class MessageImpl: public v8::Debug::Message {
    570  public:
    571   // Create a message object for a debug event.
    572   static MessageImpl NewEvent(DebugEvent event,
    573                               bool running,
    574                               Handle<JSObject> exec_state,
    575                               Handle<JSObject> event_data);
    576 
    577   // Create a message object for the response to a debug command.
    578   static MessageImpl NewResponse(DebugEvent event,
    579                                  bool running,
    580                                  Handle<JSObject> exec_state,
    581                                  Handle<JSObject> event_data,
    582                                  Handle<String> response_json,
    583                                  v8::Debug::ClientData* client_data);
    584 
    585   // Implementation of interface v8::Debug::Message.
    586   virtual bool IsEvent() const;
    587   virtual bool IsResponse() const;
    588   virtual DebugEvent GetEvent() const;
    589   virtual bool WillStartRunning() const;
    590   virtual v8::Handle<v8::Object> GetExecutionState() const;
    591   virtual v8::Handle<v8::Object> GetEventData() const;
    592   virtual v8::Handle<v8::String> GetJSON() const;
    593   virtual v8::Handle<v8::Context> GetEventContext() const;
    594   virtual v8::Debug::ClientData* GetClientData() const;
    595 
    596  private:
    597   MessageImpl(bool is_event,
    598               DebugEvent event,
    599               bool running,
    600               Handle<JSObject> exec_state,
    601               Handle<JSObject> event_data,
    602               Handle<String> response_json,
    603               v8::Debug::ClientData* client_data);
    604 
    605   bool is_event_;  // Does this message represent a debug event?
    606   DebugEvent event_;  // Debug event causing the break.
    607   bool running_;  // Will the VM start running after this event?
    608   Handle<JSObject> exec_state_;  // Current execution state.
    609   Handle<JSObject> event_data_;  // Data associated with the event.
    610   Handle<String> response_json_;  // Response JSON if message holds a response.
    611   v8::Debug::ClientData* client_data_;  // Client data passed with the request.
    612 };
    613 
    614 
    615 // Details of the debug event delivered to the debug event listener.
    616 class EventDetailsImpl : public v8::Debug::EventDetails {
    617  public:
    618   EventDetailsImpl(DebugEvent event,
    619                    Handle<JSObject> exec_state,
    620                    Handle<JSObject> event_data,
    621                    Handle<Object> callback_data,
    622                    v8::Debug::ClientData* client_data);
    623   virtual DebugEvent GetEvent() const;
    624   virtual v8::Handle<v8::Object> GetExecutionState() const;
    625   virtual v8::Handle<v8::Object> GetEventData() const;
    626   virtual v8::Handle<v8::Context> GetEventContext() const;
    627   virtual v8::Handle<v8::Value> GetCallbackData() const;
    628   virtual v8::Debug::ClientData* GetClientData() const;
    629  private:
    630   DebugEvent event_;  // Debug event causing the break.
    631   Handle<JSObject> exec_state_;         // Current execution state.
    632   Handle<JSObject> event_data_;         // Data associated with the event.
    633   Handle<Object> callback_data_;        // User data passed with the callback
    634                                         // when it was registered.
    635   v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand.
    636 };
    637 
    638 
    639 // Message send by user to v8 debugger or debugger output message.
    640 // In addition to command text it may contain a pointer to some user data
    641 // which are expected to be passed along with the command reponse to message
    642 // handler.
    643 class CommandMessage {
    644  public:
    645   static CommandMessage New(const Vector<uint16_t>& command,
    646                             v8::Debug::ClientData* data);
    647   CommandMessage();
    648   ~CommandMessage();
    649 
    650   // Deletes user data and disposes of the text.
    651   void Dispose();
    652   Vector<uint16_t> text() const { return text_; }
    653   v8::Debug::ClientData* client_data() const { return client_data_; }
    654  private:
    655   CommandMessage(const Vector<uint16_t>& text,
    656                  v8::Debug::ClientData* data);
    657 
    658   Vector<uint16_t> text_;
    659   v8::Debug::ClientData* client_data_;
    660 };
    661 
    662 // A Queue of CommandMessage objects.  A thread-safe version is
    663 // LockingCommandMessageQueue, based on this class.
    664 class CommandMessageQueue BASE_EMBEDDED {
    665  public:
    666   explicit CommandMessageQueue(int size);
    667   ~CommandMessageQueue();
    668   bool IsEmpty() const { return start_ == end_; }
    669   CommandMessage Get();
    670   void Put(const CommandMessage& message);
    671   void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear().
    672  private:
    673   // Doubles the size of the message queue, and copies the messages.
    674   void Expand();
    675 
    676   CommandMessage* messages_;
    677   int start_;
    678   int end_;
    679   int size_;  // The size of the queue buffer.  Queue can hold size-1 messages.
    680 };
    681 
    682 
    683 class MessageDispatchHelperThread;
    684 
    685 
    686 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
    687 // messages.  The message data is not managed by LockingCommandMessageQueue.
    688 // Pointers to the data are passed in and out. Implemented by adding a
    689 // Mutex to CommandMessageQueue.  Includes logging of all puts and gets.
    690 class LockingCommandMessageQueue BASE_EMBEDDED {
    691  public:
    692   LockingCommandMessageQueue(Logger* logger, int size);
    693   ~LockingCommandMessageQueue();
    694   bool IsEmpty() const;
    695   CommandMessage Get();
    696   void Put(const CommandMessage& message);
    697   void Clear();
    698  private:
    699   Logger* logger_;
    700   CommandMessageQueue queue_;
    701   Mutex* lock_;
    702   DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
    703 };
    704 
    705 
    706 class Debugger {
    707  public:
    708   ~Debugger();
    709 
    710   void DebugRequest(const uint16_t* json_request, int length);
    711 
    712   Handle<Object> MakeJSObject(Vector<const char> constructor_name,
    713                               int argc,
    714                               Handle<Object> argv[],
    715                               bool* caught_exception);
    716   Handle<Object> MakeExecutionState(bool* caught_exception);
    717   Handle<Object> MakeBreakEvent(Handle<Object> exec_state,
    718                                 Handle<Object> break_points_hit,
    719                                 bool* caught_exception);
    720   Handle<Object> MakeExceptionEvent(Handle<Object> exec_state,
    721                                     Handle<Object> exception,
    722                                     bool uncaught,
    723                                     bool* caught_exception);
    724   Handle<Object> MakeNewFunctionEvent(Handle<Object> func,
    725                                       bool* caught_exception);
    726   Handle<Object> MakeCompileEvent(Handle<Script> script,
    727                                   bool before,
    728                                   bool* caught_exception);
    729   Handle<Object> MakeScriptCollectedEvent(int id,
    730                                           bool* caught_exception);
    731   void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
    732   void OnException(Handle<Object> exception, bool uncaught);
    733   void OnBeforeCompile(Handle<Script> script);
    734 
    735   enum AfterCompileFlags {
    736     NO_AFTER_COMPILE_FLAGS,
    737     SEND_WHEN_DEBUGGING
    738   };
    739   void OnAfterCompile(Handle<Script> script,
    740                       AfterCompileFlags after_compile_flags);
    741   void OnNewFunction(Handle<JSFunction> fun);
    742   void OnScriptCollected(int id);
    743   void ProcessDebugEvent(v8::DebugEvent event,
    744                          Handle<JSObject> event_data,
    745                          bool auto_continue);
    746   void NotifyMessageHandler(v8::DebugEvent event,
    747                             Handle<JSObject> exec_state,
    748                             Handle<JSObject> event_data,
    749                             bool auto_continue);
    750   void SetEventListener(Handle<Object> callback, Handle<Object> data);
    751   void SetMessageHandler(v8::Debug::MessageHandler2 handler);
    752   void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
    753                               int period);
    754   void SetDebugMessageDispatchHandler(
    755       v8::Debug::DebugMessageDispatchHandler handler,
    756       bool provide_locker);
    757 
    758   // Invoke the message handler function.
    759   void InvokeMessageHandler(MessageImpl message);
    760 
    761   // Add a debugger command to the command queue.
    762   void ProcessCommand(Vector<const uint16_t> command,
    763                       v8::Debug::ClientData* client_data = NULL);
    764 
    765   // Check whether there are commands in the command queue.
    766   bool HasCommands();
    767 
    768   // Enqueue a debugger command to the command queue for event listeners.
    769   void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
    770 
    771   Handle<Object> Call(Handle<JSFunction> fun,
    772                       Handle<Object> data,
    773                       bool* pending_exception);
    774 
    775   // Start the debugger agent listening on the provided port.
    776   bool StartAgent(const char* name, int port,
    777                   bool wait_for_connection = false);
    778 
    779   // Stop the debugger agent.
    780   void StopAgent();
    781 
    782   // Blocks until the agent has started listening for connections
    783   void WaitForAgent();
    784 
    785   void CallMessageDispatchHandler();
    786 
    787   Handle<Context> GetDebugContext();
    788 
    789   // Unload the debugger if possible. Only called when no debugger is currently
    790   // active.
    791   void UnloadDebugger();
    792   friend void ForceUnloadDebugger();  // In test-debug.cc
    793 
    794   inline bool EventActive(v8::DebugEvent event) {
    795     ScopedLock with(debugger_access_);
    796 
    797     // Check whether the message handler was been cleared.
    798     if (debugger_unload_pending_) {
    799       if (isolate_->debug()->debugger_entry() == NULL) {
    800         UnloadDebugger();
    801       }
    802     }
    803 
    804     if (((event == v8::BeforeCompile) || (event == v8::AfterCompile)) &&
    805         !FLAG_debug_compile_events) {
    806       return false;
    807 
    808     } else if ((event == v8::ScriptCollected) &&
    809                !FLAG_debug_script_collected_events) {
    810       return false;
    811     }
    812 
    813     // Currently argument event is not used.
    814     return !compiling_natives_ && Debugger::IsDebuggerActive();
    815   }
    816 
    817   void set_compiling_natives(bool compiling_natives) {
    818     compiling_natives_ = compiling_natives;
    819   }
    820   bool compiling_natives() const { return compiling_natives_; }
    821   void set_loading_debugger(bool v) { is_loading_debugger_ = v; }
    822   bool is_loading_debugger() const { return is_loading_debugger_; }
    823   void set_force_debugger_active(bool force_debugger_active) {
    824     force_debugger_active_ = force_debugger_active;
    825   }
    826   bool force_debugger_active() const { return force_debugger_active_; }
    827 
    828   bool IsDebuggerActive();
    829 
    830  private:
    831   explicit Debugger(Isolate* isolate);
    832 
    833   void CallEventCallback(v8::DebugEvent event,
    834                          Handle<Object> exec_state,
    835                          Handle<Object> event_data,
    836                          v8::Debug::ClientData* client_data);
    837   void CallCEventCallback(v8::DebugEvent event,
    838                           Handle<Object> exec_state,
    839                           Handle<Object> event_data,
    840                           v8::Debug::ClientData* client_data);
    841   void CallJSEventCallback(v8::DebugEvent event,
    842                            Handle<Object> exec_state,
    843                            Handle<Object> event_data);
    844   void ListenersChanged();
    845 
    846   Mutex* debugger_access_;  // Mutex guarding debugger variables.
    847   Handle<Object> event_listener_;  // Global handle to listener.
    848   Handle<Object> event_listener_data_;
    849   bool compiling_natives_;  // Are we compiling natives?
    850   bool is_loading_debugger_;  // Are we loading the debugger?
    851   bool never_unload_debugger_;  // Can we unload the debugger?
    852   bool force_debugger_active_;  // Activate debugger without event listeners.
    853   v8::Debug::MessageHandler2 message_handler_;
    854   bool debugger_unload_pending_;  // Was message handler cleared?
    855   v8::Debug::HostDispatchHandler host_dispatch_handler_;
    856   Mutex* dispatch_handler_access_;  // Mutex guarding dispatch handler.
    857   v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_;
    858   MessageDispatchHelperThread* message_dispatch_helper_thread_;
    859   int host_dispatch_micros_;
    860 
    861   DebuggerAgent* agent_;
    862 
    863   static const int kQueueInitialSize = 4;
    864   LockingCommandMessageQueue command_queue_;
    865   Semaphore* command_received_;  // Signaled for each command received.
    866   LockingCommandMessageQueue event_command_queue_;
    867 
    868   Isolate* isolate_;
    869 
    870   friend class EnterDebugger;
    871   friend class Isolate;
    872 
    873   DISALLOW_COPY_AND_ASSIGN(Debugger);
    874 };
    875 
    876 
    877 // This class is used for entering the debugger. Create an instance in the stack
    878 // to enter the debugger. This will set the current break state, make sure the
    879 // debugger is loaded and switch to the debugger context. If the debugger for
    880 // some reason could not be entered FailedToEnter will return true.
    881 class EnterDebugger BASE_EMBEDDED {
    882  public:
    883   EnterDebugger();
    884   ~EnterDebugger();
    885 
    886   // Check whether the debugger could be entered.
    887   inline bool FailedToEnter() { return load_failed_; }
    888 
    889   // Check whether there are any JavaScript frames on the stack.
    890   inline bool HasJavaScriptFrames() { return has_js_frames_; }
    891 
    892   // Get the active context from before entering the debugger.
    893   inline Handle<Context> GetContext() { return save_.context(); }
    894 
    895  private:
    896   Isolate* isolate_;
    897   EnterDebugger* prev_;  // Previous debugger entry if entered recursively.
    898   JavaScriptFrameIterator it_;
    899   const bool has_js_frames_;  // Were there any JavaScript frames?
    900   StackFrame::Id break_frame_id_;  // Previous break frame id.
    901   int break_id_;  // Previous break id.
    902   bool load_failed_;  // Did the debugger fail to load?
    903   SaveContext save_;  // Saves previous context.
    904 };
    905 
    906 
    907 // Stack allocated class for disabling break.
    908 class DisableBreak BASE_EMBEDDED {
    909  public:
    910   explicit DisableBreak(bool disable_break) : isolate_(Isolate::Current()) {
    911     prev_disable_break_ = isolate_->debug()->disable_break();
    912     isolate_->debug()->set_disable_break(disable_break);
    913   }
    914   ~DisableBreak() {
    915     ASSERT(Isolate::Current() == isolate_);
    916     isolate_->debug()->set_disable_break(prev_disable_break_);
    917   }
    918 
    919  private:
    920   Isolate* isolate_;
    921   // The previous state of the disable break used to restore the value when this
    922   // object is destructed.
    923   bool prev_disable_break_;
    924 };
    925 
    926 
    927 // Debug_Address encapsulates the Address pointers used in generating debug
    928 // code.
    929 class Debug_Address {
    930  public:
    931   explicit Debug_Address(Debug::AddressId id) : id_(id) { }
    932 
    933   static Debug_Address AfterBreakTarget() {
    934     return Debug_Address(Debug::k_after_break_target_address);
    935   }
    936 
    937   static Debug_Address DebugBreakReturn() {
    938     return Debug_Address(Debug::k_debug_break_return_address);
    939   }
    940 
    941   static Debug_Address RestarterFrameFunctionPointer() {
    942     return Debug_Address(Debug::k_restarter_frame_function_pointer);
    943   }
    944 
    945   Address address(Isolate* isolate) const {
    946     Debug* debug = isolate->debug();
    947     switch (id_) {
    948       case Debug::k_after_break_target_address:
    949         return reinterpret_cast<Address>(debug->after_break_target_address());
    950       case Debug::k_debug_break_return_address:
    951         return reinterpret_cast<Address>(debug->debug_break_return_address());
    952       case Debug::k_debug_break_slot_address:
    953         return reinterpret_cast<Address>(debug->debug_break_slot_address());
    954       case Debug::k_restarter_frame_function_pointer:
    955         return reinterpret_cast<Address>(
    956             debug->restarter_frame_function_pointer_address());
    957       default:
    958         UNREACHABLE();
    959         return NULL;
    960     }
    961   }
    962 
    963  private:
    964   Debug::AddressId id_;
    965 };
    966 
    967 // The optional thread that Debug Agent may use to temporary call V8 to process
    968 // pending debug requests if debuggee is not running V8 at the moment.
    969 // Techincally it does not call V8 itself, rather it asks embedding program
    970 // to do this via v8::Debug::HostDispatchHandler
    971 class MessageDispatchHelperThread: public Thread {
    972  public:
    973   explicit MessageDispatchHelperThread(Isolate* isolate);
    974   ~MessageDispatchHelperThread();
    975 
    976   void Schedule();
    977 
    978  private:
    979   void Run();
    980 
    981   Semaphore* const sem_;
    982   Mutex* const mutex_;
    983   bool already_signalled_;
    984 
    985   DISALLOW_COPY_AND_ASSIGN(MessageDispatchHelperThread);
    986 };
    987 
    988 
    989 } }  // namespace v8::internal
    990 
    991 #endif  // ENABLE_DEBUGGER_SUPPORT
    992 
    993 #endif  // V8_DEBUG_H_
    994