| Index: src/debug/debug.h | 
| diff --git a/src/debug/debug.h b/src/debug/debug.h | 
| index 88fd6ecc8d6cc5f12b8f81ebcac6daacc60ce002..8d2f8d5974d9db3e8f6d32c09dca7a72beb88c66 100644 | 
| --- a/src/debug/debug.h | 
| +++ b/src/debug/debug.h | 
| @@ -240,6 +240,47 @@ class DebugInfoListNode { | 
| DebugInfoListNode* next_; | 
| }; | 
|  | 
| +// Message delivered to the message handler callback. This is either a debugger | 
| +// event or the response to a command. | 
| +class MessageImpl : public v8::Debug::Message { | 
| + public: | 
| +  // Create a message object for a debug event. | 
| +  static MessageImpl NewEvent(DebugEvent event, bool running, | 
| +                              Handle<JSObject> exec_state, | 
| +                              Handle<JSObject> event_data); | 
| + | 
| +  // Create a message object for the response to a debug command. | 
| +  static MessageImpl NewResponse(DebugEvent event, bool running, | 
| +                                 Handle<JSObject> exec_state, | 
| +                                 Handle<JSObject> event_data, | 
| +                                 Handle<String> response_json, | 
| +                                 v8::Debug::ClientData* client_data); | 
| + | 
| +  // Implementation of interface v8::Debug::Message. | 
| +  virtual bool IsEvent() const; | 
| +  virtual bool IsResponse() const; | 
| +  virtual DebugEvent GetEvent() const; | 
| +  virtual bool WillStartRunning() const; | 
| +  virtual v8::Local<v8::Object> GetExecutionState() const; | 
| +  virtual v8::Local<v8::Object> GetEventData() const; | 
| +  virtual v8::Local<v8::String> GetJSON() const; | 
| +  virtual v8::Local<v8::Context> GetEventContext() const; | 
| +  virtual v8::Debug::ClientData* GetClientData() const; | 
| +  virtual v8::Isolate* GetIsolate() const; | 
| + | 
| + private: | 
| +  MessageImpl(bool is_event, DebugEvent event, bool running, | 
| +              Handle<JSObject> exec_state, Handle<JSObject> event_data, | 
| +              Handle<String> response_json, v8::Debug::ClientData* client_data); | 
| + | 
| +  bool is_event_;                 // Does this message represent a debug event? | 
| +  DebugEvent event_;              // Debug event causing the break. | 
| +  bool running_;                  // Will the VM start running after this event? | 
| +  Handle<JSObject> exec_state_;   // Current execution state. | 
| +  Handle<JSObject> event_data_;   // Data associated with the event. | 
| +  Handle<String> response_json_;  // Response JSON if message holds a response. | 
| +  v8::Debug::ClientData* client_data_;  // Client data passed with the request. | 
| +}; | 
|  | 
| // Details of the debug event delivered to the debug event listener. | 
| class EventDetailsImpl : public v8::DebugInterface::EventDetails { | 
| @@ -266,6 +307,67 @@ class EventDetailsImpl : public v8::DebugInterface::EventDetails { | 
| v8::Debug::ClientData* client_data_;  // Data passed to DebugBreakForCommand. | 
| }; | 
|  | 
| +// Message send by user to v8 debugger or debugger output message. | 
| +// In addition to command text it may contain a pointer to some user data | 
| +// which are expected to be passed along with the command reponse to message | 
| +// handler. | 
| +class CommandMessage { | 
| + public: | 
| +  static CommandMessage New(const Vector<uint16_t>& command, | 
| +                            v8::Debug::ClientData* data); | 
| +  CommandMessage(); | 
| + | 
| +  // Deletes user data and disposes of the text. | 
| +  void Dispose(); | 
| +  Vector<uint16_t> text() const { return text_; } | 
| +  v8::Debug::ClientData* client_data() const { return client_data_; } | 
| + | 
| + private: | 
| +  CommandMessage(const Vector<uint16_t>& text, v8::Debug::ClientData* data); | 
| + | 
| +  Vector<uint16_t> text_; | 
| +  v8::Debug::ClientData* client_data_; | 
| +}; | 
| + | 
| +// A Queue of CommandMessage objects.  A thread-safe version is | 
| +// LockingCommandMessageQueue, based on this class. | 
| +class CommandMessageQueue BASE_EMBEDDED { | 
| + public: | 
| +  explicit CommandMessageQueue(int size); | 
| +  ~CommandMessageQueue(); | 
| +  bool IsEmpty() const { return start_ == end_; } | 
| +  CommandMessage Get(); | 
| +  void Put(const CommandMessage& message); | 
| +  void Clear() { start_ = end_ = 0; }  // Queue is empty after Clear(). | 
| + | 
| + private: | 
| +  // Doubles the size of the message queue, and copies the messages. | 
| +  void Expand(); | 
| + | 
| +  CommandMessage* messages_; | 
| +  int start_; | 
| +  int end_; | 
| +  int size_;  // The size of the queue buffer.  Queue can hold size-1 messages. | 
| +}; | 
| + | 
| +// LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage | 
| +// messages.  The message data is not managed by LockingCommandMessageQueue. | 
| +// Pointers to the data are passed in and out. Implemented by adding a | 
| +// Mutex to CommandMessageQueue.  Includes logging of all puts and gets. | 
| +class LockingCommandMessageQueue BASE_EMBEDDED { | 
| + public: | 
| +  LockingCommandMessageQueue(Logger* logger, int size); | 
| +  bool IsEmpty() const; | 
| +  CommandMessage Get(); | 
| +  void Put(const CommandMessage& message); | 
| +  void Clear(); | 
| + | 
| + private: | 
| +  Logger* logger_; | 
| +  CommandMessageQueue queue_; | 
| +  mutable base::Mutex mutex_; | 
| +  DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); | 
| +}; | 
|  | 
| class DebugFeatureTracker { | 
| public: | 
| @@ -299,11 +401,12 @@ class DebugFeatureTracker { | 
| class Debug { | 
| public: | 
| // Debug event triggers. | 
| -  void OnDebugBreak(Handle<Object> break_points_hit); | 
| +  void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); | 
|  | 
| void OnThrow(Handle<Object> exception); | 
| void OnPromiseReject(Handle<Object> promise, Handle<Object> value); | 
| void OnCompileError(Handle<Script> script); | 
| +  void OnBeforeCompile(Handle<Script> script); | 
| void OnAfterCompile(Handle<Script> script); | 
| void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, | 
| Handle<String> name); | 
| @@ -311,11 +414,13 @@ class Debug { | 
| // API facing. | 
| void SetEventListener(Handle<Object> callback, Handle<Object> data); | 
| void SetMessageHandler(v8::Debug::MessageHandler handler); | 
| +  void EnqueueCommandMessage(Vector<const uint16_t> command, | 
| +                             v8::Debug::ClientData* client_data = NULL); | 
| MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, | 
| Handle<Object> data); | 
| Handle<Context> GetDebugContext(); | 
| void HandleDebugBreak(); | 
| -  void ProcessDebugMessages(); | 
| +  void ProcessDebugMessages(bool debug_command_only); | 
|  | 
| // Internal logic | 
| bool Load(); | 
| @@ -454,6 +559,7 @@ class Debug { | 
| } | 
|  | 
| // Check whether there are commands in the command queue. | 
| +  inline bool has_commands() const { return !command_queue_.IsEmpty(); } | 
| inline bool ignore_events() const { return is_suppressed_ || !is_active_; } | 
| inline bool break_disabled() const { | 
| return break_disabled_ || in_debug_event_listener_; | 
| @@ -491,7 +597,11 @@ class Debug { | 
| Handle<Object> event_data, | 
| v8::Debug::ClientData* client_data); | 
| void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); | 
| -  void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); | 
| +  void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, | 
| +                         bool auto_continue); | 
| +  void NotifyMessageHandler(v8::DebugEvent event, Handle<JSObject> exec_state, | 
| +                            Handle<JSObject> event_data, bool auto_continue); | 
| +  void InvokeMessageHandler(MessageImpl message); | 
|  | 
| // Find the closest source position for a break point for a given position. | 
| int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, | 
| @@ -534,6 +644,10 @@ class Debug { | 
|  | 
| v8::Debug::MessageHandler message_handler_; | 
|  | 
| +  static const int kQueueInitialSize = 4; | 
| +  base::Semaphore command_received_;  // Signaled for each command received. | 
| +  LockingCommandMessageQueue command_queue_; | 
| + | 
| bool is_active_; | 
| bool is_suppressed_; | 
| bool live_edit_enabled_; | 
|  |