| 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 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 return true; | 600 return true; |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 void Debug::Unload() { | 604 void Debug::Unload() { |
| 605 // Return debugger is not loaded. | 605 // Return debugger is not loaded. |
| 606 if (!IsLoaded()) { | 606 if (!IsLoaded()) { |
| 607 return; | 607 return; |
| 608 } | 608 } |
| 609 | 609 |
| 610 // Get rid of all break points and related information. | |
| 611 ClearAllBreakPoints(); | |
| 612 | |
| 613 // Clear debugger context global handle. | 610 // Clear debugger context global handle. |
| 614 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); | 611 GlobalHandles::Destroy(reinterpret_cast<Object**>(debug_context_.location())); |
| 615 debug_context_ = Handle<Context>(); | 612 debug_context_ = Handle<Context>(); |
| 616 } | 613 } |
| 617 | 614 |
| 618 | 615 |
| 619 // Set the flag indicating that preemption happened during debugging. | 616 // Set the flag indicating that preemption happened during debugging. |
| 620 void Debug::PreemptionWhileInDebugger() { | 617 void Debug::PreemptionWhileInDebugger() { |
| 621 ASSERT(InDebugger()); | 618 ASSERT(InDebugger()); |
| 622 Debug::set_preemption_pending(true); | 619 Debug::set_preemption_pending(true); |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 Handle<Object> fun(Top::global()->GetProperty(*function_name)); | 1359 Handle<Object> fun(Top::global()->GetProperty(*function_name)); |
| 1363 ASSERT(fun->IsJSFunction()); | 1360 ASSERT(fun->IsJSFunction()); |
| 1364 bool caught_exception; | 1361 bool caught_exception; |
| 1365 Handle<Object> js_object = Execution::TryCall( | 1362 Handle<Object> js_object = Execution::TryCall( |
| 1366 Handle<JSFunction>::cast(fun), | 1363 Handle<JSFunction>::cast(fun), |
| 1367 Handle<JSObject>(Debug::debug_context()->global()), | 1364 Handle<JSObject>(Debug::debug_context()->global()), |
| 1368 0, NULL, &caught_exception); | 1365 0, NULL, &caught_exception); |
| 1369 } | 1366 } |
| 1370 | 1367 |
| 1371 | 1368 |
| 1369 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); |
| 1372 Handle<Object> Debugger::event_listener_ = Handle<Object>(); | 1370 Handle<Object> Debugger::event_listener_ = Handle<Object>(); |
| 1373 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); | 1371 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); |
| 1374 bool Debugger::debugger_active_ = false; | |
| 1375 bool Debugger::compiling_natives_ = false; | 1372 bool Debugger::compiling_natives_ = false; |
| 1376 bool Debugger::is_loading_debugger_ = false; | 1373 bool Debugger::is_loading_debugger_ = false; |
| 1374 bool Debugger::never_unload_debugger_ = false; |
| 1377 DebugMessageThread* Debugger::message_thread_ = NULL; | 1375 DebugMessageThread* Debugger::message_thread_ = NULL; |
| 1378 v8::DebugMessageHandler Debugger::message_handler_ = NULL; | 1376 v8::DebugMessageHandler Debugger::message_handler_ = NULL; |
| 1377 bool Debugger::message_handler_cleared_ = false; |
| 1379 void* Debugger::message_handler_data_ = NULL; | 1378 void* Debugger::message_handler_data_ = NULL; |
| 1380 v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL; | 1379 v8::DebugHostDispatchHandler Debugger::host_dispatch_handler_ = NULL; |
| 1381 void* Debugger::host_dispatch_handler_data_ = NULL; | 1380 void* Debugger::host_dispatch_handler_data_ = NULL; |
| 1382 DebuggerAgent* Debugger::agent_ = NULL; | 1381 DebuggerAgent* Debugger::agent_ = NULL; |
| 1383 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); | 1382 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); |
| 1384 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); | 1383 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); |
| 1385 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); | 1384 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); |
| 1386 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); | 1385 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); |
| 1387 | 1386 |
| 1388 | 1387 |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 | 1573 |
| 1575 | 1574 |
| 1576 // Handle debugger actions when a new script is compiled. | 1575 // Handle debugger actions when a new script is compiled. |
| 1577 void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) { | 1576 void Debugger::OnAfterCompile(Handle<Script> script, Handle<JSFunction> fun) { |
| 1578 HandleScope scope; | 1577 HandleScope scope; |
| 1579 | 1578 |
| 1580 // No compile events while compiling natives. | 1579 // No compile events while compiling natives. |
| 1581 if (compiling_natives()) return; | 1580 if (compiling_natives()) return; |
| 1582 | 1581 |
| 1583 // No more to do if not debugging. | 1582 // No more to do if not debugging. |
| 1584 if (!debugger_active()) return; | 1583 if (!IsDebuggerActive()) return; |
| 1585 | 1584 |
| 1586 // Store whether in debugger before entering debugger. | 1585 // Store whether in debugger before entering debugger. |
| 1587 bool in_debugger = Debug::InDebugger(); | 1586 bool in_debugger = Debug::InDebugger(); |
| 1588 | 1587 |
| 1589 // Enter the debugger. | 1588 // Enter the debugger. |
| 1590 EnterDebugger debugger; | 1589 EnterDebugger debugger; |
| 1591 if (debugger.FailedToEnter()) return; | 1590 if (debugger.FailedToEnter()) return; |
| 1592 | 1591 |
| 1593 // If debugging there might be script break points registered for this | 1592 // If debugging there might be script break points registered for this |
| 1594 // script. Make sure that these break points are set. | 1593 // script. Make sure that these break points are set. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 // Silently ignore exceptions from debug event listeners. | 1702 // Silently ignore exceptions from debug event listeners. |
| 1704 } | 1703 } |
| 1705 } | 1704 } |
| 1706 } | 1705 } |
| 1707 | 1706 |
| 1708 // Clear the mirror cache. | 1707 // Clear the mirror cache. |
| 1709 Debug::ClearMirrorCache(); | 1708 Debug::ClearMirrorCache(); |
| 1710 } | 1709 } |
| 1711 | 1710 |
| 1712 | 1711 |
| 1712 void Debugger::UnloadDebugger() { |
| 1713 // Make sure that there are no breakpoints left. |
| 1714 Debug::ClearAllBreakPoints(); |
| 1715 |
| 1716 // Unload the debugger if feasible. |
| 1717 if (!never_unload_debugger_) { |
| 1718 Debug::Unload(); |
| 1719 } |
| 1720 |
| 1721 // Clear the flag indicating that the message handler was recently cleared. |
| 1722 message_handler_cleared_ = false; |
| 1723 } |
| 1724 |
| 1725 |
| 1713 void Debugger::NotifyMessageHandler(v8::DebugEvent event, | 1726 void Debugger::NotifyMessageHandler(v8::DebugEvent event, |
| 1714 Handle<Object> exec_state, | 1727 Handle<Object> exec_state, |
| 1715 Handle<Object> event_data, | 1728 Handle<Object> event_data, |
| 1716 bool auto_continue) { | 1729 bool auto_continue) { |
| 1717 HandleScope scope; | 1730 HandleScope scope; |
| 1718 | 1731 |
| 1719 if (!Debug::Load()) return; | 1732 if (!Debug::Load()) return; |
| 1720 | 1733 |
| 1721 // Process the individual events. | 1734 // Process the individual events. |
| 1722 bool interactive = false; | 1735 bool interactive = false; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 // Wait for new command in the queue. | 1783 // Wait for new command in the queue. |
| 1771 command_received_->Wait(); | 1784 command_received_->Wait(); |
| 1772 | 1785 |
| 1773 // The debug command interrupt flag might have been set when the command was | 1786 // The debug command interrupt flag might have been set when the command was |
| 1774 // added. | 1787 // added. |
| 1775 StackGuard::Continue(DEBUGCOMMAND); | 1788 StackGuard::Continue(DEBUGCOMMAND); |
| 1776 | 1789 |
| 1777 // Get the command from the queue. | 1790 // Get the command from the queue. |
| 1778 Vector<uint16_t> command = command_queue_.Get(); | 1791 Vector<uint16_t> command = command_queue_.Get(); |
| 1779 Logger::DebugTag("Got request from command queue, in interactive loop."); | 1792 Logger::DebugTag("Got request from command queue, in interactive loop."); |
| 1780 if (!Debugger::debugger_active()) { | 1793 if (!Debugger::IsDebuggerActive()) { |
| 1781 return; | 1794 return; |
| 1782 } | 1795 } |
| 1783 | 1796 |
| 1784 // Check if the command is a host dispatch. | 1797 // Check if the command is a host dispatch. |
| 1785 if (command[0] == 0) { | 1798 if (command[0] == 0) { |
| 1786 if (Debugger::host_dispatch_handler_) { | 1799 if (Debugger::host_dispatch_handler_) { |
| 1787 int32_t dispatch = (command[1] << 16) | command[2]; | 1800 int32_t dispatch = (command[1] << 16) | command[2]; |
| 1788 Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch), | 1801 Debugger::host_dispatch_handler_(reinterpret_cast<void*>(dispatch), |
| 1789 Debugger::host_dispatch_handler_data_); | 1802 Debugger::host_dispatch_handler_data_); |
| 1790 } | 1803 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 // If there is a new debug event listener register it together with its data | 1886 // If there is a new debug event listener register it together with its data |
| 1874 // object. | 1887 // object. |
| 1875 if (!callback->IsUndefined() && !callback->IsNull()) { | 1888 if (!callback->IsUndefined() && !callback->IsNull()) { |
| 1876 event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback)); | 1889 event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback)); |
| 1877 if (data.is_null()) { | 1890 if (data.is_null()) { |
| 1878 data = Factory::undefined_value(); | 1891 data = Factory::undefined_value(); |
| 1879 } | 1892 } |
| 1880 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); | 1893 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); |
| 1881 } | 1894 } |
| 1882 | 1895 |
| 1883 UpdateActiveDebugger(); | 1896 // Unload the debugger if event listener cleared. |
| 1897 if (callback->IsUndefined()) { |
| 1898 UnloadDebugger(); |
| 1899 } |
| 1884 } | 1900 } |
| 1885 | 1901 |
| 1886 | 1902 |
| 1887 void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data, | 1903 void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data, |
| 1888 bool message_handler_thread) { | 1904 bool message_handler_thread) { |
| 1905 ScopedLock with(debugger_access_); |
| 1906 |
| 1889 message_handler_ = handler; | 1907 message_handler_ = handler; |
| 1890 message_handler_data_ = data; | 1908 message_handler_data_ = data; |
| 1891 if (!message_thread_ && message_handler_thread) { | 1909 if (handler != NULL) { |
| 1892 message_thread_ = new DebugMessageThread(); | 1910 if (!message_thread_ && message_handler_thread) { |
| 1893 message_thread_->Start(); | 1911 message_thread_ = new DebugMessageThread(); |
| 1912 message_thread_->Start(); |
| 1913 } |
| 1914 } else { |
| 1915 // Indicate that the message handler was recently cleared. |
| 1916 message_handler_cleared_ = true; |
| 1917 |
| 1918 // Send an empty command to the debugger if in a break to make JavaScript |
| 1919 // run again if the debugger is closed. |
| 1920 if (Debug::InDebugger()) { |
| 1921 ProcessCommand(Vector<const uint16_t>::empty()); |
| 1922 } |
| 1894 } | 1923 } |
| 1895 UpdateActiveDebugger(); | |
| 1896 } | 1924 } |
| 1897 | 1925 |
| 1898 | 1926 |
| 1899 void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler, | 1927 void Debugger::SetHostDispatchHandler(v8::DebugHostDispatchHandler handler, |
| 1900 void* data) { | 1928 void* data) { |
| 1901 host_dispatch_handler_ = handler; | 1929 host_dispatch_handler_ = handler; |
| 1902 host_dispatch_handler_data_ = data; | 1930 host_dispatch_handler_data_ = data; |
| 1903 } | 1931 } |
| 1904 | 1932 |
| 1905 | 1933 |
| 1906 // Calls the registered debug message handler. This callback is part of the | 1934 // 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 | 1935 // public API. Messages are kept internally as Vector<uint16_t> strings, which |
| 1908 // are allocated in various places and deallocated by the calling function | 1936 // are allocated in various places and deallocated by the calling function |
| 1909 // sometime after this call. | 1937 // sometime after this call. |
| 1910 void Debugger::InvokeMessageHandler(Vector<uint16_t> message) { | 1938 void Debugger::InvokeMessageHandler(Vector<uint16_t> message) { |
| 1939 ScopedLock with(debugger_access_); |
| 1940 |
| 1911 if (message_handler_ != NULL) { | 1941 if (message_handler_ != NULL) { |
| 1912 message_handler_(message.start(), message.length(), message_handler_data_); | 1942 message_handler_(message.start(), message.length(), message_handler_data_); |
| 1913 } | 1943 } |
| 1914 } | 1944 } |
| 1915 | 1945 |
| 1916 | 1946 |
| 1917 void Debugger::SendMessage(Vector<uint16_t> message) { | 1947 void Debugger::SendMessage(Vector<uint16_t> message) { |
| 1918 if (message_thread_ == NULL) { | 1948 if (message_thread_ == NULL) { |
| 1919 // If there is no message thread just invoke the message handler from the | 1949 // If there is no message thread just invoke the message handler from the |
| 1920 // V8 thread. | 1950 // V8 thread. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1992 uint16_t hack[3]; | 2022 uint16_t hack[3]; |
| 1993 hack[0] = 0; | 2023 hack[0] = 0; |
| 1994 hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16; | 2024 hack[1] = reinterpret_cast<uint32_t>(dispatch) >> 16; |
| 1995 hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF; | 2025 hack[2] = reinterpret_cast<uint32_t>(dispatch) & 0xFFFF; |
| 1996 Logger::DebugTag("Put dispatch on command_queue."); | 2026 Logger::DebugTag("Put dispatch on command_queue."); |
| 1997 command_queue_.Put(Vector<uint16_t>(hack, 3).Clone()); | 2027 command_queue_.Put(Vector<uint16_t>(hack, 3).Clone()); |
| 1998 command_received_->Signal(); | 2028 command_received_->Signal(); |
| 1999 } | 2029 } |
| 2000 | 2030 |
| 2001 | 2031 |
| 2002 void Debugger::UpdateActiveDebugger() { | 2032 bool Debugger::IsDebuggerActive() { |
| 2003 set_debugger_active(message_handler_ != NULL || !event_listener_.is_null()); | 2033 ScopedLock with(debugger_access_); |
| 2004 if (!debugger_active() && message_thread_) { | 2034 |
| 2005 // Send an empty command to the debugger if in a break to make JavaScript | 2035 return message_handler_ != NULL || !event_listener_.is_null(); |
| 2006 // run again if the debugger is closed. | |
| 2007 ProcessCommand(Vector<const uint16_t>::empty()); | |
| 2008 } | |
| 2009 if (!debugger_active()) { | |
| 2010 Debug::Unload(); | |
| 2011 } | |
| 2012 } | 2036 } |
| 2013 | 2037 |
| 2014 | 2038 |
| 2015 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 2039 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
| 2016 Handle<Object> data, | 2040 Handle<Object> data, |
| 2017 bool* pending_exception) { | 2041 bool* pending_exception) { |
| 2042 // When calling functions in the debugger prevent it from beeing unloaded. |
| 2043 Debugger::never_unload_debugger_ = true; |
| 2044 |
| 2018 // Enter the debugger. | 2045 // Enter the debugger. |
| 2019 EnterDebugger debugger; | 2046 EnterDebugger debugger; |
| 2020 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) { | 2047 if (debugger.FailedToEnter() || !debugger.HasJavaScriptFrames()) { |
| 2021 return Factory::undefined_value(); | 2048 return Factory::undefined_value(); |
| 2022 } | 2049 } |
| 2023 | 2050 |
| 2024 // Create the execution state. | 2051 // Create the execution state. |
| 2025 bool caught_exception = false; | 2052 bool caught_exception = false; |
| 2026 Handle<Object> exec_state = MakeExecutionState(&caught_exception); | 2053 Handle<Object> exec_state = MakeExecutionState(&caught_exception); |
| 2027 if (caught_exception) { | 2054 if (caught_exception) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2157 } | 2184 } |
| 2158 | 2185 |
| 2159 | 2186 |
| 2160 void LockingMessageQueue::Clear() { | 2187 void LockingMessageQueue::Clear() { |
| 2161 ScopedLock sl(lock_); | 2188 ScopedLock sl(lock_); |
| 2162 queue_.Clear(); | 2189 queue_.Clear(); |
| 2163 } | 2190 } |
| 2164 | 2191 |
| 2165 | 2192 |
| 2166 } } // namespace v8::internal | 2193 } } // namespace v8::internal |
| OLD | NEW |