| OLD | NEW | 
|---|
| 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 "v8.h" | 5 #include "v8.h" | 
| 6 | 6 | 
| 7 #include "api.h" | 7 #include "api.h" | 
| 8 #include "arguments.h" | 8 #include "arguments.h" | 
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" | 
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" | 
| (...skipping 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2625 | 2625 | 
| 2626 Debugger::Debugger(Isolate* isolate) | 2626 Debugger::Debugger(Isolate* isolate) | 
| 2627     : event_listener_(Handle<Object>()), | 2627     : event_listener_(Handle<Object>()), | 
| 2628       event_listener_data_(Handle<Object>()), | 2628       event_listener_data_(Handle<Object>()), | 
| 2629       is_active_(false), | 2629       is_active_(false), | 
| 2630       ignore_debugger_(false), | 2630       ignore_debugger_(false), | 
| 2631       live_edit_enabled_(true), | 2631       live_edit_enabled_(true), | 
| 2632       never_unload_debugger_(false), | 2632       never_unload_debugger_(false), | 
| 2633       message_handler_(NULL), | 2633       message_handler_(NULL), | 
| 2634       debugger_unload_pending_(false), | 2634       debugger_unload_pending_(false), | 
| 2635       debug_message_dispatch_handler_(NULL), |  | 
| 2636       message_dispatch_helper_thread_(NULL), |  | 
| 2637       agent_(NULL), |  | 
| 2638       command_queue_(isolate->logger(), kQueueInitialSize), | 2635       command_queue_(isolate->logger(), kQueueInitialSize), | 
| 2639       command_received_(0), | 2636       command_received_(0), | 
| 2640       event_command_queue_(isolate->logger(), kQueueInitialSize), | 2637       event_command_queue_(isolate->logger(), kQueueInitialSize), | 
| 2641       isolate_(isolate) { | 2638       isolate_(isolate) { | 
| 2642 } | 2639 } | 
| 2643 | 2640 | 
| 2644 | 2641 | 
| 2645 Debugger::~Debugger() {} | 2642 Debugger::~Debugger() {} | 
| 2646 | 2643 | 
| 2647 | 2644 | 
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3182 | 3179 | 
| 3183 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { | 3180 void Debugger::SetMessageHandler(v8::Debug::MessageHandler2 handler) { | 
| 3184   LockGuard<RecursiveMutex> with(&debugger_access_); | 3181   LockGuard<RecursiveMutex> with(&debugger_access_); | 
| 3185 | 3182 | 
| 3186   message_handler_ = handler; | 3183   message_handler_ = handler; | 
| 3187   ListenersChanged(); | 3184   ListenersChanged(); | 
| 3188   if (handler == NULL) { | 3185   if (handler == NULL) { | 
| 3189     // Send an empty command to the debugger if in a break to make JavaScript | 3186     // Send an empty command to the debugger if in a break to make JavaScript | 
| 3190     // run again if the debugger is closed. | 3187     // run again if the debugger is closed. | 
| 3191     if (isolate_->debug()->InDebugger()) { | 3188     if (isolate_->debug()->InDebugger()) { | 
| 3192       ProcessCommand(Vector<const uint16_t>::empty()); | 3189       EnqueueCommandMessage(Vector<const uint16_t>::empty()); | 
| 3193     } | 3190     } | 
| 3194   } | 3191   } | 
| 3195 } | 3192 } | 
| 3196 | 3193 | 
| 3197 | 3194 | 
| 3198 void Debugger::ListenersChanged() { | 3195 void Debugger::ListenersChanged() { | 
| 3199   LockGuard<RecursiveMutex> with(&debugger_access_); | 3196   LockGuard<RecursiveMutex> with(&debugger_access_); | 
| 3200   is_active_ = message_handler_ != NULL || !event_listener_.is_null(); | 3197   is_active_ = message_handler_ != NULL || !event_listener_.is_null(); | 
| 3201   if (is_active_) { | 3198   if (is_active_) { | 
| 3202     // Disable the compilation cache when the debugger is active. | 3199     // Disable the compilation cache when the debugger is active. | 
| 3203     isolate_->compilation_cache()->Disable(); | 3200     isolate_->compilation_cache()->Disable(); | 
| 3204     debugger_unload_pending_ = false; | 3201     debugger_unload_pending_ = false; | 
| 3205   } else { | 3202   } else { | 
| 3206     isolate_->compilation_cache()->Enable(); | 3203     isolate_->compilation_cache()->Enable(); | 
| 3207     // Unload the debugger if event listener and message handler cleared. | 3204     // Unload the debugger if event listener and message handler cleared. | 
| 3208     // Schedule this for later, because we may be in non-V8 thread. | 3205     // Schedule this for later, because we may be in non-V8 thread. | 
| 3209     debugger_unload_pending_ = true; | 3206     debugger_unload_pending_ = true; | 
| 3210   } | 3207   } | 
| 3211 } | 3208 } | 
| 3212 | 3209 | 
| 3213 | 3210 | 
| 3214 void Debugger::SetDebugMessageDispatchHandler( |  | 
| 3215     v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { |  | 
| 3216   LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |  | 
| 3217   debug_message_dispatch_handler_ = handler; |  | 
| 3218 |  | 
| 3219   if (provide_locker && message_dispatch_helper_thread_ == NULL) { |  | 
| 3220     message_dispatch_helper_thread_ = new MessageDispatchHelperThread(isolate_); |  | 
| 3221     message_dispatch_helper_thread_->Start(); |  | 
| 3222   } |  | 
| 3223 } |  | 
| 3224 |  | 
| 3225 |  | 
| 3226 // Calls the registered debug message handler. This callback is part of the | 3211 // Calls the registered debug message handler. This callback is part of the | 
| 3227 // public API. | 3212 // public API. | 
| 3228 void Debugger::InvokeMessageHandler(MessageImpl message) { | 3213 void Debugger::InvokeMessageHandler(MessageImpl message) { | 
| 3229   LockGuard<RecursiveMutex> with(&debugger_access_); | 3214   LockGuard<RecursiveMutex> with(&debugger_access_); | 
| 3230 | 3215 | 
| 3231   if (message_handler_ != NULL) { | 3216   if (message_handler_ != NULL) { | 
| 3232     message_handler_(message); | 3217     message_handler_(message); | 
| 3233   } | 3218   } | 
| 3234 } | 3219 } | 
| 3235 | 3220 | 
| 3236 | 3221 | 
| 3237 // Puts a command coming from the public API on the queue.  Creates | 3222 // Puts a command coming from the public API on the queue.  Creates | 
| 3238 // a copy of the command string managed by the debugger.  Up to this | 3223 // a copy of the command string managed by the debugger.  Up to this | 
| 3239 // point, the command data was managed by the API client.  Called | 3224 // point, the command data was managed by the API client.  Called | 
| 3240 // by the API client thread. | 3225 // by the API client thread. | 
| 3241 void Debugger::ProcessCommand(Vector<const uint16_t> command, | 3226 void Debugger::EnqueueCommandMessage(Vector<const uint16_t> command, | 
| 3242                               v8::Debug::ClientData* client_data) { | 3227                                      v8::Debug::ClientData* client_data) { | 
| 3243   // Need to cast away const. | 3228   // Need to cast away const. | 
| 3244   CommandMessage message = CommandMessage::New( | 3229   CommandMessage message = CommandMessage::New( | 
| 3245       Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 3230       Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 
| 3246                        command.length()), | 3231                        command.length()), | 
| 3247       client_data); | 3232       client_data); | 
| 3248   isolate_->logger()->DebugTag("Put command on command_queue."); | 3233   isolate_->logger()->DebugTag("Put command on command_queue."); | 
| 3249   command_queue_.Put(message); | 3234   command_queue_.Put(message); | 
| 3250   command_received_.Signal(); | 3235   command_received_.Signal(); | 
| 3251 | 3236 | 
| 3252   // Set the debug command break flag to have the command processed. | 3237   // Set the debug command break flag to have the command processed. | 
| 3253   if (!isolate_->debug()->InDebugger()) { | 3238   if (!isolate_->debug()->InDebugger()) { | 
| 3254     isolate_->stack_guard()->RequestDebugCommand(); | 3239     isolate_->stack_guard()->RequestDebugCommand(); | 
| 3255   } | 3240   } | 
| 3256 |  | 
| 3257   MessageDispatchHelperThread* dispatch_thread; |  | 
| 3258   { |  | 
| 3259     LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |  | 
| 3260     dispatch_thread = message_dispatch_helper_thread_; |  | 
| 3261   } |  | 
| 3262 |  | 
| 3263   if (dispatch_thread == NULL) { |  | 
| 3264     CallMessageDispatchHandler(); |  | 
| 3265   } else { |  | 
| 3266     dispatch_thread->Schedule(); |  | 
| 3267   } |  | 
| 3268 } | 3241 } | 
| 3269 | 3242 | 
| 3270 | 3243 | 
| 3271 bool Debugger::HasCommands() { | 3244 bool Debugger::HasCommands() { | 
| 3272   return !command_queue_.IsEmpty(); | 3245   return !command_queue_.IsEmpty(); | 
| 3273 } | 3246 } | 
| 3274 | 3247 | 
| 3275 | 3248 | 
| 3276 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 3249 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 
| 3277   CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 3250   CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 3305   return Execution::Call( | 3278   return Execution::Call( | 
| 3306       isolate_, | 3279       isolate_, | 
| 3307       fun, | 3280       fun, | 
| 3308       Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), | 3281       Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), | 
| 3309                      isolate_), | 3282                      isolate_), | 
| 3310       ARRAY_SIZE(argv), | 3283       ARRAY_SIZE(argv), | 
| 3311       argv); | 3284       argv); | 
| 3312 } | 3285 } | 
| 3313 | 3286 | 
| 3314 | 3287 | 
| 3315 static void StubMessageHandler2(const v8::Debug::Message& message) { |  | 
| 3316   // Simply ignore message. |  | 
| 3317 } |  | 
| 3318 |  | 
| 3319 |  | 
| 3320 bool Debugger::StartAgent(const char* name, int port, |  | 
| 3321                           bool wait_for_connection) { |  | 
| 3322   if (wait_for_connection) { |  | 
| 3323     // Suspend V8 if it is already running or set V8 to suspend whenever |  | 
| 3324     // it starts. |  | 
| 3325     // Provide stub message handler; V8 auto-continues each suspend |  | 
| 3326     // when there is no message handler; we doesn't need it. |  | 
| 3327     // Once become suspended, V8 will stay so indefinitely long, until remote |  | 
| 3328     // debugger connects and issues "continue" command. |  | 
| 3329     Debugger::message_handler_ = StubMessageHandler2; |  | 
| 3330     v8::Debug::DebugBreak(reinterpret_cast<v8::Isolate*>(isolate_)); |  | 
| 3331   } |  | 
| 3332 |  | 
| 3333   if (agent_ == NULL) { |  | 
| 3334     agent_ = new DebuggerAgent(isolate_, name, port); |  | 
| 3335     agent_->Start(); |  | 
| 3336   } |  | 
| 3337   return true; |  | 
| 3338 } |  | 
| 3339 |  | 
| 3340 |  | 
| 3341 void Debugger::StopAgent() { |  | 
| 3342   if (agent_ != NULL) { |  | 
| 3343     agent_->Shutdown(); |  | 
| 3344     agent_->Join(); |  | 
| 3345     delete agent_; |  | 
| 3346     agent_ = NULL; |  | 
| 3347   } |  | 
| 3348 } |  | 
| 3349 |  | 
| 3350 |  | 
| 3351 void Debugger::WaitForAgent() { |  | 
| 3352   if (agent_ != NULL) |  | 
| 3353     agent_->WaitUntilListening(); |  | 
| 3354 } |  | 
| 3355 |  | 
| 3356 |  | 
| 3357 void Debugger::CallMessageDispatchHandler() { |  | 
| 3358   v8::Debug::DebugMessageDispatchHandler handler; |  | 
| 3359   { |  | 
| 3360     LockGuard<Mutex> lock_guard(&dispatch_handler_access_); |  | 
| 3361     handler = Debugger::debug_message_dispatch_handler_; |  | 
| 3362   } |  | 
| 3363   if (handler != NULL) { |  | 
| 3364     handler(); |  | 
| 3365   } |  | 
| 3366 } |  | 
| 3367 |  | 
| 3368 |  | 
| 3369 EnterDebugger::EnterDebugger(Isolate* isolate) | 3288 EnterDebugger::EnterDebugger(Isolate* isolate) | 
| 3370     : isolate_(isolate), | 3289     : isolate_(isolate), | 
| 3371       prev_(isolate_->debug()->debugger_entry()), | 3290       prev_(isolate_->debug()->debugger_entry()), | 
| 3372       it_(isolate_), | 3291       it_(isolate_), | 
| 3373       has_js_frames_(!it_.done()), | 3292       has_js_frames_(!it_.done()), | 
| 3374       save_(isolate_) { | 3293       save_(isolate_) { | 
| 3375   Debug* debug = isolate_->debug(); | 3294   Debug* debug = isolate_->debug(); | 
| 3376   // Link recursive debugger entry. | 3295   // Link recursive debugger entry. | 
| 3377   debug->set_debugger_entry(this); | 3296   debug->set_debugger_entry(this); | 
| 3378 | 3297 | 
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3696   queue_.Put(message); | 3615   queue_.Put(message); | 
| 3697   logger_->DebugEvent("Put", message.text()); | 3616   logger_->DebugEvent("Put", message.text()); | 
| 3698 } | 3617 } | 
| 3699 | 3618 | 
| 3700 | 3619 | 
| 3701 void LockingCommandMessageQueue::Clear() { | 3620 void LockingCommandMessageQueue::Clear() { | 
| 3702   LockGuard<Mutex> lock_guard(&mutex_); | 3621   LockGuard<Mutex> lock_guard(&mutex_); | 
| 3703   queue_.Clear(); | 3622   queue_.Clear(); | 
| 3704 } | 3623 } | 
| 3705 | 3624 | 
| 3706 |  | 
| 3707 MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) |  | 
| 3708     : Thread("v8:MsgDispHelpr"), |  | 
| 3709       isolate_(isolate), sem_(0), |  | 
| 3710       already_signalled_(false) { |  | 
| 3711 } |  | 
| 3712 |  | 
| 3713 |  | 
| 3714 void MessageDispatchHelperThread::Schedule() { |  | 
| 3715   { |  | 
| 3716     LockGuard<Mutex> lock_guard(&mutex_); |  | 
| 3717     if (already_signalled_) { |  | 
| 3718       return; |  | 
| 3719     } |  | 
| 3720     already_signalled_ = true; |  | 
| 3721   } |  | 
| 3722   sem_.Signal(); |  | 
| 3723 } |  | 
| 3724 |  | 
| 3725 |  | 
| 3726 void MessageDispatchHelperThread::Run() { |  | 
| 3727   while (true) { |  | 
| 3728     sem_.Wait(); |  | 
| 3729     { |  | 
| 3730       LockGuard<Mutex> lock_guard(&mutex_); |  | 
| 3731       already_signalled_ = false; |  | 
| 3732     } |  | 
| 3733     { |  | 
| 3734       Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |  | 
| 3735       isolate_->debugger()->CallMessageDispatchHandler(); |  | 
| 3736     } |  | 
| 3737   } |  | 
| 3738 } |  | 
| 3739 |  | 
| 3740 } }  // namespace v8::internal | 3625 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|