| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |