Chromium Code Reviews| Index: runtime/bin/dbg_message.cc |
| =================================================================== |
| --- runtime/bin/dbg_message.cc (revision 13208) |
| +++ runtime/bin/dbg_message.cc (working copy) |
| @@ -796,7 +796,7 @@ |
| } |
| -void DbgMessageQueue::AddMessage(int32_t cmd_idx, |
| +void DbgMsgQueue::AddMessage(int32_t cmd_idx, |
| const char* start, |
|
hausner
2012/10/05 18:06:34
Indentation
siva
2012/10/05 22:35:06
Done.
|
| const char* end, |
| int debug_fd) { |
| @@ -817,7 +817,7 @@ |
| } |
| -void DbgMessageQueue::HandleMessages() { |
| +void DbgMsgQueue::HandleMessages() { |
| bool resume_requested = false; |
| MonitorLocker ml(&msg_queue_lock_); |
| is_running_ = false; |
| @@ -838,16 +838,28 @@ |
| msglist_tail_ = NULL; |
| } |
| } |
| + is_interrupted_ = false; |
| is_running_ = true; |
| } |
| -void DbgMessageQueue::QueueOutputMsg(dart::TextBuffer* msg) { |
| +void DbgMsgQueue::InterruptIsolate() { |
| + Dart_Isolate isolate = Dart_GetIsolate(isolate_id_); |
| + ASSERT(DbgMsgQueueList::GetIsolateMsgQueue(isolate_id_) == this); |
| + MonitorLocker ml(&msg_queue_lock_); |
| + if (is_running_ && !is_interrupted_) { |
| + is_interrupted_ = true; |
| + Dart_InterruptIsolate(isolate); |
| + } |
| +} |
| + |
| + |
| +void DbgMsgQueue::QueueOutputMsg(dart::TextBuffer* msg) { |
| queued_output_messages_.Printf("%s", msg->buf()); |
| } |
| -void DbgMessageQueue::SendQueuedMsgs() { |
| +void DbgMsgQueue::SendQueuedMsgs() { |
| if (queued_output_messages_.length() > 0) { |
| DebuggerConnectionHandler::BroadcastMsg(&queued_output_messages_); |
| queued_output_messages_.Clear(); |
| @@ -855,23 +867,25 @@ |
| } |
| -void DbgMessageQueue::SendBreakpointEvent(Dart_StackTrace trace) { |
| +void DbgMsgQueue::SendBreakpointEvent(Dart_StackTrace trace) { |
| dart::TextBuffer msg(128); |
| msg.Printf("{ \"event\": \"paused\", \"params\": { "); |
| msg.Printf("\"reason\": \"breakpoint\", "); |
| + msg.Printf("\"id\": %"Pd64", ", isolate_id_); |
| FormatCallFrames(&msg, trace); |
| msg.Printf("}}"); |
| DebuggerConnectionHandler::BroadcastMsg(&msg); |
| } |
| -void DbgMessageQueue::SendExceptionEvent(Dart_Handle exception, |
| - Dart_StackTrace stack_trace) { |
| +void DbgMsgQueue::SendExceptionEvent(Dart_Handle exception, |
| + Dart_StackTrace stack_trace) { |
| intptr_t exception_id = Dart_CacheObject(exception); |
| ASSERT(exception_id >= 0); |
| dart::TextBuffer msg(128); |
| msg.Printf("{ \"event\": \"paused\", \"params\": {"); |
| msg.Printf("\"reason\": \"exception\", "); |
| + msg.Printf("\"id\": %"Pd64", ", isolate_id_); |
| msg.Printf("\"exception\":"); |
| FormatRemoteObj(&msg, exception); |
| msg.Printf(", "); |
| @@ -881,17 +895,38 @@ |
| } |
| -// TODO(asiva): Get rid of this static variable one we have a means |
| -// for associating an isolate with a debugger message queue object. |
| -static DbgMessageQueue* message_queue = NULL; |
| +void DbgMsgQueue::SendIsolateEvent(Dart_IsolateId isolate_id, |
| + Dart_IsolateEvent kind) { |
| + dart::TextBuffer msg(128); |
| + if (kind == kInterrupted) { |
| + Dart_StackTrace trace; |
| + Dart_Handle res = Dart_GetStackTrace(&trace); |
| + ASSERT_NOT_ERROR(res); |
| + msg.Printf("{ \"event\": \"paused\", \"params\": { "); |
| + msg.Printf("\"reason\": \"interrupted\", "); |
| + msg.Printf("\"id\": %"Pd64", ", isolate_id); |
| + FormatCallFrames(&msg, trace); |
| + msg.Printf("}}"); |
| + } else { |
| + msg.Printf("{ \"event\": \"isolate\", \"params\": { "); |
| + if (kind == kCreated) { |
| + msg.Printf("\"reason\": \"created\", "); |
| + } else { |
| + ASSERT(kind == kShutdown); |
| + msg.Printf("\"reason\": \"shutdown\", "); |
| + } |
| + msg.Printf("\"id\": %"Pd64" ", isolate_id); |
| + msg.Printf("}}"); |
| + } |
| + DebuggerConnectionHandler::BroadcastMsg(&msg); |
| +} |
| -void DbgMessageQueue::Initialize() { |
| - // TODO(asiva): Need to setup a message queue when an Isolate is created. |
| - // For now we use a static message queue object as we are only supporting |
| - // debugging of a single isolate. |
| - message_queue = new DbgMessageQueue(); |
| +DbgMsgQueue* DbgMsgQueueList::list_ = NULL; |
| +dart::Mutex DbgMsgQueueList::msg_queue_list_lock_; |
| + |
| +void DbgMsgQueueList::Initialize() { |
| // Setup handlers for isolate events, breakpoints, exceptions and |
| // delayed breakpoints. |
| Dart_SetIsolateEventHandler(IsolateEventHandler); |
| @@ -901,7 +936,7 @@ |
| } |
| -int32_t DbgMessageQueue::LookupIsolateCommand(const char* buf, |
| +int32_t DbgMsgQueueList::LookupIsolateCommand(const char* buf, |
| int32_t buflen) { |
| // Check if we have a isolate specific debugger command. |
| int32_t i = 0; |
| @@ -915,35 +950,89 @@ |
| } |
| -DbgMessageQueue* DbgMessageQueue::GetIsolateMessageQueue(Dart_Isolate isolate) { |
| - // TODO(asiva): Return a message queue corresponding to the isolate. |
| - // For now we use a static message queue object as we are only supporting |
| +DbgMsgQueue* DbgMsgQueueList::AddIsolateMsgQueue(Dart_IsolateId isolate_id) { |
| + MutexLocker ml(&msg_queue_list_lock_); |
| + |
| + DbgMsgQueue* queue = new DbgMsgQueue(isolate_id, list_); |
| + ASSERT(queue != NULL); |
| + list_ = queue; |
| + return queue; |
| +} |
| + |
| + |
| +DbgMsgQueue* DbgMsgQueueList::GetIsolateMsgQueue(Dart_IsolateId isolate_id) { |
| + MutexLocker ml(&msg_queue_list_lock_); |
| + |
| + if (list_ == NULL) { |
| + return NULL; // No items in the list. |
| + } |
| + |
| + // TODO(asiva): Remove once debug wire protocol has isolate id. |
| + // For now we return the first item in the list as we are only supporting |
| // debugging of a single isolate. |
| - return message_queue; |
| + if (isolate_id == ILLEGAL_ISOLATE_ID) { |
| + return list_; |
| + } |
| + |
| + // Find message queue corresponding to isolate id. |
| + DbgMsgQueue* iterator = list_; |
| + while (iterator != NULL && iterator->isolate_id() != isolate_id) { |
| + iterator = iterator->next(); |
| + } |
| + return iterator; |
| } |
| -void DbgMessageQueue::BptResolvedHandler(intptr_t bp_id, |
| +void DbgMsgQueueList::RemoveIsolateMsgQueue(Dart_IsolateId isolate_id) { |
| + MutexLocker ml(&msg_queue_list_lock_); |
| + if (list_ == NULL) { |
| + return; // No items in the list. |
| + } |
| + DbgMsgQueue* queue = list_; |
| + if (queue->isolate_id() == isolate_id) { |
| + list_ = queue->next(); // Remove from list. |
| + delete queue; // Delete the message queue. |
| + } else { |
| + DbgMsgQueue* iterator = queue; |
| + queue = queue->next(); |
| + while (queue != NULL) { |
| + if (queue->isolate_id() != isolate_id) { |
| + iterator->set_next(queue->next()); // Remove from list. |
| + delete queue; // Delete the message queue. |
| + break; |
| + } |
| + iterator = queue; |
| + queue = queue->next(); |
| + } |
| + } |
| +} |
| + |
| + |
| +void DbgMsgQueueList::BptResolvedHandler(Dart_IsolateId isolate_id, |
| + intptr_t bp_id, |
| Dart_Handle url, |
| intptr_t line_number) { |
| + ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate()); |
| Dart_EnterScope(); |
| dart::TextBuffer msg(128); |
| msg.Printf("{ \"event\": \"breakpointResolved\", \"params\": {"); |
| msg.Printf("\"breakpointId\": %"Pd", \"url\":", bp_id); |
| FormatEncodedString(&msg, url); |
| msg.Printf(",\"line\": %"Pd" }}", line_number); |
| - DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate()); |
| + DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id); |
| ASSERT(msg_queue != NULL); |
| msg_queue->QueueOutputMsg(&msg); |
| Dart_ExitScope(); |
| } |
| -void DbgMessageQueue::BreakpointHandler(Dart_Breakpoint bpt, |
| +void DbgMsgQueueList::BreakpointHandler(Dart_IsolateId isolate_id, |
| + Dart_Breakpoint bpt, |
| Dart_StackTrace trace) { |
| + ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate()); |
| DebuggerConnectionHandler::WaitForConnection(); |
| Dart_EnterScope(); |
| - DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate()); |
| + DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id); |
| ASSERT(msg_queue != NULL); |
| msg_queue->SendQueuedMsgs(); |
| msg_queue->SendBreakpointEvent(trace); |
| @@ -952,11 +1041,13 @@ |
| } |
| -void DbgMessageQueue::ExceptionThrownHandler(Dart_Handle exception, |
| +void DbgMsgQueueList::ExceptionThrownHandler(Dart_IsolateId isolate_id, |
| + Dart_Handle exception, |
| Dart_StackTrace stack_trace) { |
| + ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate()); |
| DebuggerConnectionHandler::WaitForConnection(); |
| Dart_EnterScope(); |
| - DbgMessageQueue* msg_queue = GetIsolateMessageQueue(Dart_CurrentIsolate()); |
| + DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id); |
| ASSERT(msg_queue != NULL); |
| msg_queue->SendQueuedMsgs(); |
| msg_queue->SendExceptionEvent(exception, stack_trace); |
| @@ -965,8 +1056,25 @@ |
| } |
| -void DbgMessageQueue::IsolateEventHandler(Dart_IsolateId isolate_id, |
| +void DbgMsgQueueList::IsolateEventHandler(Dart_IsolateId isolate_id, |
| Dart_IsolateEvent kind) { |
| DebuggerConnectionHandler::WaitForConnection(); |
| - // TODO(asiva): Add code to send isolate events over to the debugger client. |
| + Dart_EnterScope(); |
| + if (kind == kCreated) { |
| + DbgMsgQueue* msg_queue = AddIsolateMsgQueue(isolate_id); |
| + msg_queue->SendIsolateEvent(isolate_id, kind); |
| + } else { |
| + ASSERT(Dart_GetIsolate(isolate_id) == Dart_CurrentIsolate()); |
| + DbgMsgQueue* msg_queue = GetIsolateMsgQueue(isolate_id); |
| + ASSERT(msg_queue != NULL); |
| + msg_queue->SendQueuedMsgs(); |
| + msg_queue->SendIsolateEvent(isolate_id, kind); |
| + if (kind == kInterrupted) { |
| + msg_queue->HandleMessages(); |
| + } else { |
| + ASSERT(kind == kShutdown); |
| + RemoveIsolateMsgQueue(isolate_id); |
| + } |
| + } |
| + Dart_ExitScope(); |
| } |