| 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 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); | 1417 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); |
| 1418 Handle<Object> Debugger::event_listener_ = Handle<Object>(); | 1418 Handle<Object> Debugger::event_listener_ = Handle<Object>(); |
| 1419 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); | 1419 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); |
| 1420 bool Debugger::compiling_natives_ = false; | 1420 bool Debugger::compiling_natives_ = false; |
| 1421 bool Debugger::is_loading_debugger_ = false; | 1421 bool Debugger::is_loading_debugger_ = false; |
| 1422 bool Debugger::never_unload_debugger_ = false; | 1422 bool Debugger::never_unload_debugger_ = false; |
| 1423 DebugMessageThread* Debugger::message_thread_ = NULL; | 1423 DebugMessageThread* Debugger::message_thread_ = NULL; |
| 1424 v8::Debug::MessageHandler Debugger::message_handler_ = NULL; | 1424 v8::Debug::MessageHandler Debugger::message_handler_ = NULL; |
| 1425 bool Debugger::message_handler_cleared_ = false; | 1425 bool Debugger::message_handler_cleared_ = false; |
| 1426 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; | 1426 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; |
| 1427 int Debugger::host_dispatch_micros_ = 100 * 1000; |
| 1427 DebuggerAgent* Debugger::agent_ = NULL; | 1428 DebuggerAgent* Debugger::agent_ = NULL; |
| 1428 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); | 1429 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); |
| 1429 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); | 1430 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); |
| 1430 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); | 1431 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); |
| 1431 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); | 1432 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); |
| 1432 | 1433 |
| 1433 | 1434 |
| 1434 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, | 1435 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, |
| 1435 int argc, Object*** argv, | 1436 int argc, Object*** argv, |
| 1436 bool* caught_exception) { | 1437 bool* caught_exception) { |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1820 bool success = SendEventMessage(event_data); | 1821 bool success = SendEventMessage(event_data); |
| 1821 if (!success) { | 1822 if (!success) { |
| 1822 // If failed to notify debugger just continue running. | 1823 // If failed to notify debugger just continue running. |
| 1823 return; | 1824 return; |
| 1824 } | 1825 } |
| 1825 } | 1826 } |
| 1826 | 1827 |
| 1827 // Process requests from the debugger. | 1828 // Process requests from the debugger. |
| 1828 while (true) { | 1829 while (true) { |
| 1829 // Wait for new command in the queue. | 1830 // Wait for new command in the queue. |
| 1830 command_received_->Wait(); | 1831 if (Debugger::host_dispatch_handler_) { |
| 1832 // In case there is a host dispatch - do periodic dispatches. |
| 1833 if (!command_received_->Wait(host_dispatch_micros_)) { |
| 1834 // Timout expired, do the dispatch. |
| 1835 Debugger::host_dispatch_handler_(); |
| 1836 continue; |
| 1837 } |
| 1838 } else { |
| 1839 // In case there is no host dispatch - just wait. |
| 1840 command_received_->Wait(); |
| 1841 } |
| 1831 | 1842 |
| 1832 // The debug command interrupt flag might have been set when the command was | 1843 // The debug command interrupt flag might have been set when the command was |
| 1833 // added. | 1844 // added. |
| 1834 StackGuard::Continue(DEBUGCOMMAND); | 1845 StackGuard::Continue(DEBUGCOMMAND); |
| 1835 | 1846 |
| 1836 // Get the command from the queue. | 1847 // Get the command from the queue. |
| 1837 Message command = command_queue_.Get(); | 1848 Message command = command_queue_.Get(); |
| 1838 Logger::DebugTag("Got request from command queue, in interactive loop."); | 1849 Logger::DebugTag("Got request from command queue, in interactive loop."); |
| 1839 if (!Debugger::IsDebuggerActive()) { | 1850 if (!Debugger::IsDebuggerActive()) { |
| 1840 // Delete command text and user data. | 1851 // Delete command text and user data. |
| 1841 command.Dispose(); | 1852 command.Dispose(); |
| 1842 return; | 1853 return; |
| 1843 } | 1854 } |
| 1844 | 1855 |
| 1845 // Check if the command is a host dispatch. | |
| 1846 if (command.IsHostDispatch()) { | |
| 1847 if (Debugger::host_dispatch_handler_) { | |
| 1848 Debugger::host_dispatch_handler_(command.client_data()); | |
| 1849 // Delete the dispatch. | |
| 1850 command.Dispose(); | |
| 1851 } | |
| 1852 if (auto_continue && !HasCommands()) { | |
| 1853 return; | |
| 1854 } | |
| 1855 continue; | |
| 1856 } | |
| 1857 | |
| 1858 // Invoke JavaScript to process the debug request. | 1856 // Invoke JavaScript to process the debug request. |
| 1859 v8::Local<v8::String> fun_name; | 1857 v8::Local<v8::String> fun_name; |
| 1860 v8::Local<v8::Function> fun; | 1858 v8::Local<v8::Function> fun; |
| 1861 v8::Local<v8::Value> request; | 1859 v8::Local<v8::Value> request; |
| 1862 v8::TryCatch try_catch; | 1860 v8::TryCatch try_catch; |
| 1863 fun_name = v8::String::New("processDebugRequest"); | 1861 fun_name = v8::String::New("processDebugRequest"); |
| 1864 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); | 1862 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); |
| 1865 | 1863 |
| 1866 request = v8::String::New(command.text().start(), | 1864 request = v8::String::New(command.text().start(), |
| 1867 command.text().length()); | 1865 command.text().length()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1964 | 1962 |
| 1965 // Send an empty command to the debugger if in a break to make JavaScript | 1963 // Send an empty command to the debugger if in a break to make JavaScript |
| 1966 // run again if the debugger is closed. | 1964 // run again if the debugger is closed. |
| 1967 if (Debug::InDebugger()) { | 1965 if (Debug::InDebugger()) { |
| 1968 ProcessCommand(Vector<const uint16_t>::empty()); | 1966 ProcessCommand(Vector<const uint16_t>::empty()); |
| 1969 } | 1967 } |
| 1970 } | 1968 } |
| 1971 } | 1969 } |
| 1972 | 1970 |
| 1973 | 1971 |
| 1974 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler) { | 1972 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
| 1973 int period) { |
| 1975 host_dispatch_handler_ = handler; | 1974 host_dispatch_handler_ = handler; |
| 1975 host_dispatch_micros_ = period * 1000; |
| 1976 } | 1976 } |
| 1977 | 1977 |
| 1978 | 1978 |
| 1979 // Calls the registered debug message handler. This callback is part of the | 1979 // Calls the registered debug message handler. This callback is part of the |
| 1980 // public API. Messages are kept internally as Vector<uint16_t> strings, which | 1980 // public API. Messages are kept internally as Vector<uint16_t> strings, which |
| 1981 // are allocated in various places and deallocated by the calling function | 1981 // are allocated in various places and deallocated by the calling function |
| 1982 // sometime after this call. | 1982 // sometime after this call. |
| 1983 void Debugger::InvokeMessageHandler(Message message) { | 1983 void Debugger::InvokeMessageHandler(Message message) { |
| 1984 ScopedLock with(debugger_access_); | 1984 ScopedLock with(debugger_access_); |
| 1985 | 1985 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 StackGuard::DebugCommand(); | 2060 StackGuard::DebugCommand(); |
| 2061 } | 2061 } |
| 2062 } | 2062 } |
| 2063 | 2063 |
| 2064 | 2064 |
| 2065 bool Debugger::HasCommands() { | 2065 bool Debugger::HasCommands() { |
| 2066 return !command_queue_.IsEmpty(); | 2066 return !command_queue_.IsEmpty(); |
| 2067 } | 2067 } |
| 2068 | 2068 |
| 2069 | 2069 |
| 2070 void Debugger::ProcessHostDispatch(v8::Debug::ClientData* dispatch) { | |
| 2071 // Puts a host dispatch comming from the public API on the queue. | |
| 2072 Logger::DebugTag("Put dispatch on command_queue."); | |
| 2073 command_queue_.Put(Message::NewHostDispatch(dispatch)); | |
| 2074 command_received_->Signal(); | |
| 2075 | |
| 2076 // Set the debug command break flag to have the host dispatch processed. | |
| 2077 if (!Debug::InDebugger()) { | |
| 2078 StackGuard::DebugCommand(); | |
| 2079 } | |
| 2080 } | |
| 2081 | |
| 2082 | |
| 2083 bool Debugger::IsDebuggerActive() { | 2070 bool Debugger::IsDebuggerActive() { |
| 2084 ScopedLock with(debugger_access_); | 2071 ScopedLock with(debugger_access_); |
| 2085 | 2072 |
| 2086 return message_handler_ != NULL || !event_listener_.is_null(); | 2073 return message_handler_ != NULL || !event_listener_.is_null(); |
| 2087 } | 2074 } |
| 2088 | 2075 |
| 2089 | 2076 |
| 2090 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 2077 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
| 2091 Handle<Object> data, | 2078 Handle<Object> data, |
| 2092 bool* pending_exception) { | 2079 bool* pending_exception) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2161 | 2148 |
| 2162 | 2149 |
| 2163 void DebugMessageThread::Stop() { | 2150 void DebugMessageThread::Stop() { |
| 2164 keep_running_ = false; | 2151 keep_running_ = false; |
| 2165 Debugger::SendMessage(Message::NewEmptyMessage()); | 2152 Debugger::SendMessage(Message::NewEmptyMessage()); |
| 2166 Join(); | 2153 Join(); |
| 2167 } | 2154 } |
| 2168 | 2155 |
| 2169 | 2156 |
| 2170 Message::Message() : text_(Vector<uint16_t>::empty()), | 2157 Message::Message() : text_(Vector<uint16_t>::empty()), |
| 2171 client_data_(NULL), | 2158 client_data_(NULL) { |
| 2172 is_host_dispatch_(false) { | |
| 2173 } | 2159 } |
| 2174 | 2160 |
| 2175 | 2161 |
| 2176 Message::Message(const Vector<uint16_t>& text, | 2162 Message::Message(const Vector<uint16_t>& text, |
| 2177 v8::Debug::ClientData* data, | 2163 v8::Debug::ClientData* data) |
| 2178 bool is_host_dispatch) | |
| 2179 : text_(text), | 2164 : text_(text), |
| 2180 client_data_(data), | 2165 client_data_(data) { |
| 2181 is_host_dispatch_(is_host_dispatch) { | |
| 2182 } | 2166 } |
| 2183 | 2167 |
| 2184 | 2168 |
| 2185 Message::~Message() { | 2169 Message::~Message() { |
| 2186 } | 2170 } |
| 2187 | 2171 |
| 2188 | 2172 |
| 2189 void Message::Dispose() { | 2173 void Message::Dispose() { |
| 2190 text_.Dispose(); | 2174 text_.Dispose(); |
| 2191 delete client_data_; | 2175 delete client_data_; |
| 2192 client_data_ = NULL; | 2176 client_data_ = NULL; |
| 2193 } | 2177 } |
| 2194 | 2178 |
| 2195 | 2179 |
| 2196 bool Message::IsHostDispatch() const { | |
| 2197 return is_host_dispatch_; | |
| 2198 } | |
| 2199 | |
| 2200 | |
| 2201 Message Message::NewCommand(const Vector<uint16_t>& command, | 2180 Message Message::NewCommand(const Vector<uint16_t>& command, |
| 2202 v8::Debug::ClientData* data) { | 2181 v8::Debug::ClientData* data) { |
| 2203 return Message(command.Clone(), data, false); | 2182 return Message(command.Clone(), data); |
| 2204 } | 2183 } |
| 2205 | 2184 |
| 2206 | 2185 |
| 2207 Message Message::NewHostDispatch(v8::Debug::ClientData* dispatch) { | |
| 2208 return Message(Vector<uint16_t>::empty(), dispatch, true); | |
| 2209 } | |
| 2210 | |
| 2211 | |
| 2212 Message Message::NewOutput(v8::Handle<v8::String> output, | 2186 Message Message::NewOutput(v8::Handle<v8::String> output, |
| 2213 v8::Debug::ClientData* data) { | 2187 v8::Debug::ClientData* data) { |
| 2214 Vector<uint16_t> text; | 2188 Vector<uint16_t> text; |
| 2215 if (!output.IsEmpty()) { | 2189 if (!output.IsEmpty()) { |
| 2216 // Do not include trailing '\0'. | 2190 // Do not include trailing '\0'. |
| 2217 text = Vector<uint16_t>::New(output->Length()); | 2191 text = Vector<uint16_t>::New(output->Length()); |
| 2218 output->Write(text.start(), 0, output->Length()); | 2192 output->Write(text.start(), 0, output->Length()); |
| 2219 } | 2193 } |
| 2220 return Message(text, data, false); | 2194 return Message(text, data); |
| 2221 } | 2195 } |
| 2222 | 2196 |
| 2223 | 2197 |
| 2224 Message Message::NewEmptyMessage() { | 2198 Message Message::NewEmptyMessage() { |
| 2225 return Message(); | 2199 return Message(); |
| 2226 } | 2200 } |
| 2227 | 2201 |
| 2228 | 2202 |
| 2229 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { | 2203 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { |
| 2230 messages_ = NewArray<Message>(size); | 2204 messages_ = NewArray<Message>(size); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 | 2277 |
| 2304 | 2278 |
| 2305 void LockingMessageQueue::Clear() { | 2279 void LockingMessageQueue::Clear() { |
| 2306 ScopedLock sl(lock_); | 2280 ScopedLock sl(lock_); |
| 2307 queue_.Clear(); | 2281 queue_.Clear(); |
| 2308 } | 2282 } |
| 2309 | 2283 |
| 2310 #endif // ENABLE_DEBUGGER_SUPPORT | 2284 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2311 | 2285 |
| 2312 } } // namespace v8::internal | 2286 } } // namespace v8::internal |
| OLD | NEW |