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 #ifndef V8_DEBUG_H_ | 5 #ifndef V8_DEBUG_H_ |
6 #define V8_DEBUG_H_ | 6 #define V8_DEBUG_H_ |
7 | 7 |
8 #include "allocation.h" | 8 #include "allocation.h" |
9 #include "arguments.h" | 9 #include "arguments.h" |
10 #include "assembler.h" | 10 #include "assembler.h" |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 // A number of words that should be reserved on stack for the LiveEdit use. | 483 // A number of words that should be reserved on stack for the LiveEdit use. |
484 // Normally equals 1. Stored on stack in form of Smi. | 484 // Normally equals 1. Stored on stack in form of Smi. |
485 static const int kInitialSize; | 485 static const int kInitialSize; |
486 // A value that padding words are filled with (in form of Smi). Going | 486 // A value that padding words are filled with (in form of Smi). Going |
487 // bottom-top, the first word not having this value is a counter word. | 487 // bottom-top, the first word not having this value is a counter word. |
488 static const int kPaddingValue; | 488 static const int kPaddingValue; |
489 }; | 489 }; |
490 | 490 |
491 private: | 491 private: |
492 explicit Debug(Isolate* isolate); | 492 explicit Debug(Isolate* isolate); |
493 ~Debug(); | |
494 | 493 |
495 static bool CompileDebuggerScript(Isolate* isolate, int index); | 494 static bool CompileDebuggerScript(Isolate* isolate, int index); |
496 void ClearOneShot(); | 495 void ClearOneShot(); |
497 void ActivateStepIn(StackFrame* frame); | 496 void ActivateStepIn(StackFrame* frame); |
498 void ClearStepIn(); | 497 void ClearStepIn(); |
499 void ActivateStepOut(StackFrame* frame); | 498 void ActivateStepOut(StackFrame* frame); |
500 void ClearStepNext(); | 499 void ClearStepNext(); |
501 // Returns whether the compile succeeded. | 500 // Returns whether the compile succeeded. |
502 void RemoveDebugInfo(Handle<DebugInfo> debug_info); | 501 void RemoveDebugInfo(Handle<DebugInfo> debug_info); |
503 void SetAfterBreakTarget(JavaScriptFrame* frame); | 502 void SetAfterBreakTarget(JavaScriptFrame* frame); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 private: | 735 private: |
737 Logger* logger_; | 736 Logger* logger_; |
738 CommandMessageQueue queue_; | 737 CommandMessageQueue queue_; |
739 mutable Mutex mutex_; | 738 mutable Mutex mutex_; |
740 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); | 739 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); |
741 }; | 740 }; |
742 | 741 |
743 | 742 |
744 class Debugger { | 743 class Debugger { |
745 public: | 744 public: |
746 ~Debugger(); | |
747 | |
748 void DebugRequest(const uint16_t* json_request, int length); | |
749 | |
750 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( | |
751 Vector<const char> constructor_name, | |
752 int argc, | |
753 Handle<Object> argv[]); | |
754 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); | |
755 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( | |
756 Handle<Object> break_points_hit); | |
757 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( | |
758 Handle<Object> exception, | |
759 bool uncaught, | |
760 Handle<Object> promise); | |
761 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( | |
762 Handle<Script> script, bool before); | |
763 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id); | |
764 | |
765 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); | 745 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); |
766 void OnException(Handle<Object> exception, bool uncaught); | 746 void OnException(Handle<Object> exception, bool uncaught); |
767 void OnBeforeCompile(Handle<Script> script); | 747 void OnBeforeCompile(Handle<Script> script); |
768 | 748 |
769 enum AfterCompileFlags { | 749 enum AfterCompileFlags { |
770 NO_AFTER_COMPILE_FLAGS, | 750 NO_AFTER_COMPILE_FLAGS, |
771 SEND_WHEN_DEBUGGING | 751 SEND_WHEN_DEBUGGING |
772 }; | 752 }; |
773 void OnAfterCompile(Handle<Script> script, | 753 void OnAfterCompile(Handle<Script> script, |
774 AfterCompileFlags after_compile_flags); | 754 AfterCompileFlags after_compile_flags); |
775 void OnScriptCollected(int id); | 755 void OnScriptCollected(int id); |
776 void ProcessDebugEvent(v8::DebugEvent event, | 756 |
777 Handle<JSObject> event_data, | |
778 bool auto_continue); | |
779 void NotifyMessageHandler(v8::DebugEvent event, | |
780 Handle<JSObject> exec_state, | |
781 Handle<JSObject> event_data, | |
782 bool auto_continue); | |
783 void SetEventListener(Handle<Object> callback, Handle<Object> data); | 757 void SetEventListener(Handle<Object> callback, Handle<Object> data); |
784 void SetMessageHandler(v8::Debug::MessageHandler handler); | 758 void SetMessageHandler(v8::Debug::MessageHandler handler); |
785 | 759 |
786 // Invoke the message handler function. | |
787 void InvokeMessageHandler(MessageImpl message); | |
788 | |
789 // Add a debugger command to the command queue. | 760 // Add a debugger command to the command queue. |
790 void EnqueueCommandMessage(Vector<const uint16_t> command, | 761 void EnqueueCommandMessage(Vector<const uint16_t> command, |
791 v8::Debug::ClientData* client_data = NULL); | 762 v8::Debug::ClientData* client_data = NULL); |
792 | 763 |
793 // Check whether there are commands in the command queue. | 764 // Check whether there are commands in the command queue. |
794 bool HasCommands(); | 765 bool HasCommands(); |
795 | 766 |
796 // Enqueue a debugger command to the command queue for event listeners. | 767 // Enqueue a debugger command to the command queue for event listeners. |
797 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); | 768 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); |
798 | 769 |
799 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, | 770 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, |
800 Handle<Object> data); | 771 Handle<Object> data); |
801 | 772 |
802 Handle<Context> GetDebugContext(); | 773 Handle<Context> GetDebugContext(); |
803 | 774 |
804 // Unload the debugger if possible. Only called when no debugger is currently | |
805 // active. | |
806 void UnloadDebugger(); | |
807 friend void ForceUnloadDebugger(); // In test-debug.cc | |
808 | |
809 inline bool EventActive() { | |
810 LockGuard<RecursiveMutex> lock_guard(&debugger_access_); | |
811 | |
812 // Check whether the message handler was been cleared. | |
813 // TODO(yangguo): handle loading and unloading of the debugger differently. | |
814 if (debugger_unload_pending_) { | |
815 if (isolate_->debug()->debugger_entry() == NULL) { | |
816 UnloadDebugger(); | |
817 } | |
818 } | |
819 | |
820 // Currently argument event is not used. | |
821 return !ignore_debugger_ && is_active_; | |
822 } | |
823 | |
824 bool ignore_debugger() const { return ignore_debugger_; } | 775 bool ignore_debugger() const { return ignore_debugger_; } |
825 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } | 776 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } |
826 bool live_edit_enabled() const { | 777 bool live_edit_enabled() const { |
827 return FLAG_enable_liveedit && live_edit_enabled_ ; | 778 return FLAG_enable_liveedit && live_edit_enabled_ ; |
828 } | 779 } |
829 | 780 |
830 bool is_active() { | 781 bool is_active() { return is_active_; } |
831 LockGuard<RecursiveMutex> lock_guard(&debugger_access_); | |
832 return is_active_; | |
833 } | |
834 | 782 |
835 class IgnoreScope { | 783 class IgnoreScope { |
836 public: | 784 public: |
837 explicit IgnoreScope(Debugger* debugger) | 785 explicit IgnoreScope(Debugger* debugger) |
838 : debugger_(debugger), | 786 : debugger_(debugger), |
839 old_state_(debugger_->ignore_debugger_) { | 787 old_state_(debugger_->ignore_debugger_) { |
840 debugger_->ignore_debugger_ = true; | 788 debugger_->ignore_debugger_ = true; |
841 } | 789 } |
842 | 790 |
843 ~IgnoreScope() { | 791 ~IgnoreScope() { |
844 debugger_->ignore_debugger_ = old_state_; | 792 debugger_->ignore_debugger_ = old_state_; |
845 } | 793 } |
846 | 794 |
847 private: | 795 private: |
848 Debugger* debugger_; | 796 Debugger* debugger_; |
849 bool old_state_; | 797 bool old_state_; |
850 DISALLOW_COPY_AND_ASSIGN(IgnoreScope); | 798 DISALLOW_COPY_AND_ASSIGN(IgnoreScope); |
851 }; | 799 }; |
852 | 800 |
853 private: | 801 private: |
854 explicit Debugger(Isolate* isolate); | 802 explicit Debugger(Isolate* isolate); |
| 803 ~Debugger(); |
| 804 |
| 805 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( |
| 806 Vector<const char> constructor_name, |
| 807 int argc, |
| 808 Handle<Object> argv[]); |
| 809 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); |
| 810 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( |
| 811 Handle<Object> break_points_hit); |
| 812 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( |
| 813 Handle<Object> exception, |
| 814 bool uncaught, |
| 815 Handle<Object> promise); |
| 816 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( |
| 817 Handle<Script> script, bool before); |
| 818 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id); |
855 | 819 |
856 void CallEventCallback(v8::DebugEvent event, | 820 void CallEventCallback(v8::DebugEvent event, |
857 Handle<Object> exec_state, | 821 Handle<Object> exec_state, |
858 Handle<Object> event_data, | 822 Handle<Object> event_data, |
859 v8::Debug::ClientData* client_data); | 823 v8::Debug::ClientData* client_data); |
860 void CallCEventCallback(v8::DebugEvent event, | 824 void CallCEventCallback(v8::DebugEvent event, |
861 Handle<Object> exec_state, | 825 Handle<Object> exec_state, |
862 Handle<Object> event_data, | 826 Handle<Object> event_data, |
863 v8::Debug::ClientData* client_data); | 827 v8::Debug::ClientData* client_data); |
864 void CallJSEventCallback(v8::DebugEvent event, | 828 void CallJSEventCallback(v8::DebugEvent event, |
865 Handle<Object> exec_state, | 829 Handle<Object> exec_state, |
866 Handle<Object> event_data); | 830 Handle<Object> event_data); |
867 void ListenersChanged(); | 831 void UpdateState(); |
| 832 |
| 833 void ProcessDebugEvent(v8::DebugEvent event, |
| 834 Handle<JSObject> event_data, |
| 835 bool auto_continue); |
| 836 void NotifyMessageHandler(v8::DebugEvent event, |
| 837 Handle<JSObject> exec_state, |
| 838 Handle<JSObject> event_data, |
| 839 bool auto_continue); |
868 | 840 |
869 // Invoke the message handler function. | 841 // Invoke the message handler function. |
870 void InvokeMessageHandler(MessageImpl message); | 842 void InvokeMessageHandler(MessageImpl message); |
871 | 843 |
872 RecursiveMutex debugger_access_; // Mutex guarding debugger variables. | 844 inline bool EventActive() { |
| 845 // Check whether the message handler was been cleared. |
| 846 // TODO(yangguo): handle loading and unloading of the debugger differently. |
| 847 // Currently argument event is not used. |
| 848 return !ignore_debugger_ && is_active_; |
| 849 } |
| 850 |
873 Handle<Object> event_listener_; // Global handle to listener. | 851 Handle<Object> event_listener_; // Global handle to listener. |
874 Handle<Object> event_listener_data_; | 852 Handle<Object> event_listener_data_; |
875 bool is_active_; | 853 bool is_active_; |
876 bool ignore_debugger_; // Are we temporarily ignoring the debugger? | 854 bool ignore_debugger_; // Are we temporarily ignoring the debugger? |
877 bool live_edit_enabled_; // Enable LiveEdit. | 855 bool live_edit_enabled_; // Enable LiveEdit. |
878 bool never_unload_debugger_; // Can we unload the debugger? | |
879 v8::Debug::MessageHandler message_handler_; | 856 v8::Debug::MessageHandler message_handler_; |
880 bool debugger_unload_pending_; // Was message handler cleared? | 857 bool debugger_unload_pending_; // Was message handler cleared? |
881 | 858 |
882 static const int kQueueInitialSize = 4; | 859 static const int kQueueInitialSize = 4; |
883 LockingCommandMessageQueue command_queue_; | 860 LockingCommandMessageQueue command_queue_; |
884 Semaphore command_received_; // Signaled for each command received. | 861 Semaphore command_received_; // Signaled for each command received. |
885 LockingCommandMessageQueue event_command_queue_; | 862 LockingCommandMessageQueue event_command_queue_; |
886 | 863 |
887 Isolate* isolate_; | 864 Isolate* isolate_; |
888 | 865 |
(...skipping 18 matching lines...) Expand all Loading... |
907 | 884 |
908 // Check whether there are any JavaScript frames on the stack. | 885 // Check whether there are any JavaScript frames on the stack. |
909 inline bool HasJavaScriptFrames() { return has_js_frames_; } | 886 inline bool HasJavaScriptFrames() { return has_js_frames_; } |
910 | 887 |
911 // Get the active context from before entering the debugger. | 888 // Get the active context from before entering the debugger. |
912 inline Handle<Context> GetContext() { return save_.context(); } | 889 inline Handle<Context> GetContext() { return save_.context(); } |
913 | 890 |
914 private: | 891 private: |
915 Isolate* isolate_; | 892 Isolate* isolate_; |
916 EnterDebugger* prev_; // Previous debugger entry if entered recursively. | 893 EnterDebugger* prev_; // Previous debugger entry if entered recursively. |
917 JavaScriptFrameIterator it_; | 894 bool has_js_frames_; // Were there any JavaScript frames? |
918 const bool has_js_frames_; // Were there any JavaScript frames? | |
919 StackFrame::Id break_frame_id_; // Previous break frame id. | 895 StackFrame::Id break_frame_id_; // Previous break frame id. |
920 int break_id_; // Previous break id. | 896 int break_id_; // Previous break id. |
921 bool load_failed_; // Did the debugger fail to load? | 897 bool load_failed_; // Did the debugger fail to load? |
922 SaveContext save_; // Saves previous context. | 898 SaveContext save_; // Saves previous context. |
923 }; | 899 }; |
924 | 900 |
925 | 901 |
926 // Stack allocated class for disabling break. | 902 // Stack allocated class for disabling break. |
927 class DisableBreak BASE_EMBEDDED { | 903 class DisableBreak BASE_EMBEDDED { |
928 public: | 904 public: |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 } | 947 } |
972 } | 948 } |
973 | 949 |
974 private: | 950 private: |
975 Debug::AddressId id_; | 951 Debug::AddressId id_; |
976 }; | 952 }; |
977 | 953 |
978 } } // namespace v8::internal | 954 } } // namespace v8::internal |
979 | 955 |
980 #endif // V8_DEBUG_H_ | 956 #endif // V8_DEBUG_H_ |
OLD | NEW |