OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2605 event_listener_(Handle<Object>()), | 2605 event_listener_(Handle<Object>()), |
2606 event_listener_data_(Handle<Object>()), | 2606 event_listener_data_(Handle<Object>()), |
2607 compiling_natives_(false), | 2607 compiling_natives_(false), |
2608 is_loading_debugger_(false), | 2608 is_loading_debugger_(false), |
2609 live_edit_enabled_(true), | 2609 live_edit_enabled_(true), |
2610 never_unload_debugger_(false), | 2610 never_unload_debugger_(false), |
2611 force_debugger_active_(false), | 2611 force_debugger_active_(false), |
2612 message_handler_(NULL), | 2612 message_handler_(NULL), |
2613 debugger_unload_pending_(false), | 2613 debugger_unload_pending_(false), |
2614 host_dispatch_handler_(NULL), | 2614 host_dispatch_handler_(NULL), |
2615 dispatch_handler_access_(OS::CreateMutex()), | |
2616 debug_message_dispatch_handler_(NULL), | 2615 debug_message_dispatch_handler_(NULL), |
2617 message_dispatch_helper_thread_(NULL), | 2616 message_dispatch_helper_thread_(NULL), |
2618 host_dispatch_micros_(100 * 1000), | 2617 host_dispatch_micros_(100 * 1000), |
2619 agent_(NULL), | 2618 agent_(NULL), |
2620 command_queue_(isolate->logger(), kQueueInitialSize), | 2619 command_queue_(isolate->logger(), kQueueInitialSize), |
2621 command_received_(OS::CreateSemaphore(0)), | 2620 command_received_(OS::CreateSemaphore(0)), |
2622 event_command_queue_(isolate->logger(), kQueueInitialSize), | 2621 event_command_queue_(isolate->logger(), kQueueInitialSize), |
2623 isolate_(isolate) { | 2622 isolate_(isolate) { |
2624 } | 2623 } |
2625 | 2624 |
2626 | 2625 |
2627 Debugger::~Debugger() { | 2626 Debugger::~Debugger() { |
2628 delete dispatch_handler_access_; | |
2629 dispatch_handler_access_ = 0; | |
2630 delete command_received_; | 2627 delete command_received_; |
2631 command_received_ = 0; | 2628 command_received_ = 0; |
2632 } | 2629 } |
2633 | 2630 |
2634 | 2631 |
2635 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, | 2632 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, |
2636 int argc, | 2633 int argc, |
2637 Handle<Object> argv[], | 2634 Handle<Object> argv[], |
2638 bool* caught_exception) { | 2635 bool* caught_exception) { |
2639 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 2636 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 } | 3262 } |
3266 event_listener_data_ = Handle<Object>::cast( | 3263 event_listener_data_ = Handle<Object>::cast( |
3267 global_handles->Create(*data)); | 3264 global_handles->Create(*data)); |
3268 } | 3265 } |
3269 | 3266 |
3270 ListenersChanged(); | 3267 ListenersChanged(); |
3271 } | 3268 } |
3272 | 3269 |
3273 | 3270 |
3274 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { | 3271 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { |
3275 ScopedLock with(debugger_access_); | 3272 LockGuard<RecursiveMutex> with(debugger_access_); |
3276 | 3273 |
3277 message_handler_ = handler; | 3274 message_handler_ = handler; |
3278 ListenersChanged(); | 3275 ListenersChanged(); |
3279 if (handler == NULL) { | 3276 if (handler == NULL) { |
3280 // Send an empty command to the debugger if in a break to make JavaScript | 3277 // Send an empty command to the debugger if in a break to make JavaScript |
3281 // run again if the debugger is closed. | 3278 // run again if the debugger is closed. |
3282 if (isolate_->debug()->InDebugger()) { | 3279 if (isolate_->debug()->InDebugger()) { |
3283 ProcessCommand(Vector<const uint16_t>::empty()); | 3280 ProcessCommand(Vector<const uint16_t>::empty()); |
3284 } | 3281 } |
3285 } | 3282 } |
(...skipping 16 matching lines...) Expand all Loading... |
3302 | 3299 |
3303 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, | 3300 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
3304 int period) { | 3301 int period) { |
3305 host_dispatch_handler_ = handler; | 3302 host_dispatch_handler_ = handler; |
3306 host_dispatch_micros_ = period * 1000; | 3303 host_dispatch_micros_ = period * 1000; |
3307 } | 3304 } |
3308 | 3305 |
3309 | 3306 |
3310 void Debugger::SetDebugMessageDispatchHandler( | 3307 void Debugger::SetDebugMessageDispatchHandler( |
3311 v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { | 3308 v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { |
3312 ScopedLock with(dispatch_handler_access_); | 3309 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |
3313 debug_message_dispatch_handler_ = handler; | 3310 debug_message_dispatch_handler_ = handler; |
3314 | 3311 |
3315 if (provide_locker && message_dispatch_helper_thread_ == NULL) { | 3312 if (provide_locker && message_dispatch_helper_thread_ == NULL) { |
3316 message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); | 3313 message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); |
3317 message_dispatch_helper_thread_->Start(); | 3314 message_dispatch_helper_thread_->Start(); |
3318 } | 3315 } |
3319 } | 3316 } |
3320 | 3317 |
3321 | 3318 |
3322 // Calls the registered debug message handler. This callback is part of the | 3319 // Calls the registered debug message handler. This callback is part of the |
3323 // public API. | 3320 // public API. |
3324 void Debugger::InvokeMessageHandler(MessageImpl message) { | 3321 void Debugger::InvokeMessageHandler(MessageImpl message) { |
3325 ScopedLock with(debugger_access_); | 3322 LockGuard<RecursiveMutex> with(debugger_access_); |
3326 | 3323 |
3327 if (message_handler_ != NULL) { | 3324 if (message_handler_ != NULL) { |
3328 message_handler_(message); | 3325 message_handler_(message); |
3329 } | 3326 } |
3330 } | 3327 } |
3331 | 3328 |
3332 | 3329 |
3333 // Puts a command coming from the public API on the queue. Creates | 3330 // Puts a command coming from the public API on the queue. Creates |
3334 // a copy of the command string managed by the debugger. Up to this | 3331 // a copy of the command string managed by the debugger. Up to this |
3335 // point, the command data was managed by the API client. Called | 3332 // point, the command data was managed by the API client. Called |
3336 // by the API client thread. | 3333 // by the API client thread. |
3337 void Debugger::ProcessCommand(Vector<const uint16_t> command, | 3334 void Debugger::ProcessCommand(Vector<const uint16_t> command, |
3338 v8::Debug::ClientData* client_data) { | 3335 v8::Debug::ClientData* client_data) { |
3339 // Need to cast away const. | 3336 // Need to cast away const. |
3340 CommandMessage message = CommandMessage::New( | 3337 CommandMessage message = CommandMessage::New( |
3341 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 3338 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), |
3342 command.length()), | 3339 command.length()), |
3343 client_data); | 3340 client_data); |
3344 isolate_->logger()->DebugTag("Put command on command_queue."); | 3341 isolate_->logger()->DebugTag("Put command on command_queue."); |
3345 command_queue_.Put(message); | 3342 command_queue_.Put(message); |
3346 command_received_->Signal(); | 3343 command_received_->Signal(); |
3347 | 3344 |
3348 // Set the debug command break flag to have the command processed. | 3345 // Set the debug command break flag to have the command processed. |
3349 if (!isolate_->debug()->InDebugger()) { | 3346 if (!isolate_->debug()->InDebugger()) { |
3350 isolate_->stack_guard()->DebugCommand(); | 3347 isolate_->stack_guard()->DebugCommand(); |
3351 } | 3348 } |
3352 | 3349 |
3353 MessageDispatchHelperThread* dispatch_thread; | 3350 MessageDispatchHelperThread* dispatch_thread; |
3354 { | 3351 { |
3355 ScopedLock with(dispatch_handler_access_); | 3352 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |
3356 dispatch_thread = message_dispatch_helper_thread_; | 3353 dispatch_thread = message_dispatch_helper_thread_; |
3357 } | 3354 } |
3358 | 3355 |
3359 if (dispatch_thread == NULL) { | 3356 if (dispatch_thread == NULL) { |
3360 CallMessageDispatchHandler(); | 3357 CallMessageDispatchHandler(); |
3361 } else { | 3358 } else { |
3362 dispatch_thread->Schedule(); | 3359 dispatch_thread->Schedule(); |
3363 } | 3360 } |
3364 } | 3361 } |
3365 | 3362 |
3366 | 3363 |
3367 bool Debugger::HasCommands() { | 3364 bool Debugger::HasCommands() { |
3368 return !command_queue_.IsEmpty(); | 3365 return !command_queue_.IsEmpty(); |
3369 } | 3366 } |
3370 | 3367 |
3371 | 3368 |
3372 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 3369 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { |
3373 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 3370 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); |
3374 event_command_queue_.Put(message); | 3371 event_command_queue_.Put(message); |
3375 | 3372 |
3376 // Set the debug command break flag to have the command processed. | 3373 // Set the debug command break flag to have the command processed. |
3377 if (!isolate_->debug()->InDebugger()) { | 3374 if (!isolate_->debug()->InDebugger()) { |
3378 isolate_->stack_guard()->DebugCommand(); | 3375 isolate_->stack_guard()->DebugCommand(); |
3379 } | 3376 } |
3380 } | 3377 } |
3381 | 3378 |
3382 | 3379 |
3383 bool Debugger::IsDebuggerActive() { | 3380 bool Debugger::IsDebuggerActive() { |
3384 ScopedLock with(debugger_access_); | 3381 LockGuard<RecursiveMutex> with(debugger_access_); |
3385 | 3382 |
3386 return message_handler_ != NULL || | 3383 return message_handler_ != NULL || |
3387 !event_listener_.is_null() || | 3384 !event_listener_.is_null() || |
3388 force_debugger_active_; | 3385 force_debugger_active_; |
3389 } | 3386 } |
3390 | 3387 |
3391 | 3388 |
3392 Handle<Object> Debugger::Call(Handle<JSFunction> fun, | 3389 Handle<Object> Debugger::Call(Handle<JSFunction> fun, |
3393 Handle<Object> data, | 3390 Handle<Object> data, |
3394 bool* pending_exception) { | 3391 bool* pending_exception) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3465 void Debugger::WaitForAgent() { | 3462 void Debugger::WaitForAgent() { |
3466 ASSERT(Isolate::Current() == isolate_); | 3463 ASSERT(Isolate::Current() == isolate_); |
3467 if (agent_ != NULL) | 3464 if (agent_ != NULL) |
3468 agent_->WaitUntilListening(); | 3465 agent_->WaitUntilListening(); |
3469 } | 3466 } |
3470 | 3467 |
3471 | 3468 |
3472 void Debugger::CallMessageDispatchHandler() { | 3469 void Debugger::CallMessageDispatchHandler() { |
3473 v8::Debug::DebugMessageDispatchHandler handler; | 3470 v8::Debug::DebugMessageDispatchHandler handler; |
3474 { | 3471 { |
3475 ScopedLock with(dispatch_handler_access_); | 3472 LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |
3476 handler = Debugger::debug_message_dispatch_handler_; | 3473 handler = Debugger::debug_message_dispatch_handler_; |
3477 } | 3474 } |
3478 if (handler != NULL) { | 3475 if (handler != NULL) { |
3479 handler(); | 3476 handler(); |
3480 } | 3477 } |
3481 } | 3478 } |
3482 | 3479 |
3483 | 3480 |
3484 EnterDebugger::EnterDebugger() | 3481 EnterDebugger::EnterDebugger() |
3485 : isolate_(Isolate::Current()), | 3482 : isolate_(Isolate::Current()), |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3786 CommandMessage* array_to_free = messages_; | 3783 CommandMessage* array_to_free = messages_; |
3787 *this = new_queue; | 3784 *this = new_queue; |
3788 new_queue.messages_ = array_to_free; | 3785 new_queue.messages_ = array_to_free; |
3789 // Make the new_queue empty so that it doesn't call Dispose on any messages. | 3786 // Make the new_queue empty so that it doesn't call Dispose on any messages. |
3790 new_queue.start_ = new_queue.end_; | 3787 new_queue.start_ = new_queue.end_; |
3791 // Automatic destructor called on new_queue, freeing array_to_free. | 3788 // Automatic destructor called on new_queue, freeing array_to_free. |
3792 } | 3789 } |
3793 | 3790 |
3794 | 3791 |
3795 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size) | 3792 LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size) |
3796 : logger_(logger), queue_(size) { | 3793 : logger_(logger), queue_(size) {} |
3797 lock_ = OS::CreateMutex(); | |
3798 } | |
3799 | |
3800 | |
3801 LockingCommandMessageQueue::~LockingCommandMessageQueue() { | |
3802 delete lock_; | |
3803 } | |
3804 | 3794 |
3805 | 3795 |
3806 bool LockingCommandMessageQueue::IsEmpty() const { | 3796 bool LockingCommandMessageQueue::IsEmpty() const { |
3807 ScopedLock sl(lock_); | 3797 LockGuard<Mutex> lock_guard(&mutex_); |
3808 return queue_.IsEmpty(); | 3798 return queue_.IsEmpty(); |
3809 } | 3799 } |
3810 | 3800 |
3811 | 3801 |
3812 CommandMessage LockingCommandMessageQueue::Get() { | 3802 CommandMessage LockingCommandMessageQueue::Get() { |
3813 ScopedLock sl(lock_); | 3803 LockGuard<Mutex> lock_guard(&mutex_); |
3814 CommandMessage result = queue_.Get(); | 3804 CommandMessage result = queue_.Get(); |
3815 logger_->DebugEvent("Get", result.text()); | 3805 logger_->DebugEvent("Get", result.text()); |
3816 return result; | 3806 return result; |
3817 } | 3807 } |
3818 | 3808 |
3819 | 3809 |
3820 void LockingCommandMessageQueue::Put(const CommandMessage& message) { | 3810 void LockingCommandMessageQueue::Put(const CommandMessage& message) { |
3821 ScopedLock sl(lock_); | 3811 LockGuard<Mutex> lock_guard(&mutex_); |
3822 queue_.Put(message); | 3812 queue_.Put(message); |
3823 logger_->DebugEvent("Put", message.text()); | 3813 logger_->DebugEvent("Put", message.text()); |
3824 } | 3814 } |
3825 | 3815 |
3826 | 3816 |
3827 void LockingCommandMessageQueue::Clear() { | 3817 void LockingCommandMessageQueue::Clear() { |
3828 ScopedLock sl(lock_); | 3818 LockGuard<Mutex> lock_guard(&mutex_); |
3829 queue_.Clear(); | 3819 queue_.Clear(); |
3830 } | 3820 } |
3831 | 3821 |
3832 | 3822 |
3833 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) | 3823 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) |
3834 : Thread("v8:MsgDispHelpr"), | 3824 : Thread("v8:MsgDispHelpr"), |
3835 isolate_(isolate), sem_(OS::CreateSemaphore(0)), | 3825 isolate_(isolate), sem_(OS::CreateSemaphore(0)), |
3836 mutex_(OS::CreateMutex()), already_signalled_(false) { | 3826 already_signalled_(false) { |
3837 } | 3827 } |
3838 | 3828 |
3839 | 3829 |
3840 MessageDispatchHelperThread::~MessageDispatchHelperThread() { | 3830 MessageDispatchHelperThread::~MessageDispatchHelperThread() { |
3841 delete mutex_; | |
3842 delete sem_; | 3831 delete sem_; |
3843 } | 3832 } |
3844 | 3833 |
3845 | 3834 |
3846 void MessageDispatchHelperThread::Schedule() { | 3835 void MessageDispatchHelperThread::Schedule() { |
3847 { | 3836 { |
3848 ScopedLock lock(mutex_); | 3837 LockGuard<Mutex> lock_guard(&mutex_); |
3849 if (already_signalled_) { | 3838 if (already_signalled_) { |
3850 return; | 3839 return; |
3851 } | 3840 } |
3852 already_signalled_ = true; | 3841 already_signalled_ = true; |
3853 } | 3842 } |
3854 sem_->Signal(); | 3843 sem_->Signal(); |
3855 } | 3844 } |
3856 | 3845 |
3857 | 3846 |
3858 void MessageDispatchHelperThread::Run() { | 3847 void MessageDispatchHelperThread::Run() { |
3859 while (true) { | 3848 while (true) { |
3860 sem_->Wait(); | 3849 sem_->Wait(); |
3861 { | 3850 { |
3862 ScopedLock lock(mutex_); | 3851 LockGuard<Mutex> lock_guard(&mutex_); |
3863 already_signalled_ = false; | 3852 already_signalled_ = false; |
3864 } | 3853 } |
3865 { | 3854 { |
3866 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3855 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
3867 isolate_->debugger()->CallMessageDispatchHandler(); | 3856 isolate_->debugger()->CallMessageDispatchHandler(); |
3868 } | 3857 } |
3869 } | 3858 } |
3870 } | 3859 } |
3871 | 3860 |
3872 #endif // ENABLE_DEBUGGER_SUPPORT | 3861 #endif // ENABLE_DEBUGGER_SUPPORT |
3873 | 3862 |
3874 } } // namespace v8::internal | 3863 } } // namespace v8::internal |
OLD | NEW |