Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(600)

Side by Side Diff: src/debug.cc

Issue 67266: Accompany debugger commands with senders data (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/debug.h ('k') | src/debug-agent.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 } 1391 }
1392 1392
1393 1393
1394 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); 1394 Mutex* Debugger::debugger_access_ = OS::CreateMutex();
1395 Handle<Object> Debugger::event_listener_ = Handle<Object>(); 1395 Handle<Object> Debugger::event_listener_ = Handle<Object>();
1396 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); 1396 Handle<Object> Debugger::event_listener_data_ = Handle<Object>();
1397 bool Debugger::compiling_natives_ = false; 1397 bool Debugger::compiling_natives_ = false;
1398 bool Debugger::is_loading_debugger_ = false; 1398 bool Debugger::is_loading_debugger_ = false;
1399 bool Debugger::never_unload_debugger_ = false; 1399 bool Debugger::never_unload_debugger_ = false;
1400 DebugMessageThread* Debugger::message_thread_ = NULL; 1400 DebugMessageThread* Debugger::message_thread_ = NULL;
1401 v8::DebugMessageHandler Debugger::message_handler_ = NULL; 1401 v8::Debug::MessageHandler Debugger::message_handler_ = NULL;
1402 bool Debugger::message_handler_cleared_ = false; 1402 bool Debugger::message_handler_cleared_ = false;
1403 void* Debugger::message_handler_data_ = NULL; 1403 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1404 v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1405 void* Debugger::host_dispatch_handler_data_ = NULL;
1406 DebuggerAgent* Debugger::agent_ = NULL; 1404 DebuggerAgent* Debugger::agent_ = NULL;
1407 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); 1405 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize);
1408 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); 1406 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize);
1409 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); 1407 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
1410 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); 1408 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0);
1411 1409
1412 1410
1413 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, 1411 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
1414 int argc, Object*** argv, 1412 int argc, Object*** argv,
1415 bool* caught_exception) { 1413 bool* caught_exception) {
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 // First notify the message handler if any. 1695 // First notify the message handler if any.
1698 if (message_handler_ != NULL) { 1696 if (message_handler_ != NULL) {
1699 NotifyMessageHandler(event, exec_state, event_data, auto_continue); 1697 NotifyMessageHandler(event, exec_state, event_data, auto_continue);
1700 } 1698 }
1701 // Notify registered debug event listener. This can be either a C or a 1699 // Notify registered debug event listener. This can be either a C or a
1702 // JavaScript function. 1700 // JavaScript function.
1703 if (!event_listener_.is_null()) { 1701 if (!event_listener_.is_null()) {
1704 if (event_listener_->IsProxy()) { 1702 if (event_listener_->IsProxy()) {
1705 // C debug event listener. 1703 // C debug event listener.
1706 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); 1704 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
1707 v8::DebugEventCallback callback = 1705 v8::Debug::EventCallback callback =
1708 FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy()); 1706 FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy());
1709 callback(event, 1707 callback(event,
1710 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), 1708 v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
1711 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)), 1709 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)),
1712 v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_))); 1710 v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_)));
1713 } else { 1711 } else {
1714 // JavaScript debug event listener. 1712 // JavaScript debug event listener.
1715 ASSERT(event_listener_->IsJSFunction()); 1713 ASSERT(event_listener_->IsJSFunction());
1716 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); 1714 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
1717 1715
1718 // Invoke the JavaScript debug event listener. 1716 // Invoke the JavaScript debug event listener.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 // Process requests from the debugger. 1804 // Process requests from the debugger.
1807 while (true) { 1805 while (true) {
1808 // Wait for new command in the queue. 1806 // Wait for new command in the queue.
1809 command_received_->Wait(); 1807 command_received_->Wait();
1810 1808
1811 // The debug command interrupt flag might have been set when the command was 1809 // The debug command interrupt flag might have been set when the command was
1812 // added. 1810 // added.
1813 StackGuard::Continue(DEBUGCOMMAND); 1811 StackGuard::Continue(DEBUGCOMMAND);
1814 1812
1815 // Get the command from the queue. 1813 // Get the command from the queue.
1816 Vector<uint16_t> command = command_queue_.Get(); 1814 Message command = command_queue_.Get();
1817 Logger::DebugTag("Got request from command queue, in interactive loop."); 1815 Logger::DebugTag("Got request from command queue, in interactive loop.");
1818 if (!Debugger::IsDebuggerActive()) { 1816 if (!Debugger::IsDebuggerActive()) {
1817 // Delete command text and user data.
1818 command.Dispose();
1819 return; 1819 return;
1820 } 1820 }
1821 1821
1822 // Check if the command is a host dispatch. 1822 // Check if the command is a host dispatch.
1823 if (command[0] == 0) { 1823 if (command.IsHostDispatch()) {
1824 if (Debugger::host_dispatch_handler_) { 1824 if (Debugger::host_dispatch_handler_) {
1825 int32_t dispatch = (command[1] << 16) | command[2]; 1825 Debugger::host_dispatch_handler_(command.client_data());
1826 Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch), 1826 // Delete the dispatch.
1827 Debugger::host_dispatch_handler_data_); 1827 command.Dispose();
1828 } 1828 }
1829 if (auto_continue && !HasCommands()) { 1829 if (auto_continue && !HasCommands()) {
1830 return; 1830 return;
1831 } 1831 }
1832 continue; 1832 continue;
1833 } 1833 }
1834 1834
1835 // Invoke JavaScript to process the debug request. 1835 // Invoke JavaScript to process the debug request.
1836 v8::Local<v8::String> fun_name; 1836 v8::Local<v8::String> fun_name;
1837 v8::Local<v8::Function> fun; 1837 v8::Local<v8::Function> fun;
1838 v8::Local<v8::Value> request; 1838 v8::Local<v8::Value> request;
1839 v8::TryCatch try_catch; 1839 v8::TryCatch try_catch;
1840 fun_name = v8::String::New("processDebugRequest"); 1840 fun_name = v8::String::New("processDebugRequest");
1841 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); 1841 fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
1842 request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()), 1842
1843 command.length()); 1843 request = v8::String::New(command.text().start(),
1844 command.text().length());
1845 command.text().Dispose();
1844 static const int kArgc = 1; 1846 static const int kArgc = 1;
1845 v8::Handle<Value> argv[kArgc] = { request }; 1847 v8::Handle<Value> argv[kArgc] = { request };
1846 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); 1848 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
1847 1849
1848 // Get the response. 1850 // Get the response.
1849 v8::Local<v8::String> response; 1851 v8::Local<v8::String> response;
1850 bool running = false; 1852 bool running = false;
1851 if (!try_catch.HasCaught()) { 1853 if (!try_catch.HasCaught()) {
1852 // Get response string. 1854 // Get response string.
1853 if (!response_val->IsUndefined()) { 1855 if (!response_val->IsUndefined()) {
(...skipping 15 matching lines...) Expand all
1869 v8::Handle<Value> argv[kArgc] = { response }; 1871 v8::Handle<Value> argv[kArgc] = { response };
1870 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); 1872 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv);
1871 if (!try_catch.HasCaught()) { 1873 if (!try_catch.HasCaught()) {
1872 running = running_val->ToBoolean()->Value(); 1874 running = running_val->ToBoolean()->Value();
1873 } 1875 }
1874 } else { 1876 } else {
1875 // In case of failure the result text is the exception text. 1877 // In case of failure the result text is the exception text.
1876 response = try_catch.Exception()->ToString(); 1878 response = try_catch.Exception()->ToString();
1877 } 1879 }
1878 1880
1879 // Convert text result to C string.
1880 v8::String::Value val(response);
1881 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
1882 response->Length());
1883
1884 // Return the result. 1881 // Return the result.
1885 SendMessage(str); 1882 SendMessage(Message::NewOutput(response, command.client_data()));
1886 1883
1887 // Return from debug event processing if either the VM is put into the 1884 // Return from debug event processing if either the VM is put into the
1888 // runnning state (through a continue command) or auto continue is active 1885 // runnning state (through a continue command) or auto continue is active
1889 // and there are no more commands queued. 1886 // and there are no more commands queued.
1890 if (running || (auto_continue && !HasCommands())) { 1887 if (running || (auto_continue && !HasCommands())) {
1891 return; 1888 return;
1892 } 1889 }
1893 } 1890 }
1894 } 1891 }
1895 1892
(...skipping 25 matching lines...) Expand all
1921 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); 1918 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
1922 } 1919 }
1923 1920
1924 // Unload the debugger if event listener cleared. 1921 // Unload the debugger if event listener cleared.
1925 if (callback->IsUndefined()) { 1922 if (callback->IsUndefined()) {
1926 UnloadDebugger(); 1923 UnloadDebugger();
1927 } 1924 }
1928 } 1925 }
1929 1926
1930 1927
1931 void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data, 1928 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler,
1932 bool message_handler_thread) { 1929 bool message_handler_thread) {
1933 ScopedLock with(debugger_access_); 1930 ScopedLock with(debugger_access_);
1934 1931
1935 message_handler_ = handler; 1932 message_handler_ = handler;
1936 message_handler_data_ = data;
1937 if (handler != NULL) { 1933 if (handler != NULL) {
1938 if (!message_thread_ && message_handler_thread) { 1934 if (!message_thread_ && message_handler_thread) {
1939 message_thread_ = new DebugMessageThread(); 1935 message_thread_ = new DebugMessageThread();
1940 message_thread_->Start(); 1936 message_thread_->Start();
1941 } 1937 }
1942 } else { 1938 } else {
1943 // Indicate that the message handler was recently cleared. 1939 // Indicate that the message handler was recently cleared.
1944 message_handler_cleared_ = true; 1940 message_handler_cleared_ = true;
1945 1941
1946 // Send an empty command to the debugger if in a break to make JavaScript 1942 // Send an empty command to the debugger if in a break to make JavaScript
1947 // run again if the debugger is closed. 1943 // run again if the debugger is closed.
1948 if (Debug::InDebugger()) { 1944 if (Debug::InDebugger()) {
1949 ProcessCommand(Vector<const uint16_t>::empty()); 1945 ProcessCommand(Vector<const uint16_t>::empty());
1950 } 1946 }
1951 } 1947 }
1952 } 1948 }
1953 1949
1954 1950
1955 void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler, 1951 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler) {
1956 void* data) {
1957 host_dispatch_handler_ = handler; 1952 host_dispatch_handler_ = handler;
1958 host_dispatch_handler_data_ = data;
1959 } 1953 }
1960 1954
1961 1955
1962 // Calls the registered debug message handler. This callback is part of the 1956 // Calls the registered debug message handler. This callback is part of the
1963 // public API. Messages are kept internally as Vector<uint16_t> strings, which 1957 // public API. Messages are kept internally as Vector<uint16_t> strings, which
1964 // are allocated in various places and deallocated by the calling function 1958 // are allocated in various places and deallocated by the calling function
1965 // sometime after this call. 1959 // sometime after this call.
1966 void Debugger::InvokeMessageHandler(Vector<uint16_t> message) { 1960 void Debugger::InvokeMessageHandler(Message message) {
1967 ScopedLock with(debugger_access_); 1961 ScopedLock with(debugger_access_);
1968 1962
1969 if (message_handler_ != NULL) { 1963 if (message_handler_ != NULL) {
1970 message_handler_(message.start(), message.length(), message_handler_data_); 1964 message_handler_(message.text().start(),
1965 message.text().length(),
1966 message.client_data());
1971 } 1967 }
1968 message.Dispose();
1972 } 1969 }
1973 1970
1974 1971
1975 void Debugger::SendMessage(Vector<uint16_t> message) { 1972 void Debugger::SendMessage(Message message) {
1976 if (message_thread_ == NULL) { 1973 if (message_thread_ == NULL) {
1977 // If there is no message thread just invoke the message handler from the 1974 // If there is no message thread just invoke the message handler from the
1978 // V8 thread. 1975 // V8 thread.
1979 InvokeMessageHandler(message); 1976 InvokeMessageHandler(message);
1980 } else { 1977 } else {
1981 // Put a copy of the message coming from V8 on the queue. The new copy of 1978 // Put the message coming from V8 on the queue. The text and user data will
1982 // the event string is destroyed by the message thread. 1979 // be destroyed by the message thread.
1983 Vector<uint16_t> message_copy = message.Clone();
1984 Logger::DebugTag("Put message on event message_queue."); 1980 Logger::DebugTag("Put message on event message_queue.");
1985 message_queue_.Put(message_copy); 1981 message_queue_.Put(message);
1986 message_received_->Signal(); 1982 message_received_->Signal();
1987 } 1983 }
1988 } 1984 }
1989 1985
1990 1986
1991 bool Debugger::SendEventMessage(Handle<Object> event_data) { 1987 bool Debugger::SendEventMessage(Handle<Object> event_data) {
1992 v8::HandleScope scope; 1988 v8::HandleScope scope;
1993 // Call toJSONProtocol on the debug event object. 1989 // Call toJSONProtocol on the debug event object.
1994 v8::Local<v8::Object> api_event_data = 1990 v8::Local<v8::Object> api_event_data =
1995 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)); 1991 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data));
1996 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol"); 1992 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol");
1997 v8::Local<v8::Function> fun = 1993 v8::Local<v8::Function> fun =
1998 v8::Function::Cast(*api_event_data->Get(fun_name)); 1994 v8::Function::Cast(*api_event_data->Get(fun_name));
1999 v8::TryCatch try_catch; 1995 v8::TryCatch try_catch;
2000 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL); 1996 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL);
2001 v8::Local<v8::String> json_event_string; 1997 v8::Local<v8::String> json_event_string;
2002 if (!try_catch.HasCaught()) { 1998 if (!try_catch.HasCaught()) {
2003 if (!json_event->IsUndefined()) { 1999 if (!json_event->IsUndefined()) {
2004 json_event_string = json_event->ToString(); 2000 json_event_string = json_event->ToString();
2005 if (FLAG_trace_debug_json) { 2001 if (FLAG_trace_debug_json) {
2006 PrintLn(json_event_string); 2002 PrintLn(json_event_string);
2007 } 2003 }
2008 v8::String::Value val(json_event_string); 2004 SendMessage(Message::NewOutput(
2009 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val), 2005 json_event_string,
2010 json_event_string->Length()); 2006 NULL /* no user data since there was no request */));
2011 SendMessage(str);
2012 } else { 2007 } else {
2013 SendMessage(Vector<uint16_t>::empty()); 2008 SendMessage(Message::NewEmptyMessage());
2014 } 2009 }
2015 } else { 2010 } else {
2016 PrintLn(try_catch.Exception()); 2011 PrintLn(try_catch.Exception());
2017 return false; 2012 return false;
2018 } 2013 }
2019 return true; 2014 return true;
2020 } 2015 }
2021 2016
2022 2017
2023 // Puts a command coming from the public API on the queue. Creates 2018 // Puts a command coming from the public API on the queue. Creates
2024 // a copy of the command string managed by the debugger. Up to this 2019 // a copy of the command string managed by the debugger. Up to this
2025 // point, the command data was managed by the API client. Called 2020 // point, the command data was managed by the API client. Called
2026 // by the API client thread. This is where the API client hands off 2021 // by the API client thread. This is where the API client hands off
2027 // processing of the command to the DebugMessageThread thread. 2022 // processing of the command to the DebugMessageThread thread.
2028 // The new copy of the command is destroyed in HandleCommand(). 2023 // The new copy of the command is destroyed in HandleCommand().
2029 void Debugger::ProcessCommand(Vector<const uint16_t> command) { 2024 void Debugger::ProcessCommand(Vector<const uint16_t> command,
2030 // Make a copy of the command. Need to cast away const for Clone to work. 2025 v8::Debug::ClientData* client_data) {
2031 Vector<uint16_t> command_copy = 2026 // Need to cast away const.
2027 Message message = Message::NewCommand(
2032 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 2028 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2033 command.length()).Clone(); 2029 command.length()),
2030 client_data);
2034 Logger::DebugTag("Put command on command_queue."); 2031 Logger::DebugTag("Put command on command_queue.");
2035 command_queue_.Put(command_copy); 2032 command_queue_.Put(message);
2036 command_received_->Signal(); 2033 command_received_->Signal();
2037 2034
2038 // Set the debug command break flag to have the command processed. 2035 // Set the debug command break flag to have the command processed.
2039 if (!Debug::InDebugger()) { 2036 if (!Debug::InDebugger()) {
2040 StackGuard::DebugCommand(); 2037 StackGuard::DebugCommand();
2041 } 2038 }
2042 } 2039 }
2043 2040
2044 2041
2045 bool Debugger::HasCommands() { 2042 bool Debugger::HasCommands() {
2046 return !command_queue_.IsEmpty(); 2043 return !command_queue_.IsEmpty();
2047 } 2044 }
2048 2045
2049 2046
2050 void Debugger::ProcessHostDispatch(void* dispatch) { 2047 void Debugger::ProcessHostDispatch(v8::Debug::ClientData* dispatch) {
2051 // Puts a host dispatch comming from the public API on the queue. 2048 // Puts a host dispatch comming from the public API on the queue.
2052 uint16_t hack[3];
2053 hack[0] = 0;
2054 hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16;
2055 hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF;
2056 Logger::DebugTag("Put dispatch on command_queue."); 2049 Logger::DebugTag("Put dispatch on command_queue.");
2057 command_queue_.Put(Vector<uint16_t>(hack, 3).Clone()); 2050 command_queue_.Put(Message::NewHostDispatch(dispatch));
2058 command_received_->Signal(); 2051 command_received_->Signal();
2059 2052
2060 // Set the debug command break flag to have the host dispatch processed. 2053 // Set the debug command break flag to have the host dispatch processed.
2061 if (!Debug::InDebugger()) { 2054 if (!Debug::InDebugger()) {
2062 StackGuard::DebugCommand(); 2055 StackGuard::DebugCommand();
2063 } 2056 }
2064 } 2057 }
2065 2058
2066 2059
2067 bool Debugger::IsDebuggerActive() { 2060 bool Debugger::IsDebuggerActive() {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2127 } 2120 }
2128 } 2121 }
2129 2122
2130 2123
2131 void DebugMessageThread::Run() { 2124 void DebugMessageThread::Run() {
2132 // Sends debug events to an installed debugger message callback. 2125 // Sends debug events to an installed debugger message callback.
2133 while (keep_running_) { 2126 while (keep_running_) {
2134 // Wait and Get are paired so that semaphore count equals queue length. 2127 // Wait and Get are paired so that semaphore count equals queue length.
2135 Debugger::message_received_->Wait(); 2128 Debugger::message_received_->Wait();
2136 Logger::DebugTag("Get message from event message_queue."); 2129 Logger::DebugTag("Get message from event message_queue.");
2137 Vector<uint16_t> message = Debugger::message_queue_.Get(); 2130 Message message = Debugger::message_queue_.Get();
2138 if (message.length() > 0) { 2131 if (message.text().length() > 0) {
2139 Debugger::InvokeMessageHandler(message); 2132 Debugger::InvokeMessageHandler(message);
2133 } else {
2134 message.Dispose();
2140 } 2135 }
2141 } 2136 }
2142 } 2137 }
2143 2138
2144 2139
2145 void DebugMessageThread::Stop() { 2140 void DebugMessageThread::Stop() {
2146 keep_running_ = false; 2141 keep_running_ = false;
2147 Debugger::SendMessage(Vector<uint16_t>(NULL, 0)); 2142 Debugger::SendMessage(Message::NewEmptyMessage());
2148 Join(); 2143 Join();
2149 } 2144 }
2150 2145
2151 2146
2147 Message::Message() : text_(Vector<uint16_t>::empty()),
2148 client_data_(NULL),
2149 is_host_dispatch_(false) {
2150 }
2151
2152
2153 Message::Message(const Vector<uint16_t>& text,
2154 v8::Debug::ClientData* data,
2155 bool is_host_dispatch)
2156 : text_(text),
2157 client_data_(data),
2158 is_host_dispatch_(is_host_dispatch) {
2159 }
2160
2161
2162 Message::~Message() {
2163 }
2164
2165
2166 void Message::Dispose() {
2167 text_.Dispose();
2168 delete client_data_;
2169 client_data_ = NULL;
2170 }
2171
2172
2173 bool Message::IsHostDispatch() const {
2174 return is_host_dispatch_;
2175 }
2176
2177
2178 Message Message::NewCommand(const Vector<uint16_t>& command,
2179 v8::Debug::ClientData* data) {
2180 return Message(command.Clone(), data, false);
2181 }
2182
2183
2184 Message Message::NewHostDispatch(v8::Debug::ClientData* dispatch) {
2185 return Message(Vector<uint16_t>::empty(), dispatch, true);
2186 }
2187
2188
2189 Message Message::NewOutput(v8::Handle<v8::String> output,
2190 v8::Debug::ClientData* data) {
2191 Vector<uint16_t> text;
2192 if (!output.IsEmpty()) {
2193 text = Vector<uint16_t>::New(output->Length() + 1);
2194 output->Write(text.start());
2195 }
2196 return Message(text, data, false);
2197 }
2198
2199
2200 Message Message::NewEmptyMessage() {
2201 return Message();
2202 }
2203
2204
2152 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { 2205 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {
2153 messages_ = NewArray<Vector<uint16_t> >(size); 2206 messages_ = NewArray<Message>(size);
2154 } 2207 }
2155 2208
2156 2209
2157 MessageQueue::~MessageQueue() { 2210 MessageQueue::~MessageQueue() {
2211 while(!IsEmpty()) {
2212 Message m = Get();
2213 m.Dispose();
2214 }
2158 DeleteArray(messages_); 2215 DeleteArray(messages_);
2159 } 2216 }
2160 2217
2161 2218
2162 Vector<uint16_t> MessageQueue::Get() { 2219 Message MessageQueue::Get() {
2163 ASSERT(!IsEmpty()); 2220 ASSERT(!IsEmpty());
2164 int result = start_; 2221 int result = start_;
2165 start_ = (start_ + 1) % size_; 2222 start_ = (start_ + 1) % size_;
2166 return messages_[result]; 2223 return messages_[result];
2167 } 2224 }
2168 2225
2169 2226
2170 void MessageQueue::Put(const Vector<uint16_t>& message) { 2227 void MessageQueue::Put(const Message& message) {
2171 if ((end_ + 1) % size_ == start_) { 2228 if ((end_ + 1) % size_ == start_) {
2172 Expand(); 2229 Expand();
2173 } 2230 }
2174 messages_[end_] = message; 2231 messages_[end_] = message;
2175 end_ = (end_ + 1) % size_; 2232 end_ = (end_ + 1) % size_;
2176 } 2233 }
2177 2234
2178 2235
2179 void MessageQueue::Expand() { 2236 void MessageQueue::Expand() {
2180 MessageQueue new_queue(size_ * 2); 2237 MessageQueue new_queue(size_ * 2);
2181 while (!IsEmpty()) { 2238 while (!IsEmpty()) {
2182 new_queue.Put(Get()); 2239 new_queue.Put(Get());
2183 } 2240 }
2184 Vector<uint16_t>* array_to_free = messages_; 2241 Message* array_to_free = messages_;
2185 *this = new_queue; 2242 *this = new_queue;
2186 new_queue.messages_ = array_to_free; 2243 new_queue.messages_ = array_to_free;
2244 // Make the new_queue empty so that it doesn't call Dispose on any messages.
2245 new_queue.start_ = new_queue.end_;
2187 // Automatic destructor called on new_queue, freeing array_to_free. 2246 // Automatic destructor called on new_queue, freeing array_to_free.
2188 } 2247 }
2189 2248
2190 2249
2191 LockingMessageQueue::LockingMessageQueue(int size) : queue_(size) { 2250 LockingMessageQueue::LockingMessageQueue(int size) : queue_(size) {
2192 lock_ = OS::CreateMutex(); 2251 lock_ = OS::CreateMutex();
2193 } 2252 }
2194 2253
2195 2254
2196 LockingMessageQueue::~LockingMessageQueue() { 2255 LockingMessageQueue::~LockingMessageQueue() {
2197 delete lock_; 2256 delete lock_;
2198 } 2257 }
2199 2258
2200 2259
2201 bool LockingMessageQueue::IsEmpty() const { 2260 bool LockingMessageQueue::IsEmpty() const {
2202 ScopedLock sl(lock_); 2261 ScopedLock sl(lock_);
2203 return queue_.IsEmpty(); 2262 return queue_.IsEmpty();
2204 } 2263 }
2205 2264
2206 2265
2207 Vector<uint16_t> LockingMessageQueue::Get() { 2266 Message LockingMessageQueue::Get() {
2208 ScopedLock sl(lock_); 2267 ScopedLock sl(lock_);
2209 Vector<uint16_t> result = queue_.Get(); 2268 Message result = queue_.Get();
2210 Logger::DebugEvent("Get", result); 2269 Logger::DebugEvent("Get", result.text());
2211 return result; 2270 return result;
2212 } 2271 }
2213 2272
2214 2273
2215 void LockingMessageQueue::Put(const Vector<uint16_t>& message) { 2274 void LockingMessageQueue::Put(const Message& message) {
2216 ScopedLock sl(lock_); 2275 ScopedLock sl(lock_);
2217 queue_.Put(message); 2276 queue_.Put(message);
2218 Logger::DebugEvent("Put", message); 2277 Logger::DebugEvent("Put", message.text());
2219 } 2278 }
2220 2279
2221 2280
2222 void LockingMessageQueue::Clear() { 2281 void LockingMessageQueue::Clear() {
2223 ScopedLock sl(lock_); 2282 ScopedLock sl(lock_);
2224 queue_.Clear(); 2283 queue_.Clear();
2225 } 2284 }
2226 2285
2227 #endif // ENABLE_DEBUGGER_SUPPORT 2286 #endif // ENABLE_DEBUGGER_SUPPORT
2228 2287
2229 } } // namespace v8::internal 2288 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/debug-agent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698