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

Side by Side Diff: src/debug/debug.cc

Issue 2524323002: [debug] remove deprecated debug command message queue. (Closed)
Patch Set: git cl set_commit Created 4 years 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
« no previous file with comments | « src/debug/debug.h ('k') | src/execution.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 20 matching lines...) Expand all
31 31
32 #include "include/v8-debug.h" 32 #include "include/v8-debug.h"
33 33
34 namespace v8 { 34 namespace v8 {
35 namespace internal { 35 namespace internal {
36 36
37 Debug::Debug(Isolate* isolate) 37 Debug::Debug(Isolate* isolate)
38 : debug_context_(Handle<Context>()), 38 : debug_context_(Handle<Context>()),
39 event_listener_(Handle<Object>()), 39 event_listener_(Handle<Object>()),
40 event_listener_data_(Handle<Object>()), 40 event_listener_data_(Handle<Object>()),
41 message_handler_(NULL),
42 command_received_(0),
43 command_queue_(isolate->logger(), kQueueInitialSize),
44 is_active_(false), 41 is_active_(false),
45 is_suppressed_(false), 42 is_suppressed_(false),
46 live_edit_enabled_(true), // TODO(yangguo): set to false by default. 43 live_edit_enabled_(true), // TODO(yangguo): set to false by default.
47 break_disabled_(false), 44 break_disabled_(false),
48 break_points_active_(true), 45 break_points_active_(true),
49 in_debug_event_listener_(false), 46 in_debug_event_listener_(false),
50 break_on_exception_(false), 47 break_on_exception_(false),
51 break_on_uncaught_exception_(false), 48 break_on_uncaught_exception_(false),
52 debug_info_list_(NULL), 49 debug_info_list_(NULL),
53 feature_tracker_(isolate), 50 feature_tracker_(isolate),
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 515
519 // Find the break location where execution has stopped. 516 // Find the break location where execution has stopped.
520 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 517 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
521 518
522 // Find actual break points, if any, and trigger debug break event. 519 // Find actual break points, if any, and trigger debug break event.
523 Handle<Object> break_points_hit = CheckBreakPoints(debug_info, &location); 520 Handle<Object> break_points_hit = CheckBreakPoints(debug_info, &location);
524 if (!break_points_hit->IsUndefined(isolate_)) { 521 if (!break_points_hit->IsUndefined(isolate_)) {
525 // Clear all current stepping setup. 522 // Clear all current stepping setup.
526 ClearStepping(); 523 ClearStepping();
527 // Notify the debug event listeners. 524 // Notify the debug event listeners.
528 OnDebugBreak(break_points_hit, false); 525 OnDebugBreak(break_points_hit);
529 return; 526 return;
530 } 527 }
531 528
532 // No break point. Check for stepping. 529 // No break point. Check for stepping.
533 StepAction step_action = last_step_action(); 530 StepAction step_action = last_step_action();
534 Address current_fp = frame->UnpaddedFP(); 531 Address current_fp = frame->UnpaddedFP();
535 Address target_fp = thread_local_.target_fp_; 532 Address target_fp = thread_local_.target_fp_;
536 Address last_fp = thread_local_.last_fp_; 533 Address last_fp = thread_local_.last_fp_;
537 534
538 bool step_break = false; 535 bool step_break = false;
(...skipping 23 matching lines...) Expand all
562 case StepFrame: 559 case StepFrame:
563 step_break = current_fp != last_fp; 560 step_break = current_fp != last_fp;
564 break; 561 break;
565 } 562 }
566 563
567 // Clear all current stepping setup. 564 // Clear all current stepping setup.
568 ClearStepping(); 565 ClearStepping();
569 566
570 if (step_break) { 567 if (step_break) {
571 // Notify the debug event listeners. 568 // Notify the debug event listeners.
572 OnDebugBreak(isolate_->factory()->undefined_value(), false); 569 OnDebugBreak(isolate_->factory()->undefined_value());
573 } else { 570 } else {
574 // Re-prepare to continue. 571 // Re-prepare to continue.
575 PrepareStep(step_action); 572 PrepareStep(step_action);
576 } 573 }
577 } 574 }
578 575
579 576
580 // Find break point objects for this location, if any, and evaluate them. 577 // Find break point objects for this location, if any, and evaluate them.
581 // Return an array of break point objects that evaluated true. 578 // Return an array of break point objects that evaluated true.
582 Handle<Object> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info, 579 Handle<Object> Debug::CheckBreakPoints(Handle<DebugInfo> debug_info,
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1736
1740 // Create the event data object. 1737 // Create the event data object.
1741 Handle<Object> event_data; 1738 Handle<Object> event_data;
1742 // Bail out and don't call debugger if exception. 1739 // Bail out and don't call debugger if exception.
1743 if (!MakeExceptionEvent( 1740 if (!MakeExceptionEvent(
1744 exception, uncaught, promise).ToHandle(&event_data)) { 1741 exception, uncaught, promise).ToHandle(&event_data)) {
1745 return; 1742 return;
1746 } 1743 }
1747 1744
1748 // Process debug event. 1745 // Process debug event.
1749 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); 1746 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data));
1750 // Return to continue execution from where the exception was thrown. 1747 // Return to continue execution from where the exception was thrown.
1751 } 1748 }
1752 1749
1753 1750 void Debug::OnDebugBreak(Handle<Object> break_points_hit) {
1754 void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) {
1755 // The caller provided for DebugScope. 1751 // The caller provided for DebugScope.
1756 AssertDebugContext(); 1752 AssertDebugContext();
1757 // Bail out if there is no listener for this event 1753 // Bail out if there is no listener for this event
1758 if (ignore_events()) return; 1754 if (ignore_events()) return;
1759 1755
1760 #ifdef DEBUG 1756 #ifdef DEBUG
1761 PrintBreakLocation(); 1757 PrintBreakLocation();
1762 #endif // DEBUG 1758 #endif // DEBUG
1763 1759
1764 HandleScope scope(isolate_); 1760 HandleScope scope(isolate_);
1765 // Create the event data object. 1761 // Create the event data object.
1766 Handle<Object> event_data; 1762 Handle<Object> event_data;
1767 // Bail out and don't call debugger if exception. 1763 // Bail out and don't call debugger if exception.
1768 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; 1764 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return;
1769 1765
1770 // Process debug event. 1766 // Process debug event.
1771 ProcessDebugEvent(v8::Break, 1767 ProcessDebugEvent(v8::Break, Handle<JSObject>::cast(event_data));
1772 Handle<JSObject>::cast(event_data),
1773 auto_continue);
1774 } 1768 }
1775 1769
1776 1770
1777 void Debug::OnCompileError(Handle<Script> script) { 1771 void Debug::OnCompileError(Handle<Script> script) {
1778 ProcessCompileEvent(v8::CompileError, script); 1772 ProcessCompileEvent(v8::CompileError, script);
1779 } 1773 }
1780 1774
1781 1775
1782 void Debug::OnBeforeCompile(Handle<Script> script) { 1776 void Debug::OnBeforeCompile(Handle<Script> script) {
1783 ProcessCompileEvent(v8::BeforeCompile, script); 1777 ProcessCompileEvent(v8::BeforeCompile, script);
(...skipping 13 matching lines...) Expand all
1797 HandleScope scope(isolate_); 1791 HandleScope scope(isolate_);
1798 DebugScope debug_scope(this); 1792 DebugScope debug_scope(this);
1799 if (debug_scope.failed()) return; 1793 if (debug_scope.failed()) return;
1800 1794
1801 // Create the script collected state object. 1795 // Create the script collected state object.
1802 Handle<Object> event_data; 1796 Handle<Object> event_data;
1803 // Bail out and don't call debugger if exception. 1797 // Bail out and don't call debugger if exception.
1804 if (!MakeAsyncTaskEvent(type, id, name).ToHandle(&event_data)) return; 1798 if (!MakeAsyncTaskEvent(type, id, name).ToHandle(&event_data)) return;
1805 1799
1806 // Process debug event. 1800 // Process debug event.
1807 ProcessDebugEvent(v8::AsyncTaskEvent, 1801 ProcessDebugEvent(v8::AsyncTaskEvent, Handle<JSObject>::cast(event_data));
1808 Handle<JSObject>::cast(event_data),
1809 true);
1810 } 1802 }
1811 1803
1812
1813 void Debug::ProcessDebugEvent(v8::DebugEvent event, 1804 void Debug::ProcessDebugEvent(v8::DebugEvent event,
1814 Handle<JSObject> event_data, 1805 Handle<JSObject> event_data) {
1815 bool auto_continue) {
1816 HandleScope scope(isolate_); 1806 HandleScope scope(isolate_);
1817 1807
1818 // Create the execution state. 1808 // Create the execution state.
1819 Handle<Object> exec_state; 1809 Handle<Object> exec_state;
1820 // Bail out and don't call debugger if exception. 1810 // Bail out and don't call debugger if exception.
1821 if (!MakeExecutionState().ToHandle(&exec_state)) return; 1811 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1822 1812
1823 // First notify the message handler if any. 1813 // Notify registered debug event listener.
1824 if (message_handler_ != NULL) { 1814 if (!event_listener_.is_null()) {
1825 NotifyMessageHandler(event,
1826 Handle<JSObject>::cast(exec_state),
1827 event_data,
1828 auto_continue);
1829 }
1830 // Notify registered debug event listener. This can be either a C or
1831 // a JavaScript function. Don't call event listener for v8::Break
1832 // here, if it's only a debug command -- they will be processed later.
1833 if ((event != v8::Break || !auto_continue) && !event_listener_.is_null()) {
1834 CallEventCallback(event, exec_state, event_data, NULL); 1815 CallEventCallback(event, exec_state, event_data, NULL);
1835 } 1816 }
1836 } 1817 }
1837 1818
1838 1819
1839 void Debug::CallEventCallback(v8::DebugEvent event, 1820 void Debug::CallEventCallback(v8::DebugEvent event,
1840 Handle<Object> exec_state, 1821 Handle<Object> exec_state,
1841 Handle<Object> event_data, 1822 Handle<Object> event_data,
1842 v8::Debug::ClientData* client_data) { 1823 v8::Debug::ClientData* client_data) {
1843 // Prevent other interrupts from triggering, for example API callbacks, 1824 // Prevent other interrupts from triggering, for example API callbacks,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 1856
1876 1857
1877 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) { 1858 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) {
1878 if (ignore_events()) return; 1859 if (ignore_events()) return;
1879 if (script->type() != i::Script::TYPE_NORMAL && 1860 if (script->type() != i::Script::TYPE_NORMAL &&
1880 script->type() != i::Script::TYPE_WASM) { 1861 script->type() != i::Script::TYPE_WASM) {
1881 return; 1862 return;
1882 } 1863 }
1883 SuppressDebug while_processing(this); 1864 SuppressDebug while_processing(this);
1884 1865
1885 bool in_nested_debug_scope = in_debug_scope();
1886 HandleScope scope(isolate_); 1866 HandleScope scope(isolate_);
1887 DebugScope debug_scope(this); 1867 DebugScope debug_scope(this);
1888 if (debug_scope.failed()) return; 1868 if (debug_scope.failed()) return;
1889 1869
1890 if (event == v8::AfterCompile) { 1870 if (event == v8::AfterCompile) {
1891 // If debugging there might be script break points registered for this 1871 // If debugging there might be script break points registered for this
1892 // script. Make sure that these break points are set. 1872 // script. Make sure that these break points are set.
1893 Handle<Object> argv[] = {Script::GetWrapper(script)}; 1873 Handle<Object> argv[] = {Script::GetWrapper(script)};
1894 if (CallFunction("UpdateScriptBreakPoints", arraysize(argv), argv) 1874 if (CallFunction("UpdateScriptBreakPoints", arraysize(argv), argv)
1895 .is_null()) { 1875 .is_null()) {
1896 return; 1876 return;
1897 } 1877 }
1898 } 1878 }
1899 1879
1900 // Create the compile state object. 1880 // Create the compile state object.
1901 Handle<Object> event_data; 1881 Handle<Object> event_data;
1902 // Bail out and don't call debugger if exception. 1882 // Bail out and don't call debugger if exception.
1903 if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return; 1883 if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
1904 1884
1905 // Don't call NotifyMessageHandler if already in debug scope to avoid running 1885 ProcessDebugEvent(event, Handle<JSObject>::cast(event_data));
1906 // nested command loop.
1907 if (in_nested_debug_scope) {
1908 if (event_listener_.is_null()) return;
1909 // Create the execution state.
1910 Handle<Object> exec_state;
1911 // Bail out and don't call debugger if exception.
1912 if (!MakeExecutionState().ToHandle(&exec_state)) return;
1913
1914 CallEventCallback(event, exec_state, event_data, NULL);
1915 } else {
1916 // Process debug event.
1917 ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), true);
1918 }
1919 } 1886 }
1920 1887
1921 1888
1922 Handle<Context> Debug::GetDebugContext() { 1889 Handle<Context> Debug::GetDebugContext() {
1923 if (!is_loaded()) return Handle<Context>(); 1890 if (!is_loaded()) return Handle<Context>();
1924 DebugScope debug_scope(this); 1891 DebugScope debug_scope(this);
1925 if (debug_scope.failed()) return Handle<Context>(); 1892 if (debug_scope.failed()) return Handle<Context>();
1926 // The global handle may be destroyed soon after. Return it reboxed. 1893 // The global handle may be destroyed soon after. Return it reboxed.
1927 return handle(*debug_context(), isolate_); 1894 return handle(*debug_context(), isolate_);
1928 } 1895 }
1929 1896
1930 1897
1931 void Debug::NotifyMessageHandler(v8::DebugEvent event,
1932 Handle<JSObject> exec_state,
1933 Handle<JSObject> event_data,
1934 bool auto_continue) {
1935 // Prevent other interrupts from triggering, for example API callbacks,
1936 // while dispatching message handler callbacks.
1937 PostponeInterruptsScope no_interrupts(isolate_);
1938 DCHECK(is_active_);
1939 HandleScope scope(isolate_);
1940 // Process the individual events.
1941 bool sendEventMessage = false;
1942 switch (event) {
1943 case v8::Break:
1944 sendEventMessage = !auto_continue;
1945 break;
1946 case v8::NewFunction:
1947 case v8::BeforeCompile:
1948 case v8::CompileError:
1949 case v8::AsyncTaskEvent:
1950 break;
1951 case v8::Exception:
1952 case v8::AfterCompile:
1953 sendEventMessage = true;
1954 break;
1955 }
1956
1957 // The debug command interrupt flag might have been set when the command was
1958 // added. It should be enough to clear the flag only once while we are in the
1959 // debugger.
1960 DCHECK(in_debug_scope());
1961 isolate_->stack_guard()->ClearDebugCommand();
1962
1963 // Notify the debugger that a debug event has occurred unless auto continue is
1964 // active in which case no event is send.
1965 if (sendEventMessage) {
1966 MessageImpl message = MessageImpl::NewEvent(
1967 event,
1968 auto_continue,
1969 Handle<JSObject>::cast(exec_state),
1970 Handle<JSObject>::cast(event_data));
1971 InvokeMessageHandler(message);
1972 }
1973
1974 // If auto continue don't make the event cause a break, but process messages
1975 // in the queue if any. For script collected events don't even process
1976 // messages in the queue as the execution state might not be what is expected
1977 // by the client.
1978 if (auto_continue && !has_commands()) return;
1979
1980 // DebugCommandProcessor goes here.
1981 bool running = auto_continue;
1982
1983 Handle<Object> cmd_processor_ctor =
1984 JSReceiver::GetProperty(isolate_, exec_state, "debugCommandProcessor")
1985 .ToHandleChecked();
1986 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
1987 Handle<JSReceiver> cmd_processor = Handle<JSReceiver>::cast(
1988 Execution::Call(isolate_, cmd_processor_ctor, exec_state, 1, ctor_args)
1989 .ToHandleChecked());
1990 Handle<JSFunction> process_debug_request = Handle<JSFunction>::cast(
1991 JSReceiver::GetProperty(isolate_, cmd_processor, "processDebugRequest")
1992 .ToHandleChecked());
1993 Handle<Object> is_running =
1994 JSReceiver::GetProperty(isolate_, cmd_processor, "isRunning")
1995 .ToHandleChecked();
1996
1997 // Process requests from the debugger.
1998 do {
1999 // Wait for new command in the queue.
2000 command_received_.Wait();
2001
2002 // Get the command from the queue.
2003 CommandMessage command = command_queue_.Get();
2004 isolate_->logger()->DebugTag(
2005 "Got request from command queue, in interactive loop.");
2006 if (!is_active()) {
2007 // Delete command text and user data.
2008 command.Dispose();
2009 return;
2010 }
2011
2012 Vector<const uc16> command_text(
2013 const_cast<const uc16*>(command.text().start()),
2014 command.text().length());
2015 Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte(
2016 command_text).ToHandleChecked();
2017 Handle<Object> request_args[] = { request_text };
2018 Handle<Object> answer_value;
2019 Handle<String> answer;
2020 MaybeHandle<Object> maybe_exception;
2021 MaybeHandle<Object> maybe_result =
2022 Execution::TryCall(isolate_, process_debug_request, cmd_processor, 1,
2023 request_args, &maybe_exception);
2024
2025 if (maybe_result.ToHandle(&answer_value)) {
2026 if (answer_value->IsUndefined(isolate_)) {
2027 answer = isolate_->factory()->empty_string();
2028 } else {
2029 answer = Handle<String>::cast(answer_value);
2030 }
2031
2032 // Log the JSON request/response.
2033 if (FLAG_trace_debug_json) {
2034 PrintF("%s\n", request_text->ToCString().get());
2035 PrintF("%s\n", answer->ToCString().get());
2036 }
2037
2038 Handle<Object> is_running_args[] = { answer };
2039 maybe_result = Execution::Call(
2040 isolate_, is_running, cmd_processor, 1, is_running_args);
2041 Handle<Object> result;
2042 if (!maybe_result.ToHandle(&result)) break;
2043 running = result->IsTrue(isolate_);
2044 } else {
2045 Handle<Object> exception;
2046 if (!maybe_exception.ToHandle(&exception)) break;
2047 Handle<Object> result;
2048 if (!Object::ToString(isolate_, exception).ToHandle(&result)) break;
2049 answer = Handle<String>::cast(result);
2050 }
2051
2052 // Return the result.
2053 MessageImpl message = MessageImpl::NewResponse(
2054 event, running, exec_state, event_data, answer, command.client_data());
2055 InvokeMessageHandler(message);
2056 command.Dispose();
2057
2058 // Return from debug event processing if either the VM is put into the
2059 // running state (through a continue command) or auto continue is active
2060 // and there are no more commands queued.
2061 } while (!running || has_commands());
2062 command_queue_.Clear();
2063 }
2064
2065
2066 void Debug::SetEventListener(Handle<Object> callback, 1898 void Debug::SetEventListener(Handle<Object> callback,
2067 Handle<Object> data) { 1899 Handle<Object> data) {
2068 GlobalHandles* global_handles = isolate_->global_handles(); 1900 GlobalHandles* global_handles = isolate_->global_handles();
2069 1901
2070 // Remove existing entry. 1902 // Remove existing entry.
2071 GlobalHandles::Destroy(event_listener_.location()); 1903 GlobalHandles::Destroy(event_listener_.location());
2072 event_listener_ = Handle<Object>(); 1904 event_listener_ = Handle<Object>();
2073 GlobalHandles::Destroy(event_listener_data_.location()); 1905 GlobalHandles::Destroy(event_listener_data_.location());
2074 event_listener_data_ = Handle<Object>(); 1906 event_listener_data_ = Handle<Object>();
2075 1907
2076 // Set new entry. 1908 // Set new entry.
2077 if (!callback->IsUndefined(isolate_) && !callback->IsNull(isolate_)) { 1909 if (!callback->IsUndefined(isolate_) && !callback->IsNull(isolate_)) {
2078 event_listener_ = global_handles->Create(*callback); 1910 event_listener_ = global_handles->Create(*callback);
2079 if (data.is_null()) data = isolate_->factory()->undefined_value(); 1911 if (data.is_null()) data = isolate_->factory()->undefined_value();
2080 event_listener_data_ = global_handles->Create(*data); 1912 event_listener_data_ = global_handles->Create(*data);
2081 } 1913 }
2082 1914
2083 UpdateState(); 1915 UpdateState();
2084 } 1916 }
2085 1917
2086 1918
2087 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
2088 message_handler_ = handler;
2089 UpdateState();
2090 if (handler == NULL && in_debug_scope()) {
2091 // Send an empty command to the debugger if in a break to make JavaScript
2092 // run again if the debugger is closed.
2093 EnqueueCommandMessage(Vector<const uint16_t>::empty());
2094 }
2095 }
2096
2097
2098
2099 void Debug::UpdateState() { 1919 void Debug::UpdateState() {
2100 bool is_active = message_handler_ != NULL || !event_listener_.is_null(); 1920 bool is_active = !event_listener_.is_null();
2101 if (is_active || in_debug_scope()) { 1921 if (is_active || in_debug_scope()) {
2102 // Note that the debug context could have already been loaded to 1922 // Note that the debug context could have already been loaded to
2103 // bootstrap test cases. 1923 // bootstrap test cases.
2104 isolate_->compilation_cache()->Disable(); 1924 isolate_->compilation_cache()->Disable();
2105 is_active = Load(); 1925 is_active = Load();
2106 } else if (is_loaded()) { 1926 } else if (is_loaded()) {
2107 isolate_->compilation_cache()->Enable(); 1927 isolate_->compilation_cache()->Enable();
2108 Unload(); 1928 Unload();
2109 } 1929 }
2110 is_active_ = is_active; 1930 is_active_ = is_active;
2111 } 1931 }
2112 1932
2113 1933
2114 // Calls the registered debug message handler. This callback is part of the
2115 // public API.
2116 void Debug::InvokeMessageHandler(MessageImpl message) {
2117 if (message_handler_ != NULL) message_handler_(message);
2118 }
2119
2120
2121 // Puts a command coming from the public API on the queue. Creates
2122 // a copy of the command string managed by the debugger. Up to this
2123 // point, the command data was managed by the API client. Called
2124 // by the API client thread.
2125 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
2126 v8::Debug::ClientData* client_data) {
2127 // Need to cast away const.
2128 CommandMessage message = CommandMessage::New(
2129 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
2130 command.length()),
2131 client_data);
2132 isolate_->logger()->DebugTag("Put command on command_queue.");
2133 command_queue_.Put(message);
2134 command_received_.Signal();
2135
2136 // Set the debug command break flag to have the command processed.
2137 if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
2138 }
2139
2140
2141 MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) { 1934 MaybeHandle<Object> Debug::Call(Handle<Object> fun, Handle<Object> data) {
2142 DebugScope debug_scope(this); 1935 DebugScope debug_scope(this);
2143 if (debug_scope.failed()) return isolate_->factory()->undefined_value(); 1936 if (debug_scope.failed()) return isolate_->factory()->undefined_value();
2144 1937
2145 // Create the execution state. 1938 // Create the execution state.
2146 Handle<Object> exec_state; 1939 Handle<Object> exec_state;
2147 if (!MakeExecutionState().ToHandle(&exec_state)) { 1940 if (!MakeExecutionState().ToHandle(&exec_state)) {
2148 return isolate_->factory()->undefined_value(); 1941 return isolate_->factory()->undefined_value();
2149 } 1942 }
2150 1943
(...skipping 26 matching lines...) Expand all
2177 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return; 1970 if (!JSFunction::cast(fun)->shared()->IsSubjectToDebugging()) return;
2178 JSGlobalObject* global = 1971 JSGlobalObject* global =
2179 JSFunction::cast(fun)->context()->global_object(); 1972 JSFunction::cast(fun)->context()->global_object();
2180 // Don't stop in debugger functions. 1973 // Don't stop in debugger functions.
2181 if (IsDebugGlobal(global)) return; 1974 if (IsDebugGlobal(global)) return;
2182 // Don't stop if the break location is muted. 1975 // Don't stop if the break location is muted.
2183 if (IsMutedAtCurrentLocation(it.frame())) return; 1976 if (IsMutedAtCurrentLocation(it.frame())) return;
2184 } 1977 }
2185 } 1978 }
2186 1979
2187 // Collect the break state before clearing the flags.
2188 bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
2189 !isolate_->stack_guard()->CheckDebugBreak();
2190
2191 isolate_->stack_guard()->ClearDebugBreak(); 1980 isolate_->stack_guard()->ClearDebugBreak();
2192 1981
2193 // Clear stepping to avoid duplicate breaks. 1982 // Clear stepping to avoid duplicate breaks.
2194 ClearStepping(); 1983 ClearStepping();
2195 1984
2196 ProcessDebugMessages(debug_command_only);
2197 }
2198
2199
2200 void Debug::ProcessDebugMessages(bool debug_command_only) {
2201 isolate_->stack_guard()->ClearDebugCommand();
2202
2203 StackLimitCheck check(isolate_);
2204 if (check.HasOverflowed()) return;
2205
2206 HandleScope scope(isolate_); 1985 HandleScope scope(isolate_);
2207 DebugScope debug_scope(this); 1986 DebugScope debug_scope(this);
2208 if (debug_scope.failed()) return; 1987 if (debug_scope.failed()) return;
2209 1988
2210 // Notify the debug event listeners. Indicate auto continue if the break was 1989 // Notify the debug event listeners.
2211 // a debug command break. 1990 OnDebugBreak(isolate_->factory()->undefined_value());
2212 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
2213 } 1991 }
2214 1992
2215 #ifdef DEBUG 1993 #ifdef DEBUG
2216 void Debug::PrintBreakLocation() { 1994 void Debug::PrintBreakLocation() {
2217 if (!FLAG_print_break_location) return; 1995 if (!FLAG_print_break_location) return;
2218 HandleScope scope(isolate_); 1996 HandleScope scope(isolate_);
2219 JavaScriptFrameIterator iterator(isolate_); 1997 JavaScriptFrameIterator iterator(isolate_);
2220 if (iterator.done()) return; 1998 if (iterator.done()) return;
2221 JavaScriptFrame* frame = iterator.frame(); 1999 JavaScriptFrame* frame = iterator.frame();
2222 FrameSummary summary = FrameSummary::GetFirst(frame); 2000 FrameSummary summary = FrameSummary::GetFirst(frame);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 } 2064 }
2287 2065
2288 2066
2289 DebugScope::~DebugScope() { 2067 DebugScope::~DebugScope() {
2290 if (!failed_ && prev_ == NULL) { 2068 if (!failed_ && prev_ == NULL) {
2291 // Clear mirror cache when leaving the debugger. Skip this if there is a 2069 // Clear mirror cache when leaving the debugger. Skip this if there is a
2292 // pending exception as clearing the mirror cache calls back into 2070 // pending exception as clearing the mirror cache calls back into
2293 // JavaScript. This can happen if the v8::Debug::Call is used in which 2071 // JavaScript. This can happen if the v8::Debug::Call is used in which
2294 // case the exception should end up in the calling code. 2072 // case the exception should end up in the calling code.
2295 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache(); 2073 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
2296
2297 // If there are commands in the queue when leaving the debugger request
2298 // that these commands are processed.
2299 if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
2300 } 2074 }
2301 2075
2302 // Leaving this debugger entry. 2076 // Leaving this debugger entry.
2303 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_, 2077 base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
2304 reinterpret_cast<base::AtomicWord>(prev_)); 2078 reinterpret_cast<base::AtomicWord>(prev_));
2305 2079
2306 // Restore to the previous break state. 2080 // Restore to the previous break state.
2307 debug_->thread_local_.break_frame_id_ = break_frame_id_; 2081 debug_->thread_local_.break_frame_id_ = break_frame_id_;
2308 debug_->thread_local_.break_id_ = break_id_; 2082 debug_->thread_local_.break_id_ = break_id_;
2309 debug_->thread_local_.return_value_ = return_value_; 2083 debug_->thread_local_.return_value_ = return_value_;
2310 2084
2311 debug_->UpdateState(); 2085 debug_->UpdateState();
2312 } 2086 }
2313 2087
2314 2088
2315 MessageImpl MessageImpl::NewEvent(DebugEvent event,
2316 bool running,
2317 Handle<JSObject> exec_state,
2318 Handle<JSObject> event_data) {
2319 MessageImpl message(true, event, running,
2320 exec_state, event_data, Handle<String>(), NULL);
2321 return message;
2322 }
2323
2324
2325 MessageImpl MessageImpl::NewResponse(DebugEvent event,
2326 bool running,
2327 Handle<JSObject> exec_state,
2328 Handle<JSObject> event_data,
2329 Handle<String> response_json,
2330 v8::Debug::ClientData* client_data) {
2331 MessageImpl message(false, event, running,
2332 exec_state, event_data, response_json, client_data);
2333 return message;
2334 }
2335
2336
2337 MessageImpl::MessageImpl(bool is_event,
2338 DebugEvent event,
2339 bool running,
2340 Handle<JSObject> exec_state,
2341 Handle<JSObject> event_data,
2342 Handle<String> response_json,
2343 v8::Debug::ClientData* client_data)
2344 : is_event_(is_event),
2345 event_(event),
2346 running_(running),
2347 exec_state_(exec_state),
2348 event_data_(event_data),
2349 response_json_(response_json),
2350 client_data_(client_data) {}
2351
2352
2353 bool MessageImpl::IsEvent() const {
2354 return is_event_;
2355 }
2356
2357
2358 bool MessageImpl::IsResponse() const {
2359 return !is_event_;
2360 }
2361
2362
2363 DebugEvent MessageImpl::GetEvent() const {
2364 return event_;
2365 }
2366
2367
2368 bool MessageImpl::WillStartRunning() const {
2369 return running_;
2370 }
2371
2372
2373 v8::Local<v8::Object> MessageImpl::GetExecutionState() const {
2374 return v8::Utils::ToLocal(exec_state_);
2375 }
2376
2377
2378 v8::Isolate* MessageImpl::GetIsolate() const {
2379 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2380 }
2381
2382
2383 v8::Local<v8::Object> MessageImpl::GetEventData() const {
2384 return v8::Utils::ToLocal(event_data_);
2385 }
2386
2387
2388 v8::Local<v8::String> MessageImpl::GetJSON() const {
2389 Isolate* isolate = event_data_->GetIsolate();
2390 v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
2391
2392 if (IsEvent()) {
2393 // Call toJSONProtocol on the debug event object.
2394 Handle<Object> fun =
2395 JSReceiver::GetProperty(isolate, event_data_, "toJSONProtocol")
2396 .ToHandleChecked();
2397 if (!fun->IsJSFunction()) {
2398 return v8::Local<v8::String>();
2399 }
2400
2401 MaybeHandle<Object> maybe_json =
2402 Execution::TryCall(isolate, fun, event_data_, 0, NULL);
2403 Handle<Object> json;
2404 if (!maybe_json.ToHandle(&json) || !json->IsString()) {
2405 return v8::Local<v8::String>();
2406 }
2407 return scope.Escape(v8::Utils::ToLocal(Handle<String>::cast(json)));
2408 } else {
2409 return v8::Utils::ToLocal(response_json_);
2410 }
2411 }
2412
2413 namespace {
2414 v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
2415 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext();
2416 // Isolate::context() may have been NULL when "script collected" event
2417 // occured.
2418 if (context.is_null()) return v8::Local<v8::Context>();
2419 Handle<Context> native_context(context->native_context());
2420 return v8::Utils::ToLocal(native_context);
2421 }
2422 } // anonymous namespace
2423
2424 v8::Local<v8::Context> MessageImpl::GetEventContext() const {
2425 Isolate* isolate = event_data_->GetIsolate();
2426 v8::Local<v8::Context> context = GetDebugEventContext(isolate);
2427 // Isolate::context() may be NULL when "script collected" event occurs.
2428 DCHECK(!context.IsEmpty());
2429 return context;
2430 }
2431
2432
2433 v8::Debug::ClientData* MessageImpl::GetClientData() const {
2434 return client_data_;
2435 }
2436
2437
2438 EventDetailsImpl::EventDetailsImpl(DebugEvent event, 2089 EventDetailsImpl::EventDetailsImpl(DebugEvent event,
2439 Handle<JSObject> exec_state, 2090 Handle<JSObject> exec_state,
2440 Handle<JSObject> event_data, 2091 Handle<JSObject> event_data,
2441 Handle<Object> callback_data, 2092 Handle<Object> callback_data,
2442 v8::Debug::ClientData* client_data) 2093 v8::Debug::ClientData* client_data)
2443 : event_(event), 2094 : event_(event),
2444 exec_state_(exec_state), 2095 exec_state_(exec_state),
2445 event_data_(event_data), 2096 event_data_(event_data),
2446 callback_data_(callback_data), 2097 callback_data_(callback_data),
2447 client_data_(client_data) {} 2098 client_data_(client_data) {}
2448 2099
2449 2100
2450 DebugEvent EventDetailsImpl::GetEvent() const { 2101 DebugEvent EventDetailsImpl::GetEvent() const {
2451 return event_; 2102 return event_;
2452 } 2103 }
2453 2104
2454 2105
2455 v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const { 2106 v8::Local<v8::Object> EventDetailsImpl::GetExecutionState() const {
2456 return v8::Utils::ToLocal(exec_state_); 2107 return v8::Utils::ToLocal(exec_state_);
2457 } 2108 }
2458 2109
2459 2110
2460 v8::Local<v8::Object> EventDetailsImpl::GetEventData() const { 2111 v8::Local<v8::Object> EventDetailsImpl::GetEventData() const {
2461 return v8::Utils::ToLocal(event_data_); 2112 return v8::Utils::ToLocal(event_data_);
2462 } 2113 }
2463 2114
2464 2115
2465 v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const { 2116 v8::Local<v8::Context> EventDetailsImpl::GetEventContext() const {
2466 return GetDebugEventContext(exec_state_->GetIsolate()); 2117 Handle<Context> context =
2118 exec_state_->GetIsolate()->debug()->debugger_entry()->GetContext();
2119 if (context.is_null()) return v8::Local<v8::Context>();
2120 Handle<Context> native_context(context->native_context());
2121 return v8::Utils::ToLocal(native_context);
2467 } 2122 }
2468 2123
2469 2124
2470 v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const { 2125 v8::Local<v8::Value> EventDetailsImpl::GetCallbackData() const {
2471 return v8::Utils::ToLocal(callback_data_); 2126 return v8::Utils::ToLocal(callback_data_);
2472 } 2127 }
2473 2128
2474 2129
2475 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const { 2130 v8::Debug::ClientData* EventDetailsImpl::GetClientData() const {
2476 return client_data_; 2131 return client_data_;
2477 } 2132 }
2478 2133
2479 v8::Isolate* EventDetailsImpl::GetIsolate() const { 2134 v8::Isolate* EventDetailsImpl::GetIsolate() const {
2480 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate()); 2135 return reinterpret_cast<v8::Isolate*>(exec_state_->GetIsolate());
2481 } 2136 }
2482 2137
2483 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()),
2484 client_data_(NULL) {
2485 }
2486
2487
2488 CommandMessage::CommandMessage(const Vector<uint16_t>& text,
2489 v8::Debug::ClientData* data)
2490 : text_(text),
2491 client_data_(data) {
2492 }
2493
2494
2495 void CommandMessage::Dispose() {
2496 text_.Dispose();
2497 delete client_data_;
2498 client_data_ = NULL;
2499 }
2500
2501
2502 CommandMessage CommandMessage::New(const Vector<uint16_t>& command,
2503 v8::Debug::ClientData* data) {
2504 return CommandMessage(command.Clone(), data);
2505 }
2506
2507
2508 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0),
2509 size_(size) {
2510 messages_ = NewArray<CommandMessage>(size);
2511 }
2512
2513
2514 CommandMessageQueue::~CommandMessageQueue() {
2515 while (!IsEmpty()) Get().Dispose();
2516 DeleteArray(messages_);
2517 }
2518
2519
2520 CommandMessage CommandMessageQueue::Get() {
2521 DCHECK(!IsEmpty());
2522 int result = start_;
2523 start_ = (start_ + 1) % size_;
2524 return messages_[result];
2525 }
2526
2527
2528 void CommandMessageQueue::Put(const CommandMessage& message) {
2529 if ((end_ + 1) % size_ == start_) {
2530 Expand();
2531 }
2532 messages_[end_] = message;
2533 end_ = (end_ + 1) % size_;
2534 }
2535
2536
2537 void CommandMessageQueue::Expand() {
2538 CommandMessageQueue new_queue(size_ * 2);
2539 while (!IsEmpty()) {
2540 new_queue.Put(Get());
2541 }
2542 CommandMessage* array_to_free = messages_;
2543 *this = new_queue;
2544 new_queue.messages_ = array_to_free;
2545 // Make the new_queue empty so that it doesn't call Dispose on any messages.
2546 new_queue.start_ = new_queue.end_;
2547 // Automatic destructor called on new_queue, freeing array_to_free.
2548 }
2549
2550
2551 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size)
2552 : logger_(logger), queue_(size) {}
2553
2554
2555 bool LockingCommandMessageQueue::IsEmpty() const {
2556 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2557 return queue_.IsEmpty();
2558 }
2559
2560
2561 CommandMessage LockingCommandMessageQueue::Get() {
2562 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2563 CommandMessage result = queue_.Get();
2564 logger_->DebugEvent("Get", result.text());
2565 return result;
2566 }
2567
2568
2569 void LockingCommandMessageQueue::Put(const CommandMessage& message) {
2570 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2571 queue_.Put(message);
2572 logger_->DebugEvent("Put", message.text());
2573 }
2574
2575
2576 void LockingCommandMessageQueue::Clear() {
2577 base::LockGuard<base::Mutex> lock_guard(&mutex_);
2578 queue_.Clear();
2579 }
2580
2581 } // namespace internal 2138 } // namespace internal
2582 } // namespace v8 2139 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/execution.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698