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

Side by Side Diff: src/debug.cc

Issue 42643: Debugger message handler can be called from V8 thread (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') | no next file » | 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 1362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); 1373 Handle<Object> Debugger::event_listener_data_ = Handle<Object>();
1374 bool Debugger::debugger_active_ = false; 1374 bool Debugger::debugger_active_ = false;
1375 bool Debugger::compiling_natives_ = false; 1375 bool Debugger::compiling_natives_ = false;
1376 bool Debugger::is_loading_debugger_ = false; 1376 bool Debugger::is_loading_debugger_ = false;
1377 DebugMessageThread* Debugger::message_thread_ = NULL; 1377 DebugMessageThread* Debugger::message_thread_ = NULL;
1378 v8::DebugMessageHandler Debugger::message_handler_ = NULL; 1378 v8::DebugMessageHandler Debugger::message_handler_ = NULL;
1379 void* Debugger::message_handler_data_ = NULL; 1379 void* Debugger::message_handler_data_ = NULL;
1380 v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL; 1380 v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1381 void* Debugger::host_dispatch_handler_data_ = NULL; 1381 void* Debugger::host_dispatch_handler_data_ = NULL;
1382 DebuggerAgent* Debugger::agent_ = NULL; 1382 DebuggerAgent* Debugger::agent_ = NULL;
1383 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize);
1384 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize);
1385 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0);
1386 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0);
1383 1387
1384 1388
1385 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, 1389 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name,
1386 int argc, Object*** argv, 1390 int argc, Object*** argv,
1387 bool* caught_exception) { 1391 bool* caught_exception) {
1388 ASSERT(Top::context() == *Debug::debug_context()); 1392 ASSERT(Top::context() == *Debug::debug_context());
1389 1393
1390 // Create the execution state object. 1394 // Create the execution state object.
1391 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); 1395 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name);
1392 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); 1396 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str));
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 Handle<Object> event_data, 1663 Handle<Object> event_data,
1660 bool auto_continue) { 1664 bool auto_continue) {
1661 HandleScope scope; 1665 HandleScope scope;
1662 1666
1663 // Create the execution state. 1667 // Create the execution state.
1664 bool caught_exception = false; 1668 bool caught_exception = false;
1665 Handle<Object> exec_state = MakeExecutionState(&caught_exception); 1669 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
1666 if (caught_exception) { 1670 if (caught_exception) {
1667 return; 1671 return;
1668 } 1672 }
1669 // First notify the builtin debugger. 1673 // First notify the message handler if any.
1670 if (message_thread_ != NULL) { 1674 if (message_handler_ != NULL) {
1671 message_thread_->DebugEvent(event, exec_state, event_data, auto_continue); 1675 NotifyMessageHandler(event, exec_state, event_data, auto_continue);
1672 } 1676 }
1673 // Notify registered debug event listener. This can be either a C or a 1677 // Notify registered debug event listener. This can be either a C or a
1674 // JavaScript function. 1678 // JavaScript function.
1675 if (!event_listener_.is_null()) { 1679 if (!event_listener_.is_null()) {
1676 if (event_listener_->IsProxy()) { 1680 if (event_listener_->IsProxy()) {
1677 // C debug event listener. 1681 // C debug event listener.
1678 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_)); 1682 Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
1679 v8::DebugEventCallback callback = 1683 v8::DebugEventCallback callback =
1680 FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy()); 1684 FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy());
1681 callback(event, 1685 callback(event,
(...skipping 17 matching lines...) Expand all
1699 // Silently ignore exceptions from debug event listeners. 1703 // Silently ignore exceptions from debug event listeners.
1700 } 1704 }
1701 } 1705 }
1702 } 1706 }
1703 1707
1704 // Clear the mirror cache. 1708 // Clear the mirror cache.
1705 Debug::ClearMirrorCache(); 1709 Debug::ClearMirrorCache();
1706 } 1710 }
1707 1711
1708 1712
1709 void Debugger::SetEventListener(Handle<Object> callback, 1713 void Debugger::NotifyMessageHandler(v8::DebugEvent event,
1710 Handle<Object> data) {
1711 HandleScope scope;
1712
1713 // Clear the global handles for the event listener and the event listener data
1714 // object.
1715 if (!event_listener_.is_null()) {
1716 GlobalHandles::Destroy(
1717 reinterpret_cast<Object**>(event_listener_.location()));
1718 event_listener_ = Handle<Object>();
1719 }
1720 if (!event_listener_data_.is_null()) {
1721 GlobalHandles::Destroy(
1722 reinterpret_cast<Object**>(event_listener_data_.location()));
1723 event_listener_data_ = Handle<Object>();
1724 }
1725
1726 // If there is a new debug event listener register it together with its data
1727 // object.
1728 if (!callback->IsUndefined() && !callback->IsNull()) {
1729 event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback));
1730 if (data.is_null()) {
1731 data = Factory::undefined_value();
1732 }
1733 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
1734 }
1735
1736 UpdateActiveDebugger();
1737 }
1738
1739
1740 void Debugger::TearDown() {
1741 if (message_thread_ != NULL) {
1742 message_thread_->Stop();
1743 delete message_thread_;
1744 message_thread_ = NULL;
1745 }
1746 }
1747
1748
1749 void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data) {
1750 message_handler_ = handler;
1751 message_handler_data_ = data;
1752 if (!message_thread_) {
1753 message_thread_ = new DebugMessageThread();
1754 message_thread_->Start();
1755 }
1756 UpdateActiveDebugger();
1757 }
1758
1759
1760 void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
1761 void* data) {
1762 host_dispatch_handler_ = handler;
1763 host_dispatch_handler_data_ = data;
1764 }
1765
1766
1767 // Posts an output message from the debugger to the debug_message_handler
1768 // callback. This callback is part of the public API. Messages are
1769 // kept internally as Vector<uint16_t> strings, which are allocated in various
1770 // places and deallocated by the calling function sometime after this call.
1771 void Debugger::SendMessage(Vector< uint16_t> message) {
1772 if (message_handler_ != NULL) {
1773 message_handler_(message.start(), message.length(), message_handler_data_);
1774 }
1775 }
1776
1777
1778 void Debugger::ProcessCommand(Vector<const uint16_t> command) {
1779 if (message_thread_ != NULL) {
1780 message_thread_->ProcessCommand(
1781 Vector<uint16_t>(const_cast<uint16_t *>(command.start()),
1782 command.length()));
1783 }
1784 }
1785
1786
1787 bool Debugger::HasCommands() {
1788 if (message_thread_ != NULL) {
1789 return message_thread_->HasCommands();
1790 } else {
1791 return false;
1792 }
1793 }
1794
1795
1796 void Debugger::ProcessHostDispatch(void* dispatch) {
1797 if (message_thread_ != NULL) {
1798 message_thread_->ProcessHostDispatch(dispatch);
1799 }
1800 }
1801
1802
1803 void Debugger::UpdateActiveDebugger() {
1804 set_debugger_active((message_thread_ != NULL &&
1805 message_handler_ != NULL) ||
1806 !event_listener_.is_null());
1807 if (!debugger_active() && message_thread_) {
1808 message_thread_->OnDebuggerInactive();
1809 }
1810 if (!debugger_active()) {
1811 Debug::Unload();
1812 }
1813 }
1814
1815
1816 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
1817 Handle<Object> data,
1818 bool* pending_exception) {
1819 // Enter the debugger.
1820 EnterDebugger debugger;
1821 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) {
1822 return Factory::undefined_value();
1823 }
1824
1825 // Create the execution state.
1826 bool caught_exception = false;
1827 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
1828 if (caught_exception) {
1829 return Factory::undefined_value();
1830 }
1831
1832 static const int kArgc = 2;
1833 Object** argv[kArgc] = { exec_state.location(), data.location() };
1834 Handle<Object> result = Execution::Call(fun, Factory::undefined_value(),
1835 kArgc, argv, pending_exception);
1836 return result;
1837 }
1838
1839
1840 bool Debugger::StartAgent(const char* name, int port) {
1841 if (Socket::Setup()) {
1842 agent_ = new DebuggerAgent(name, port);
1843 agent_->Start();
1844 return true;
1845 }
1846
1847 return false;
1848 }
1849
1850
1851 void Debugger::StopAgent() {
1852 if (agent_ != NULL) {
1853 agent_->Shutdown();
1854 agent_->Join();
1855 delete agent_;
1856 agent_ = NULL;
1857 }
1858 }
1859
1860
1861 DebugMessageThread::DebugMessageThread()
1862 : host_running_(true),
1863 command_queue_(kQueueInitialSize),
1864 message_queue_(kQueueInitialSize),
1865 keep_running_(true) {
1866 command_received_ = OS::CreateSemaphore(0);
1867 message_received_ = OS::CreateSemaphore(0);
1868 }
1869
1870 // Should only be done after the thread is done running.
1871 DebugMessageThread::~DebugMessageThread() {
1872 delete command_received_;
1873 delete message_received_;
1874 }
1875
1876 void DebugMessageThread::Stop() {
1877 keep_running_ = false;
1878 SendMessage(Vector<uint16_t>(NULL, 0));
1879 Join();
1880 }
1881
1882 // Puts an event coming from V8 on the queue. Creates
1883 // a copy of the JSON formatted event string managed by the V8.
1884 // Called by the V8 thread.
1885 // The new copy of the event string is destroyed in Run().
1886 void DebugMessageThread::SendMessage(Vector<uint16_t> message) {
1887 Vector<uint16_t> message_copy = message.Clone();
1888 Logger::DebugTag("Put message on event message_queue.");
1889 message_queue_.Put(message_copy);
1890 message_received_->Signal();
1891 }
1892
1893
1894 bool DebugMessageThread::SetEventJSONFromEvent(Handle<Object> event_data) {
1895 v8::HandleScope scope;
1896 // Call toJSONProtocol on the debug event object.
1897 v8::Local<v8::Object> api_event_data =
1898 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data));
1899 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol");
1900 v8::Local<v8::Function> fun =
1901 v8::Function::Cast(*api_event_data->Get(fun_name));
1902 v8::TryCatch try_catch;
1903 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL);
1904 v8::Local<v8::String> json_event_string;
1905 if (!try_catch.HasCaught()) {
1906 if (!json_event->IsUndefined()) {
1907 json_event_string = json_event->ToString();
1908 if (FLAG_trace_debug_json) {
1909 PrintLn(json_event_string);
1910 }
1911 v8::String::Value val(json_event_string);
1912 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
1913 json_event_string->Length());
1914 SendMessage(str);
1915 } else {
1916 SendMessage(Vector<uint16_t>::empty());
1917 }
1918 } else {
1919 PrintLn(try_catch.Exception());
1920 return false;
1921 }
1922 return true;
1923 }
1924
1925
1926 void DebugMessageThread::Run() {
1927 // Sends debug events to an installed debugger message callback.
1928 while (keep_running_) {
1929 // Wait and Get are paired so that semaphore count equals queue length.
1930 message_received_->Wait();
1931 Logger::DebugTag("Get message from event message_queue.");
1932 Vector<uint16_t> message = message_queue_.Get();
1933 if (message.length() > 0) {
1934 Debugger::SendMessage(message);
1935 }
1936 }
1937 }
1938
1939
1940 // This method is called by the V8 thread whenever a debug event occurs in
1941 // the VM.
1942 void DebugMessageThread::DebugEvent(v8::DebugEvent event,
1943 Handle<Object> exec_state, 1714 Handle<Object> exec_state,
1944 Handle<Object> event_data, 1715 Handle<Object> event_data,
1945 bool auto_continue) { 1716 bool auto_continue) {
1946 HandleScope scope; 1717 HandleScope scope;
1947 1718
1948 if (!Debug::Load()) return; 1719 if (!Debug::Load()) return;
1949 1720
1950 // Process the individual events. 1721 // Process the individual events.
1951 bool interactive = false; 1722 bool interactive = false;
1952 switch (event) { 1723 switch (event) {
(...skipping 27 matching lines...) Expand all
1980 v8::Local<v8::Object> cmd_processor = 1751 v8::Local<v8::Object> cmd_processor =
1981 v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL)); 1752 v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL));
1982 if (try_catch.HasCaught()) { 1753 if (try_catch.HasCaught()) {
1983 PrintLn(try_catch.Exception()); 1754 PrintLn(try_catch.Exception());
1984 return; 1755 return;
1985 } 1756 }
1986 1757
1987 // Notify the debugger that a debug event has occurred unless auto continue is 1758 // Notify the debugger that a debug event has occurred unless auto continue is
1988 // active in which case no event is send. 1759 // active in which case no event is send.
1989 if (!auto_continue) { 1760 if (!auto_continue) {
1990 bool success = SetEventJSONFromEvent(event_data); 1761 bool success = SendEventMessage(event_data);
1991 if (!success) { 1762 if (!success) {
1992 // If failed to notify debugger just continue running. 1763 // If failed to notify debugger just continue running.
1993 return; 1764 return;
1994 } 1765 }
1995 } 1766 }
1996 1767
1997 // Process requests from the debugger. 1768 // Process requests from the debugger.
1998 host_running_ = false;
1999 while (true) { 1769 while (true) {
2000 // Wait for new command in the queue. 1770 // Wait for new command in the queue.
2001 command_received_->Wait(); 1771 command_received_->Wait();
2002 1772
2003 // The debug command interrupt flag might have been set when the command was 1773 // The debug command interrupt flag might have been set when the command was
2004 // added. 1774 // added.
2005 StackGuard::Continue(DEBUGCOMMAND); 1775 StackGuard::Continue(DEBUGCOMMAND);
2006 1776
2007 // Get the command from the queue. 1777 // Get the command from the queue.
2008 Vector<uint16_t> command = command_queue_.Get(); 1778 Vector<uint16_t> command = command_queue_.Get();
2009 Logger::DebugTag("Got request from command queue, in interactive loop."); 1779 Logger::DebugTag("Got request from command queue, in interactive loop.");
2010 ASSERT(!host_running_);
2011 if (!Debugger::debugger_active()) { 1780 if (!Debugger::debugger_active()) {
2012 host_running_ = true;
2013 return; 1781 return;
2014 } 1782 }
2015 1783
2016 // Check if the command is a host dispatch. 1784 // Check if the command is a host dispatch.
2017 if (command[0] == 0) { 1785 if (command[0] == 0) {
2018 if (Debugger::host_dispatch_handler_) { 1786 if (Debugger::host_dispatch_handler_) {
2019 int32_t dispatch = (command[1] << 16) | command[2]; 1787 int32_t dispatch = (command[1] << 16) | command[2];
2020 Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch), 1788 Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch),
2021 Debugger::host_dispatch_handler_data_); 1789 Debugger::host_dispatch_handler_data_);
2022 } 1790 }
2023 continue; 1791 continue;
2024 } 1792 }
2025 1793
2026 // Invoke the JavaScript to process the debug request. 1794 // Invoke JavaScript to process the debug request.
2027 v8::Local<v8::String> fun_name; 1795 v8::Local<v8::String> fun_name;
2028 v8::Local<v8::Function> fun; 1796 v8::Local<v8::Function> fun;
2029 v8::Local<v8::Value> request; 1797 v8::Local<v8::Value> request;
2030 v8::TryCatch try_catch; 1798 v8::TryCatch try_catch;
2031 fun_name = v8::String::New("processDebugRequest"); 1799 fun_name = v8::String::New("processDebugRequest");
2032 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); 1800 fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
2033 request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()), 1801 request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),
2034 command.length()); 1802 command.length());
2035 static const int kArgc = 1; 1803 static const int kArgc = 1;
2036 v8::Handle<Value> argv[kArgc] = { request }; 1804 v8::Handle<Value> argv[kArgc] = { request };
(...skipping 28 matching lines...) Expand all
2065 } else { 1833 } else {
2066 // In case of failure the result text is the exception text. 1834 // In case of failure the result text is the exception text.
2067 response = try_catch.Exception()->ToString(); 1835 response = try_catch.Exception()->ToString();
2068 } 1836 }
2069 1837
2070 // Convert text result to C string. 1838 // Convert text result to C string.
2071 v8::String::Value val(response); 1839 v8::String::Value val(response);
2072 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val), 1840 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
2073 response->Length()); 1841 response->Length());
2074 1842
2075 // Set host_running_ correctly for nested debugger evaluations.
2076 host_running_ = running;
2077
2078 // Return the result. 1843 // Return the result.
2079 SendMessage(str); 1844 SendMessage(str);
2080 1845
2081 // Return from debug event processing if either the VM is put into the 1846 // Return from debug event processing if either the VM is put into the
2082 // runnning state (through a continue command) or auto continue is active 1847 // runnning state (through a continue command) or auto continue is active
2083 // and there are no more commands queued. 1848 // and there are no more commands queued.
2084 if (running || (auto_continue && !HasCommands())) { 1849 if (running || (auto_continue && !HasCommands())) {
2085 return; 1850 return;
2086 } 1851 }
2087 } 1852 }
2088 } 1853 }
2089 1854
2090 1855
1856 void Debugger::SetEventListener(Handle<Object> callback,
1857 Handle<Object> data) {
1858 HandleScope scope;
1859
1860 // Clear the global handles for the event listener and the event listener data
1861 // object.
1862 if (!event_listener_.is_null()) {
1863 GlobalHandles::Destroy(
1864 reinterpret_cast<Object**>(event_listener_.location()));
1865 event_listener_ = Handle<Object>();
1866 }
1867 if (!event_listener_data_.is_null()) {
1868 GlobalHandles::Destroy(
1869 reinterpret_cast<Object**>(event_listener_data_.location()));
1870 event_listener_data_ = Handle<Object>();
1871 }
1872
1873 // If there is a new debug event listener register it together with its data
1874 // object.
1875 if (!callback->IsUndefined() && !callback->IsNull()) {
1876 event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback));
1877 if (data.is_null()) {
1878 data = Factory::undefined_value();
1879 }
1880 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
1881 }
1882
1883 UpdateActiveDebugger();
1884 }
1885
1886
1887 void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data,
1888 bool message_handler_thread) {
1889 message_handler_ = handler;
1890 message_handler_data_ = data;
1891 if (!message_thread_ && message_handler_thread) {
1892 message_thread_ = new DebugMessageThread();
1893 message_thread_->Start();
1894 }
1895 UpdateActiveDebugger();
1896 }
1897
1898
1899 void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
1900 void* data) {
1901 host_dispatch_handler_ = handler;
1902 host_dispatch_handler_data_ = data;
1903 }
1904
1905
1906 // Calls the registered debug message handler. This callback is part of the
1907 // public API. Messages are kept internally as Vector<uint16_t> strings, which
1908 // are allocated in various places and deallocated by the calling function
1909 // sometime after this call.
1910 void Debugger::InvokeMessageHandler(Vector<uint16_t> message) {
1911 if (message_handler_ != NULL) {
1912 message_handler_(message.start(), message.length(), message_handler_data_);
1913 }
1914 }
1915
1916
1917 void Debugger::SendMessage(Vector<uint16_t> message) {
1918 if (message_thread_ == NULL) {
1919 // If there is no message thread just invoke the message handler from the
1920 // V8 thread.
1921 InvokeMessageHandler(message);
1922 } else {
1923 // Put a copy of the message coming from V8 on the queue. The new copy of
1924 // the event string is destroyed by the message thread.
1925 Vector<uint16_t> message_copy = message.Clone();
1926 Logger::DebugTag("Put message on event message_queue.");
1927 message_queue_.Put(message_copy);
1928 message_received_->Signal();
1929 }
1930 }
1931
1932
1933 bool Debugger::SendEventMessage(Handle<Object> event_data) {
1934 v8::HandleScope scope;
1935 // Call toJSONProtocol on the debug event object.
1936 v8::Local<v8::Object> api_event_data =
1937 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data));
1938 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol");
1939 v8::Local<v8::Function> fun =
1940 v8::Function::Cast(*api_event_data->Get(fun_name));
1941 v8::TryCatch try_catch;
1942 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL);
1943 v8::Local<v8::String> json_event_string;
1944 if (!try_catch.HasCaught()) {
1945 if (!json_event->IsUndefined()) {
1946 json_event_string = json_event->ToString();
1947 if (FLAG_trace_debug_json) {
1948 PrintLn(json_event_string);
1949 }
1950 v8::String::Value val(json_event_string);
1951 Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
1952 json_event_string->Length());
1953 SendMessage(str);
1954 } else {
1955 SendMessage(Vector<uint16_t>::empty());
1956 }
1957 } else {
1958 PrintLn(try_catch.Exception());
1959 return false;
1960 }
1961 return true;
1962 }
1963
1964
2091 // Puts a command coming from the public API on the queue. Creates 1965 // Puts a command coming from the public API on the queue. Creates
2092 // a copy of the command string managed by the debugger. Up to this 1966 // a copy of the command string managed by the debugger. Up to this
2093 // point, the command data was managed by the API client. Called 1967 // point, the command data was managed by the API client. Called
2094 // by the API client thread. This is where the API client hands off 1968 // by the API client thread. This is where the API client hands off
2095 // processing of the command to the DebugMessageThread thread. 1969 // processing of the command to the DebugMessageThread thread.
2096 // The new copy of the command is destroyed in HandleCommand(). 1970 // The new copy of the command is destroyed in HandleCommand().
2097 void DebugMessageThread::ProcessCommand(Vector<uint16_t> command) { 1971 void Debugger::ProcessCommand(Vector<const uint16_t> command) {
2098 Vector<uint16_t> command_copy = command.Clone(); 1972 // Make a copy of the command. Need to cast away const for Clone to work.
1973 Vector<uint16_t> command_copy =
1974 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
1975 command.length()).Clone();
2099 Logger::DebugTag("Put command on command_queue."); 1976 Logger::DebugTag("Put command on command_queue.");
2100 command_queue_.Put(command_copy); 1977 command_queue_.Put(command_copy);
2101 command_received_->Signal(); 1978 command_received_->Signal();
2102
2103 if (!Debug::InDebugger()) { 1979 if (!Debug::InDebugger()) {
2104 StackGuard::DebugCommand(); 1980 StackGuard::DebugCommand();
2105 } 1981 }
2106 } 1982 }
2107 1983
2108 1984
1985 bool Debugger::HasCommands() {
1986 return !command_queue_.IsEmpty();
1987 }
1988
1989
1990 void Debugger::ProcessHostDispatch(void* dispatch) {
2109 // Puts a host dispatch comming from the public API on the queue. 1991 // Puts a host dispatch comming from the public API on the queue.
2110 void DebugMessageThread::ProcessHostDispatch(void* dispatch) {
2111 uint16_t hack[3]; 1992 uint16_t hack[3];
2112 hack[0] = 0; 1993 hack[0] = 0;
2113 hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16; 1994 hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16;
2114 hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF; 1995 hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF;
2115 Logger::DebugTag("Put dispatch on command_queue."); 1996 Logger::DebugTag("Put dispatch on command_queue.");
2116 command_queue_.Put(Vector<uint16_t>(hack, 3).Clone()); 1997 command_queue_.Put(Vector<uint16_t>(hack, 3).Clone());
2117 command_received_->Signal(); 1998 command_received_->Signal();
2118 } 1999 }
2119 2000
2120 2001
2121 void DebugMessageThread::OnDebuggerInactive() { 2002 void Debugger::UpdateActiveDebugger() {
2122 // Send an empty command to the debugger if in a break to make JavaScript run 2003 set_debugger_active((message_thread_ != NULL &&
2123 // again if the debugger is closed. 2004 message_handler_ != NULL) ||
2124 if (!host_running_) { 2005 !event_listener_.is_null());
2125 ProcessCommand(Vector<uint16_t>::empty()); 2006 if (!debugger_active() && message_thread_) {
2007 // Send an empty command to the debugger if in a break to make JavaScript
2008 // run again if the debugger is closed.
2009 ProcessCommand(Vector<const uint16_t>::empty());
2126 } 2010 }
2011 if (!debugger_active()) {
2012 Debug::Unload();
2013 }
2014 }
2015
2016
2017 Handle<Object> Debugger::Call(Handle<JSFunction> fun,
2018 Handle<Object> data,
2019 bool* pending_exception) {
2020 // Enter the debugger.
2021 EnterDebugger debugger;
2022 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) {
2023 return Factory::undefined_value();
2024 }
2025
2026 // Create the execution state.
2027 bool caught_exception = false;
2028 Handle<Object> exec_state = MakeExecutionState(&caught_exception);
2029 if (caught_exception) {
2030 return Factory::undefined_value();
2031 }
2032
2033 static const int kArgc = 2;
2034 Object** argv[kArgc] = { exec_state.location(), data.location() };
2035 Handle<Object> result = Execution::Call(fun, Factory::undefined_value(),
2036 kArgc, argv, pending_exception);
2037 return result;
2038 }
2039
2040
2041 bool Debugger::StartAgent(const char* name, int port) {
2042 if (Socket::Setup()) {
2043 agent_ = new DebuggerAgent(name, port);
2044 agent_->Start();
2045 return true;
2046 }
2047
2048 return false;
2049 }
2050
2051
2052 void Debugger::StopAgent() {
2053 if (agent_ != NULL) {
2054 agent_->Shutdown();
2055 agent_->Join();
2056 delete agent_;
2057 agent_ = NULL;
2058 }
2059 }
2060
2061
2062 void Debugger::TearDown() {
2063 if (message_thread_ != NULL) {
2064 message_thread_->Stop();
2065 delete message_thread_;
2066 message_thread_ = NULL;
2067 }
2068 }
2069
2070
2071 void DebugMessageThread::Run() {
2072 // Sends debug events to an installed debugger message callback.
2073 while (keep_running_) {
2074 // Wait and Get are paired so that semaphore count equals queue length.
2075 Debugger::message_received_->Wait();
2076 Logger::DebugTag("Get message from event message_queue.");
2077 Vector<uint16_t> message = Debugger::message_queue_.Get();
2078 if (message.length() > 0) {
2079 Debugger::InvokeMessageHandler(message);
2080 }
2081 }
2082 }
2083
2084
2085 void DebugMessageThread::Stop() {
2086 keep_running_ = false;
2087 Debugger::SendMessage(Vector<uint16_t>(NULL, 0));
2088 Join();
2127 } 2089 }
2128 2090
2129 2091
2130 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { 2092 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {
2131 messages_ = NewArray<Vector<uint16_t> >(size); 2093 messages_ = NewArray<Vector<uint16_t> >(size);
2132 } 2094 }
2133 2095
2134 2096
2135 MessageQueue::~MessageQueue() { 2097 MessageQueue::~MessageQueue() {
2136 DeleteArray(messages_); 2098 DeleteArray(messages_);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 } 2159 }
2198 2160
2199 2161
2200 void LockingMessageQueue::Clear() { 2162 void LockingMessageQueue::Clear() {
2201 ScopedLock sl(lock_); 2163 ScopedLock sl(lock_);
2202 queue_.Clear(); 2164 queue_.Clear();
2203 } 2165 }
2204 2166
2205 2167
2206 } } // namespace v8::internal 2168 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698