diff options
| author | Leon Clarke <leonclarke@google.com> | 2010-01-19 14:06:41 +0000 |
|---|---|---|
| committer | Leon Clarke <leonclarke@google.com> | 2010-01-19 16:34:04 +0000 |
| commit | e46be819fca9468a0cd4e74859ce0f778eb8ca60 (patch) | |
| tree | f9c37105a3367f2ad5d31fbc2cb37b84fa67b59a /src/debug.cc | |
| parent | d0582a6c46733687d045e4188a1bcd0123c758a1 (diff) | |
| download | android_external_v8-e46be819fca9468a0cd4e74859ce0f778eb8ca60.tar.gz android_external_v8-e46be819fca9468a0cd4e74859ce0f778eb8ca60.tar.bz2 android_external_v8-e46be819fca9468a0cd4e74859ce0f778eb8ca60.zip | |
New version of v8 from bleeding edge at revision 3649
Diffstat (limited to 'src/debug.cc')
| -rw-r--r-- | src/debug.cc | 110 |
1 files changed, 96 insertions, 14 deletions
diff --git a/src/debug.cc b/src/debug.cc index 2c4552ef..34b3a6d5 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -1241,12 +1241,14 @@ void Debug::PrepareStep(StepAction step_action, int step_count) { uint32_t key = Smi::cast(*obj)->value(); // Argc in the stub is the number of arguments passed - not the // expected arguments of the called function. - int call_function_arg_count = CodeStub::MinorKeyFromKey(key); + int call_function_arg_count = + CallFunctionStub::ExtractArgcFromMinorKey( + CodeStub::MinorKeyFromKey(key)); ASSERT(call_function_stub->major_key() == CodeStub::MajorKeyFromKey(key)); // Find target function on the expression stack. - // Expression stack lools like this (top to bottom): + // Expression stack looks like this (top to bottom): // argN // ... // arg0 @@ -1759,8 +1761,10 @@ bool Debugger::never_unload_debugger_ = false; v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL; bool Debugger::debugger_unload_pending_ = false; v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; +Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex(); v8::Debug::DebugMessageDispatchHandler Debugger::debug_message_dispatch_handler_ = NULL; +MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL; int Debugger::host_dispatch_micros_ = 100 * 1000; DebuggerAgent* Debugger::agent_ = NULL; LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); @@ -2379,17 +2383,12 @@ void Debugger::ListenersChanged() { if (IsDebuggerActive()) { // Disable the compilation cache when the debugger is active. CompilationCache::Disable(); + debugger_unload_pending_ = false; } else { CompilationCache::Enable(); - // Unload the debugger if event listener and message handler cleared. - if (Debug::InDebugger()) { - // If we are in debugger set the flag to unload the debugger when last - // EnterDebugger on the current stack is destroyed. - debugger_unload_pending_ = true; - } else { - UnloadDebugger(); - } + // Schedule this for later, because we may be in non-V8 thread. + debugger_unload_pending_ = true; } } @@ -2402,8 +2401,14 @@ void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, void Debugger::SetDebugMessageDispatchHandler( - v8::Debug::DebugMessageDispatchHandler handler) { + v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { + ScopedLock with(dispatch_handler_access_); debug_message_dispatch_handler_ = handler; + + if (provide_locker && message_dispatch_helper_thread_ == NULL) { + message_dispatch_helper_thread_ = new MessageDispatchHelperThread; + message_dispatch_helper_thread_->Start(); + } } @@ -2438,8 +2443,16 @@ void Debugger::ProcessCommand(Vector<const uint16_t> command, StackGuard::DebugCommand(); } - if (Debugger::debug_message_dispatch_handler_ != NULL) { - Debugger::debug_message_dispatch_handler_(); + MessageDispatchHelperThread* dispatch_thread; + { + ScopedLock with(dispatch_handler_access_); + dispatch_thread = message_dispatch_helper_thread_; + } + + if (dispatch_thread == NULL) { + CallMessageDispatchHandler(); + } else { + dispatch_thread->Schedule(); } } @@ -2483,7 +2496,24 @@ Handle<Object> Debugger::Call(Handle<JSFunction> fun, } -bool Debugger::StartAgent(const char* name, int port) { +static void StubMessageHandler2(const v8::Debug::Message& message) { + // Simply ignore message. +} + + +bool Debugger::StartAgent(const char* name, int port, + bool wait_for_connection) { + if (wait_for_connection) { + // Suspend V8 if it is already running or set V8 to suspend whenever + // it starts. + // Provide stub message handler; V8 auto-continues each suspend + // when there is no message handler; we doesn't need it. + // Once become suspended, V8 will stay so indefinitely long, until remote + // debugger connects and issues "continue" command. + Debugger::message_handler_ = StubMessageHandler2; + v8::Debug::DebugBreak(); + } + if (Socket::Setup()) { agent_ = new DebuggerAgent(name, port); agent_->Start(); @@ -2509,6 +2539,19 @@ void Debugger::WaitForAgent() { agent_->WaitUntilListening(); } + +void Debugger::CallMessageDispatchHandler() { + v8::Debug::DebugMessageDispatchHandler handler; + { + ScopedLock with(dispatch_handler_access_); + handler = Debugger::debug_message_dispatch_handler_; + } + if (handler != NULL) { + handler(); + } +} + + MessageImpl MessageImpl::NewEvent(DebugEvent event, bool running, Handle<JSObject> exec_state, @@ -2729,6 +2772,45 @@ void LockingCommandMessageQueue::Clear() { queue_.Clear(); } + +MessageDispatchHelperThread::MessageDispatchHelperThread() + : sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()), + already_signalled_(false) { +} + + +MessageDispatchHelperThread::~MessageDispatchHelperThread() { + delete mutex_; + delete sem_; +} + + +void MessageDispatchHelperThread::Schedule() { + { + ScopedLock lock(mutex_); + if (already_signalled_) { + return; + } + already_signalled_ = true; + } + sem_->Signal(); +} + + +void MessageDispatchHelperThread::Run() { + while (true) { + sem_->Wait(); + { + ScopedLock lock(mutex_); + already_signalled_ = false; + } + { + Locker locker; + Debugger::CallMessageDispatchHandler(); + } + } +} + #endif // ENABLE_DEBUGGER_SUPPORT } } // namespace v8::internal |
