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