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

Side by Side Diff: src/debug.cc

Issue 56102: Change handling of debugger unloading (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') | test/cctest/test-debug.cc » ('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 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/debug.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698