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