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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 static Code* debug_break_return_; | 398 static Code* debug_break_return_; |
399 | 399 |
400 DISALLOW_COPY_AND_ASSIGN(Debug); | 400 DISALLOW_COPY_AND_ASSIGN(Debug); |
401 }; | 401 }; |
402 | 402 |
403 | 403 |
404 // Message send by user to v8 debugger or debugger output message. | 404 // Message send by user to v8 debugger or debugger output message. |
405 // In addition to command text it may contain a pointer to some user data | 405 // In addition to command text it may contain a pointer to some user data |
406 // which are expected to be passed along with the command reponse to message | 406 // which are expected to be passed along with the command reponse to message |
407 // handler. | 407 // handler. |
408 class Message { | 408 class CommandMessage { |
409 public: | 409 public: |
410 static Message NewCommand(const Vector<uint16_t>& command, | 410 static CommandMessage New(const Vector<uint16_t>& command, |
411 v8::Debug::ClientData* data); | 411 v8::Debug::ClientData* data); |
412 static Message NewOutput(v8::Handle<v8::String> output, | 412 CommandMessage(); |
413 v8::Debug::ClientData* data); | 413 ~CommandMessage(); |
414 static Message NewEmptyMessage(); | |
415 Message(); | |
416 ~Message(); | |
417 | 414 |
418 // Deletes user data and disposes of the text. | 415 // Deletes user data and disposes of the text. |
419 void Dispose(); | 416 void Dispose(); |
420 Vector<uint16_t> text() const { return text_; } | 417 Vector<uint16_t> text() const { return text_; } |
421 v8::Debug::ClientData* client_data() const { return client_data_; } | 418 v8::Debug::ClientData* client_data() const { return client_data_; } |
422 private: | 419 private: |
423 Message(const Vector<uint16_t>& text, | 420 CommandMessage(const Vector<uint16_t>& text, |
424 v8::Debug::ClientData* data); | 421 v8::Debug::ClientData* data); |
425 | 422 |
426 Vector<uint16_t> text_; | 423 Vector<uint16_t> text_; |
427 v8::Debug::ClientData* client_data_; | 424 v8::Debug::ClientData* client_data_; |
428 }; | 425 }; |
429 | 426 |
430 // A Queue of Vector<uint16_t> objects. A thread-safe version is | 427 // A Queue of CommandMessage objects. A thread-safe version is |
431 // LockingMessageQueue, based on this class. | 428 // LockingCommandMessageQueue, based on this class. |
432 class MessageQueue BASE_EMBEDDED { | 429 class CommandMessageQueue BASE_EMBEDDED { |
433 public: | 430 public: |
434 explicit MessageQueue(int size); | 431 explicit CommandMessageQueue(int size); |
435 ~MessageQueue(); | 432 ~CommandMessageQueue(); |
436 bool IsEmpty() const { return start_ == end_; } | 433 bool IsEmpty() const { return start_ == end_; } |
437 Message Get(); | 434 CommandMessage Get(); |
438 void Put(const Message& message); | 435 void Put(const CommandMessage& message); |
439 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear(). | 436 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear(). |
440 private: | 437 private: |
441 // Doubles the size of the message queue, and copies the messages. | 438 // Doubles the size of the message queue, and copies the messages. |
442 void Expand(); | 439 void Expand(); |
443 | 440 |
444 Message* messages_; | 441 CommandMessage* messages_; |
445 int start_; | 442 int start_; |
446 int end_; | 443 int end_; |
447 int size_; // The size of the queue buffer. Queue can hold size-1 messages. | 444 int size_; // The size of the queue buffer. Queue can hold size-1 messages. |
448 }; | 445 }; |
449 | 446 |
450 | 447 |
451 // LockingMessageQueue is a thread-safe circular buffer of Vector<uint16_t> | 448 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage |
452 // messages. The message data is not managed by LockingMessageQueue. | 449 // messages. The message data is not managed by LockingCommandMessageQueue. |
453 // Pointers to the data are passed in and out. Implemented by adding a | 450 // Pointers to the data are passed in and out. Implemented by adding a |
454 // Mutex to MessageQueue. Includes logging of all puts and gets. | 451 // Mutex to CommandMessageQueue. Includes logging of all puts and gets. |
455 class LockingMessageQueue BASE_EMBEDDED { | 452 class LockingCommandMessageQueue BASE_EMBEDDED { |
456 public: | 453 public: |
457 explicit LockingMessageQueue(int size); | 454 explicit LockingCommandMessageQueue(int size); |
458 ~LockingMessageQueue(); | 455 ~LockingCommandMessageQueue(); |
459 bool IsEmpty() const; | 456 bool IsEmpty() const; |
460 Message Get(); | 457 CommandMessage Get(); |
461 void Put(const Message& message); | 458 void Put(const CommandMessage& message); |
462 void Clear(); | 459 void Clear(); |
463 private: | 460 private: |
464 MessageQueue queue_; | 461 CommandMessageQueue queue_; |
465 Mutex* lock_; | 462 Mutex* lock_; |
466 DISALLOW_COPY_AND_ASSIGN(LockingMessageQueue); | 463 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); |
467 }; | 464 }; |
468 | 465 |
469 | 466 |
470 class DebugMessageThread; | |
471 | |
472 class Debugger { | 467 class Debugger { |
473 public: | 468 public: |
474 static void DebugRequest(const uint16_t* json_request, int length); | 469 static void DebugRequest(const uint16_t* json_request, int length); |
475 | 470 |
476 static Handle<Object> MakeJSObject(Vector<const char> constructor_name, | 471 static Handle<Object> MakeJSObject(Vector<const char> constructor_name, |
477 int argc, Object*** argv, | 472 int argc, Object*** argv, |
478 bool* caught_exception); | 473 bool* caught_exception); |
479 static Handle<Object> MakeExecutionState(bool* caught_exception); | 474 static Handle<Object> MakeExecutionState(bool* caught_exception); |
480 static Handle<Object> MakeBreakEvent(Handle<Object> exec_state, | 475 static Handle<Object> MakeBreakEvent(Handle<Object> exec_state, |
481 Handle<Object> break_points_hit, | 476 Handle<Object> break_points_hit, |
(...skipping 14 matching lines...) Expand all Loading... |
496 Handle<JSFunction> fun); | 491 Handle<JSFunction> fun); |
497 static void OnNewFunction(Handle<JSFunction> fun); | 492 static void OnNewFunction(Handle<JSFunction> fun); |
498 static void ProcessDebugEvent(v8::DebugEvent event, | 493 static void ProcessDebugEvent(v8::DebugEvent event, |
499 Handle<Object> event_data, | 494 Handle<Object> event_data, |
500 bool auto_continue); | 495 bool auto_continue); |
501 static void NotifyMessageHandler(v8::DebugEvent event, | 496 static void NotifyMessageHandler(v8::DebugEvent event, |
502 Handle<Object> exec_state, | 497 Handle<Object> exec_state, |
503 Handle<Object> event_data, | 498 Handle<Object> event_data, |
504 bool auto_continue); | 499 bool auto_continue); |
505 static void SetEventListener(Handle<Object> callback, Handle<Object> data); | 500 static void SetEventListener(Handle<Object> callback, Handle<Object> data); |
506 static void SetMessageHandler(v8::Debug::MessageHandler handler, | 501 static void SetMessageHandler(v8::Debug::MessageHandler handler); |
507 bool message_handler_thread); | |
508 static void TearDown(); | |
509 static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, | 502 static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
510 int period); | 503 int period); |
511 | 504 |
512 // Invoke the message handler function. | 505 // Invoke the message handler function. |
513 static void InvokeMessageHandler(Message message); | 506 static void InvokeMessageHandler(v8::Handle<v8::String> output, |
514 | 507 v8::Debug::ClientData* data); |
515 // Send a message to the message handler eiher through the message thread or | |
516 // directly. | |
517 static void SendMessage(Message message); | |
518 | 508 |
519 // Send the JSON message for a debug event. | 509 // Send the JSON message for a debug event. |
520 static bool SendEventMessage(Handle<Object> event_data); | 510 static bool InvokeMessageHandlerWithEvent(Handle<Object> event_data); |
521 | 511 |
522 // Add a debugger command to the command queue. | 512 // Add a debugger command to the command queue. |
523 static void ProcessCommand(Vector<const uint16_t> command, | 513 static void ProcessCommand(Vector<const uint16_t> command, |
524 v8::Debug::ClientData* client_data = NULL); | 514 v8::Debug::ClientData* client_data = NULL); |
525 | 515 |
526 // Check whether there are commands in the command queue. | 516 // Check whether there are commands in the command queue. |
527 static bool HasCommands(); | 517 static bool HasCommands(); |
528 | 518 |
529 static Handle<Object> Call(Handle<JSFunction> fun, | 519 static Handle<Object> Call(Handle<JSFunction> fun, |
530 Handle<Object> data, | 520 Handle<Object> data, |
(...skipping 30 matching lines...) Expand all Loading... |
561 | 551 |
562 private: | 552 private: |
563 static bool IsDebuggerActive(); | 553 static bool IsDebuggerActive(); |
564 | 554 |
565 static Mutex* debugger_access_; // Mutex guarding debugger variables. | 555 static Mutex* debugger_access_; // Mutex guarding debugger variables. |
566 static Handle<Object> event_listener_; // Global handle to listener. | 556 static Handle<Object> event_listener_; // Global handle to listener. |
567 static Handle<Object> event_listener_data_; | 557 static Handle<Object> event_listener_data_; |
568 static bool compiling_natives_; // Are we compiling natives? | 558 static bool compiling_natives_; // Are we compiling natives? |
569 static bool is_loading_debugger_; // Are we loading the debugger? | 559 static bool is_loading_debugger_; // Are we loading the debugger? |
570 static bool never_unload_debugger_; // Can we unload the debugger? | 560 static bool never_unload_debugger_; // Can we unload the debugger? |
571 static DebugMessageThread* message_thread_; | |
572 static v8::Debug::MessageHandler message_handler_; | 561 static v8::Debug::MessageHandler message_handler_; |
573 static bool message_handler_cleared_; // Was message handler cleared? | 562 static bool message_handler_cleared_; // Was message handler cleared? |
574 static v8::Debug::HostDispatchHandler host_dispatch_handler_; | 563 static v8::Debug::HostDispatchHandler host_dispatch_handler_; |
575 static int host_dispatch_micros_; | 564 static int host_dispatch_micros_; |
576 | 565 |
577 static DebuggerAgent* agent_; | 566 static DebuggerAgent* agent_; |
578 | 567 |
579 static const int kQueueInitialSize = 4; | 568 static const int kQueueInitialSize = 4; |
580 static LockingMessageQueue command_queue_; | 569 static LockingCommandMessageQueue command_queue_; |
581 static LockingMessageQueue message_queue_; | |
582 static Semaphore* command_received_; // Signaled for each command received. | 570 static Semaphore* command_received_; // Signaled for each command received. |
583 static Semaphore* message_received_; // Signalled for each message send. | |
584 | 571 |
585 friend class EnterDebugger; | 572 friend class EnterDebugger; |
586 friend class DebugMessageThread; | |
587 }; | |
588 | |
589 | |
590 // Thread to read messages from the message queue and invoke the debug message | |
591 // handler in another thread as the V8 thread. This thread is started if the | |
592 // registration of the debug message handler requested to be called in a thread | |
593 // seperate from the V8 thread. | |
594 class DebugMessageThread: public Thread { | |
595 public: | |
596 DebugMessageThread() : keep_running_(true) {} | |
597 virtual ~DebugMessageThread() {} | |
598 | |
599 // Main function of DebugMessageThread thread. | |
600 void Run(); | |
601 void Stop(); | |
602 | |
603 private: | |
604 bool keep_running_; | |
605 DISALLOW_COPY_AND_ASSIGN(DebugMessageThread); | |
606 }; | 573 }; |
607 | 574 |
608 | 575 |
609 // This class is used for entering the debugger. Create an instance in the stack | 576 // This class is used for entering the debugger. Create an instance in the stack |
610 // to enter the debugger. This will set the current break state, make sure the | 577 // to enter the debugger. This will set the current break state, make sure the |
611 // debugger is loaded and switch to the debugger context. If the debugger for | 578 // debugger is loaded and switch to the debugger context. If the debugger for |
612 // some reason could not be entered FailedToEnter will return true. | 579 // some reason could not be entered FailedToEnter will return true. |
613 class EnterDebugger BASE_EMBEDDED { | 580 class EnterDebugger BASE_EMBEDDED { |
614 public: | 581 public: |
615 EnterDebugger() | 582 EnterDebugger() |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
745 Debug::AddressId id_; | 712 Debug::AddressId id_; |
746 int reg_; | 713 int reg_; |
747 }; | 714 }; |
748 | 715 |
749 | 716 |
750 } } // namespace v8::internal | 717 } } // namespace v8::internal |
751 | 718 |
752 #endif // ENABLE_DEBUGGER_SUPPORT | 719 #endif // ENABLE_DEBUGGER_SUPPORT |
753 | 720 |
754 #endif // V8_V8_DEBUG_H_ | 721 #endif // V8_V8_DEBUG_H_ |
OLD | NEW |