| Index: src/debug.cc
|
| ===================================================================
|
| --- src/debug.cc (revision 1753)
|
| +++ src/debug.cc (working copy)
|
| @@ -1398,11 +1398,9 @@
|
| bool Debugger::is_loading_debugger_ = false;
|
| bool Debugger::never_unload_debugger_ = false;
|
| DebugMessageThread* Debugger::message_thread_ = NULL;
|
| -v8::DebugMessageHandler Debugger::message_handler_ = NULL;
|
| +v8::Debug::MessageHandler Debugger::message_handler_ = NULL;
|
| bool Debugger::message_handler_cleared_ = false;
|
| -void* Debugger::message_handler_data_ = NULL;
|
| -v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
|
| -void* Debugger::host_dispatch_handler_data_ = NULL;
|
| +v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
|
| DebuggerAgent* Debugger::agent_ = NULL;
|
| LockingMessageQueue Debugger::command_queue_(kQueueInitialSize);
|
| LockingMessageQueue Debugger::message_queue_(kQueueInitialSize);
|
| @@ -1704,8 +1702,8 @@
|
| if (event_listener_->IsProxy()) {
|
| // C debug event listener.
|
| Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
|
| - v8::DebugEventCallback callback =
|
| - FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy());
|
| + v8::Debug::EventCallback callback =
|
| + FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy());
|
| callback(event,
|
| v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
|
| v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)),
|
| @@ -1813,18 +1811,20 @@
|
| StackGuard::Continue(DEBUGCOMMAND);
|
|
|
| // Get the command from the queue.
|
| - Vector<uint16_t> command = command_queue_.Get();
|
| + Message command = command_queue_.Get();
|
| Logger::DebugTag("Got request from command queue, in interactive loop.");
|
| if (!Debugger::IsDebuggerActive()) {
|
| + // Delete command text and user data.
|
| + command.Dispose();
|
| return;
|
| }
|
|
|
| // Check if the command is a host dispatch.
|
| - if (command[0] == 0) {
|
| + if (command.IsHostDispatch()) {
|
| if (Debugger::host_dispatch_handler_) {
|
| - int32_t dispatch = (command[1] << 16) | command[2];
|
| - Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch),
|
| - Debugger::host_dispatch_handler_data_);
|
| + Debugger::host_dispatch_handler_(command.client_data());
|
| + // Delete the dispatch.
|
| + command.Dispose();
|
| }
|
| if (auto_continue && !HasCommands()) {
|
| return;
|
| @@ -1839,8 +1839,10 @@
|
| v8::TryCatch try_catch;
|
| fun_name = v8::String::New("processDebugRequest");
|
| fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
|
| - request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),
|
| - command.length());
|
| +
|
| + request = v8::String::New(command.text().start(),
|
| + command.text().length());
|
| + command.text().Dispose();
|
| static const int kArgc = 1;
|
| v8::Handle<Value> argv[kArgc] = { request };
|
| v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
|
| @@ -1876,13 +1878,8 @@
|
| response = try_catch.Exception()->ToString();
|
| }
|
|
|
| - // Convert text result to C string.
|
| - v8::String::Value val(response);
|
| - Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
|
| - response->Length());
|
| -
|
| // Return the result.
|
| - SendMessage(str);
|
| + SendMessage(Message::NewOutput(response, command.client_data()));
|
|
|
| // Return from debug event processing if either the VM is put into the
|
| // runnning state (through a continue command) or auto continue is active
|
| @@ -1928,12 +1925,11 @@
|
| }
|
|
|
|
|
| -void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data,
|
| +void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler,
|
| bool message_handler_thread) {
|
| ScopedLock with(debugger_access_);
|
|
|
| message_handler_ = handler;
|
| - message_handler_data_ = data;
|
| if (handler != NULL) {
|
| if (!message_thread_ && message_handler_thread) {
|
| message_thread_ = new DebugMessageThread();
|
| @@ -1952,10 +1948,8 @@
|
| }
|
|
|
|
|
| -void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
|
| - void* data) {
|
| +void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler) {
|
| host_dispatch_handler_ = handler;
|
| - host_dispatch_handler_data_ = data;
|
| }
|
|
|
|
|
| @@ -1963,26 +1957,28 @@
|
| // public API. Messages are kept internally as Vector<uint16_t> strings, which
|
| // are allocated in various places and deallocated by the calling function
|
| // sometime after this call.
|
| -void Debugger::InvokeMessageHandler(Vector<uint16_t> message) {
|
| +void Debugger::InvokeMessageHandler(Message message) {
|
| ScopedLock with(debugger_access_);
|
|
|
| if (message_handler_ != NULL) {
|
| - message_handler_(message.start(), message.length(), message_handler_data_);
|
| + message_handler_(message.text().start(),
|
| + message.text().length(),
|
| + message.client_data());
|
| }
|
| + message.Dispose();
|
| }
|
|
|
|
|
| -void Debugger::SendMessage(Vector<uint16_t> message) {
|
| +void Debugger::SendMessage(Message message) {
|
| if (message_thread_ == NULL) {
|
| // If there is no message thread just invoke the message handler from the
|
| // V8 thread.
|
| InvokeMessageHandler(message);
|
| } else {
|
| - // Put a copy of the message coming from V8 on the queue. The new copy of
|
| - // the event string is destroyed by the message thread.
|
| - Vector<uint16_t> message_copy = message.Clone();
|
| + // Put the message coming from V8 on the queue. The text and user data will
|
| + // be destroyed by the message thread.
|
| Logger::DebugTag("Put message on event message_queue.");
|
| - message_queue_.Put(message_copy);
|
| + message_queue_.Put(message);
|
| message_received_->Signal();
|
| }
|
| }
|
| @@ -2005,12 +2001,11 @@
|
| if (FLAG_trace_debug_json) {
|
| PrintLn(json_event_string);
|
| }
|
| - v8::String::Value val(json_event_string);
|
| - Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
|
| - json_event_string->Length());
|
| - SendMessage(str);
|
| + SendMessage(Message::NewOutput(
|
| + json_event_string,
|
| + NULL /* no user data since there was no request */));
|
| } else {
|
| - SendMessage(Vector<uint16_t>::empty());
|
| + SendMessage(Message::NewEmptyMessage());
|
| }
|
| } else {
|
| PrintLn(try_catch.Exception());
|
| @@ -2026,13 +2021,15 @@
|
| // by the API client thread. This is where the API client hands off
|
| // processing of the command to the DebugMessageThread thread.
|
| // The new copy of the command is destroyed in HandleCommand().
|
| -void Debugger::ProcessCommand(Vector<const uint16_t> command) {
|
| - // Make a copy of the command. Need to cast away const for Clone to work.
|
| - Vector<uint16_t> command_copy =
|
| +void Debugger::ProcessCommand(Vector<const uint16_t> command,
|
| + v8::Debug::ClientData* client_data) {
|
| + // Need to cast away const.
|
| + Message message = Message::NewCommand(
|
| Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
|
| - command.length()).Clone();
|
| + command.length()),
|
| + client_data);
|
| Logger::DebugTag("Put command on command_queue.");
|
| - command_queue_.Put(command_copy);
|
| + command_queue_.Put(message);
|
| command_received_->Signal();
|
|
|
| // Set the debug command break flag to have the command processed.
|
| @@ -2047,14 +2044,10 @@
|
| }
|
|
|
|
|
| -void Debugger::ProcessHostDispatch(void* dispatch) {
|
| +void Debugger::ProcessHostDispatch(v8::Debug::ClientData* dispatch) {
|
| // Puts a host dispatch comming from the public API on the queue.
|
| - uint16_t hack[3];
|
| - hack[0] = 0;
|
| - hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16;
|
| - hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF;
|
| Logger::DebugTag("Put dispatch on command_queue.");
|
| - command_queue_.Put(Vector<uint16_t>(hack, 3).Clone());
|
| + command_queue_.Put(Message::NewHostDispatch(dispatch));
|
| command_received_->Signal();
|
|
|
| // Set the debug command break flag to have the host dispatch processed.
|
| @@ -2134,9 +2127,11 @@
|
| // Wait and Get are paired so that semaphore count equals queue length.
|
| Debugger::message_received_->Wait();
|
| Logger::DebugTag("Get message from event message_queue.");
|
| - Vector<uint16_t> message = Debugger::message_queue_.Get();
|
| - if (message.length() > 0) {
|
| + Message message = Debugger::message_queue_.Get();
|
| + if (message.text().length() > 0) {
|
| Debugger::InvokeMessageHandler(message);
|
| + } else {
|
| + message.Dispose();
|
| }
|
| }
|
| }
|
| @@ -2144,22 +2139,84 @@
|
|
|
| void DebugMessageThread::Stop() {
|
| keep_running_ = false;
|
| - Debugger::SendMessage(Vector<uint16_t>(NULL, 0));
|
| + Debugger::SendMessage(Message::NewEmptyMessage());
|
| Join();
|
| }
|
|
|
|
|
| +Message::Message() : text_(Vector<uint16_t>::empty()),
|
| + client_data_(NULL),
|
| + is_host_dispatch_(false) {
|
| +}
|
| +
|
| +
|
| +Message::Message(const Vector<uint16_t>& text,
|
| + v8::Debug::ClientData* data,
|
| + bool is_host_dispatch)
|
| + : text_(text),
|
| + client_data_(data),
|
| + is_host_dispatch_(is_host_dispatch) {
|
| +}
|
| +
|
| +
|
| +Message::~Message() {
|
| +}
|
| +
|
| +
|
| +void Message::Dispose() {
|
| + text_.Dispose();
|
| + delete client_data_;
|
| + client_data_ = NULL;
|
| +}
|
| +
|
| +
|
| +bool Message::IsHostDispatch() const {
|
| + return is_host_dispatch_;
|
| +}
|
| +
|
| +
|
| +Message Message::NewCommand(const Vector<uint16_t>& command,
|
| + v8::Debug::ClientData* data) {
|
| + return Message(command.Clone(), data, false);
|
| +}
|
| +
|
| +
|
| +Message Message::NewHostDispatch(v8::Debug::ClientData* dispatch) {
|
| + return Message(Vector<uint16_t>::empty(), dispatch, true);
|
| +}
|
| +
|
| +
|
| +Message Message::NewOutput(v8::Handle<v8::String> output,
|
| + v8::Debug::ClientData* data) {
|
| + Vector<uint16_t> text;
|
| + if (!output.IsEmpty()) {
|
| + text = Vector<uint16_t>::New(output->Length() + 1);
|
| + output->Write(text.start());
|
| + }
|
| + return Message(text, data, false);
|
| +}
|
| +
|
| +
|
| +Message Message::NewEmptyMessage() {
|
| + return Message();
|
| +}
|
| +
|
| +
|
| MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {
|
| - messages_ = NewArray<Vector<uint16_t> >(size);
|
| + messages_ = NewArray<Message>(size);
|
| }
|
|
|
|
|
| MessageQueue::~MessageQueue() {
|
| + while(!IsEmpty()) {
|
| + Message m = Get();
|
| + m.Dispose();
|
| + }
|
| DeleteArray(messages_);
|
| }
|
|
|
|
|
| -Vector<uint16_t> MessageQueue::Get() {
|
| +Message MessageQueue::Get() {
|
| ASSERT(!IsEmpty());
|
| int result = start_;
|
| start_ = (start_ + 1) % size_;
|
| @@ -2167,7 +2224,7 @@
|
| }
|
|
|
|
|
| -void MessageQueue::Put(const Vector<uint16_t>& message) {
|
| +void MessageQueue::Put(const Message& message) {
|
| if ((end_ + 1) % size_ == start_) {
|
| Expand();
|
| }
|
| @@ -2181,9 +2238,11 @@
|
| while (!IsEmpty()) {
|
| new_queue.Put(Get());
|
| }
|
| - Vector<uint16_t>* array_to_free = messages_;
|
| + Message* array_to_free = messages_;
|
| *this = new_queue;
|
| new_queue.messages_ = array_to_free;
|
| + // Make the new_queue empty so that it doesn't call Dispose on any messages.
|
| + new_queue.start_ = new_queue.end_;
|
| // Automatic destructor called on new_queue, freeing array_to_free.
|
| }
|
|
|
| @@ -2204,18 +2263,18 @@
|
| }
|
|
|
|
|
| -Vector<uint16_t> LockingMessageQueue::Get() {
|
| +Message LockingMessageQueue::Get() {
|
| ScopedLock sl(lock_);
|
| - Vector<uint16_t> result = queue_.Get();
|
| - Logger::DebugEvent("Get", result);
|
| + Message result = queue_.Get();
|
| + Logger::DebugEvent("Get", result.text());
|
| return result;
|
| }
|
|
|
|
|
| -void LockingMessageQueue::Put(const Vector<uint16_t>& message) {
|
| +void LockingMessageQueue::Put(const Message& message) {
|
| ScopedLock sl(lock_);
|
| queue_.Put(message);
|
| - Logger::DebugEvent("Put", message);
|
| + Logger::DebugEvent("Put", message.text());
|
| }
|
|
|
|
|
|
|