From 95288e916e4fed9ecf4a36d8db7da465484d3c98 Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Wed, 29 Apr 2009 08:23:58 +0000 Subject: [PATCH] Changed the debugger message API to receive an object instead of a JSON string. The object delivered to the debug message handler contains additional information on the current break handling the messages. Clients which require just JSON message parsing can simply get the JSON using the GetJSON message on the message object to still have the previous behaviour. NewMessageHangler(const v8::Debug::Message& message) { v8::String::Value val(message.GetJSON()); OldMessageHandler(Vector(const_cast(*val), val.length())); } Refactored some of the debugger code to use internal handles instead of API handles. Also changed Object to JSObject is some places. The access to the active context when the break occurred is still not implemented. I will add this in a new CL, as this one is quite big already. Review URL: http://codereview.chromium.org/99122 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1811 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8-debug.h | 65 +++++++++++--- src/debug-agent.cc | 12 +-- src/debug-agent.h | 5 +- src/debug.cc | 211 ++++++++++++++++++++++++++++++++-------------- src/debug.h | 60 +++++++++++-- test/cctest/test-debug.cc | 44 ++++------ 6 files changed, 280 insertions(+), 117 deletions(-) diff --git a/include/v8-debug.h b/include/v8-debug.h index 5235495..2b9b8a0 100644 --- a/include/v8-debug.h +++ b/include/v8-debug.h @@ -92,6 +92,55 @@ class EXPORT Debug { /** + * A message object passed to the debug message handler. + */ + class Message { + public: + /** + * Check type of message. + */ + virtual bool IsEvent() const = 0; + virtual bool IsResponse() const = 0; + virtual DebugEvent GetEvent() const = 0; + + /** + * Indicate whether this is a response to a continue command which will + * start the VM running after this is processed. + */ + virtual bool WillStartRunning() const = 0; + + /** + * Access to execution state and event data. Don't store these cross + * callbacks as their content becomes invalid. These objects are from the + * debugger event that started the debug message loop. + */ + virtual Handle GetExecutionState() const = 0; + virtual Handle GetEventData() const = 0; + + /** + * Get the debugger protocol JSON. + */ + virtual Handle GetJSON() const = 0; + + /** + * Get the context active when the debug event happened. Note this is not + * the current active context as the JavaScript part of the debugger is + * running in it's own context which is entered at this point. + */ + virtual Handle GetEventContext() const = 0; + + /** + * Client data passed with the corresponding request if any. This is the + * client_data data value passed into Debug::SendCommand along with the + * request that led to the message or NULL if the message is an event. The + * debugger takes ownership of the data and will delete it even if there is + * no message handler. + */ + virtual ClientData* GetClientData() const = 0; + }; + + + /** * Debug event callback function. * * \param event the type of the debug event that triggered the callback @@ -101,26 +150,22 @@ class EXPORT Debug { * \param data value passed by the user to SetDebugEventListener */ typedef void (*EventCallback)(DebugEvent event, - Handle exec_state, - Handle event_data, - Handle data); + Handle exec_state, + Handle event_data, + Handle data); /** * Debug message callback function. * - * \param message the debug message + * \param message the debug message handler message object * \param length length of the message * \param data the data value passed when registering the message handler - * \param client_data the data value passed into Debug::SendCommand along - * with the request that led to the message or NULL if the message is an - * asynchronous event. The debugger takes ownership of the data and will - * delete it before dying even if there is no message handler. + * A MessageHandler does not take posession of the message string, * and must not rely on the data persisting after the handler returns. */ - typedef void (*MessageHandler)(const uint16_t* message, int length, - ClientData* client_data); + typedef void (*MessageHandler)(const Message& message); /** * Debug host dispatch callback function. diff --git a/src/debug-agent.cc b/src/debug-agent.cc index 0fab188..b80f5d1 100644 --- a/src/debug-agent.cc +++ b/src/debug-agent.cc @@ -34,9 +34,8 @@ namespace v8 { namespace internal { // Public V8 debugger API message handler function. This function just delegates // to the debugger agent through it's data parameter. -void DebuggerAgentMessageHandler(const uint16_t* message, int length, - v8::Debug::ClientData* client_data) { - DebuggerAgent::instance_->DebuggerMessage(message, length); +void DebuggerAgentMessageHandler(const v8::Debug::Message& message) { + DebuggerAgent::instance_->DebuggerMessage(message); } // static @@ -125,13 +124,14 @@ void DebuggerAgent::CloseSession() { } -void DebuggerAgent::DebuggerMessage(const uint16_t* message, int length) { +void DebuggerAgent::DebuggerMessage(const v8::Debug::Message& message) { ScopedLock with(session_access_); // Forward the message handling to the session. if (session_ != NULL) { - session_->DebuggerMessage(Vector(const_cast(message), - length)); + v8::String::Value val(message.GetJSON()); + session_->DebuggerMessage(Vector(const_cast(*val), + val.length())); } } diff --git a/src/debug-agent.h b/src/debug-agent.h index 08f1372..67504da 100644 --- a/src/debug-agent.h +++ b/src/debug-agent.h @@ -60,7 +60,7 @@ class DebuggerAgent: public Thread { private: void Run(); void CreateSession(Socket* socket); - void DebuggerMessage(const uint16_t* message, int length); + void DebuggerMessage(const v8::Debug::Message& message); void CloseSession(); void OnSessionClosed(DebuggerAgentSession* session); @@ -75,8 +75,7 @@ class DebuggerAgent: public Thread { static DebuggerAgent* instance_; friend class DebuggerAgentSession; - friend void DebuggerAgentMessageHandler(const uint16_t* message, int length, - v8::Debug::ClientData* client_data); + friend void DebuggerAgentMessageHandler(const v8::Debug::Message& message); DISALLOW_COPY_AND_ASSIGN(DebuggerAgent); }; diff --git a/src/debug.cc b/src/debug.cc index 50d8c80..487ba51 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -41,6 +41,8 @@ #include "stub-cache.h" #include "log.h" +#include "../include/v8-debug.h" + namespace v8 { namespace internal { #ifdef ENABLE_DEBUGGER_SUPPORT @@ -377,7 +379,9 @@ void BreakLocationIterator::SetDebugBreakAtIC() { // is set the patching performed by the runtime system will take place in // the code copy and will therefore have no effect on the running code // keeping it from using the inlined code. - if (code->is_keyed_load_stub()) KeyedLoadIC::ClearInlinedVersion(pc()); + if (code->is_keyed_load_stub() && KeyedLoadIC::HasInlinedVersion(pc())) { + KeyedLoadIC::ClearInlinedVersion(pc()); + } } } @@ -1552,8 +1556,8 @@ void Debugger::OnException(Handle exception, bool uncaught) { return; } - // Process debug event - ProcessDebugEvent(v8::Exception, event_data, false); + // Process debug event. + ProcessDebugEvent(v8::Exception, Handle::cast(event_data), false); // Return to continue execution from where the exception was thrown. } @@ -1584,8 +1588,10 @@ void Debugger::OnDebugBreak(Handle break_points_hit, return; } - // Process debug event - ProcessDebugEvent(v8::Break, event_data, auto_continue); + // Process debug event. + ProcessDebugEvent(v8::Break, + Handle::cast(event_data), + auto_continue); } @@ -1609,8 +1615,10 @@ void Debugger::OnBeforeCompile(Handle