| 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 // Add a debugger command to the command queue. | 760 // Add a debugger command to the command queue. |
| 787 void EnqueueCommandMessage(Vector<const uint16_t> command, | 761 void EnqueueCommandMessage(Vector<const uint16_t> command, |
| 788 v8::Debug::ClientData* client_data = NULL); | 762 v8::Debug::ClientData* client_data = NULL); |
| 789 | 763 |
| 790 // Check whether there are commands in the command queue. | 764 // Check whether there are commands in the command queue. |
| 791 bool HasCommands(); | 765 bool HasCommands(); |
| 792 | 766 |
| 793 // Enqueue a debugger command to the command queue for event listeners. | 767 // Enqueue a debugger command to the command queue for event listeners. |
| 794 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); | 768 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); |
| 795 | 769 |
| 796 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, | 770 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, |
| 797 Handle<Object> data); | 771 Handle<Object> data); |
| 798 | 772 |
| 799 Handle<Context> GetDebugContext(); | 773 Handle<Context> GetDebugContext(); |
| 800 | 774 |
| 801 // Unload the debugger if possible. Only called when no debugger is currently | |
| 802 // active. | |
| 803 void UnloadDebugger(); | |
| 804 friend void ForceUnloadDebugger(); // In test-debug.cc | |
| 805 | |
| 806 inline bool EventActive() { | |
| 807 LockGuard<RecursiveMutex> lock_guard(&debugger_access_); | |
| 808 | |
| 809 // Check whether the message handler was been cleared. | |
| 810 // TODO(yangguo): handle loading and unloading of the debugger differently. | |
| 811 if (debugger_unload_pending_) { | |
| 812 if (isolate_->debug()->debugger_entry() == NULL) { | |
| 813 UnloadDebugger(); | |
| 814 } | |
| 815 } | |
| 816 | |
| 817 // Currently argument event is not used. | |
| 818 return !ignore_debugger_ && is_active_; | |
| 819 } | |
| 820 | |
| 821 bool ignore_debugger() const { return ignore_debugger_; } | 775 bool ignore_debugger() const { return ignore_debugger_; } |
| 822 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } | 776 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } |
| 823 bool live_edit_enabled() const { | 777 bool live_edit_enabled() const { |
| 824 return FLAG_enable_liveedit && live_edit_enabled_ ; | 778 return FLAG_enable_liveedit && live_edit_enabled_ ; |
| 825 } | 779 } |
| 826 | 780 |
| 827 bool is_active() { | 781 bool is_active() { return is_active_; } |
| 828 LockGuard<RecursiveMutex> lock_guard(&debugger_access_); | |
| 829 return is_active_; | |
| 830 } | |
| 831 | 782 |
| 832 class IgnoreScope { | 783 class IgnoreScope { |
| 833 public: | 784 public: |
| 834 explicit IgnoreScope(Debugger* debugger) | 785 explicit IgnoreScope(Debugger* debugger) |
| 835 : debugger_(debugger), | 786 : debugger_(debugger), |
| 836 old_state_(debugger_->ignore_debugger_) { | 787 old_state_(debugger_->ignore_debugger_) { |
| 837 debugger_->ignore_debugger_ = true; | 788 debugger_->ignore_debugger_ = true; |
| 838 } | 789 } |
| 839 | 790 |
| 840 ~IgnoreScope() { | 791 ~IgnoreScope() { |
| 841 debugger_->ignore_debugger_ = old_state_; | 792 debugger_->ignore_debugger_ = old_state_; |
| 842 } | 793 } |
| 843 | 794 |
| 844 private: | 795 private: |
| 845 Debugger* debugger_; | 796 Debugger* debugger_; |
| 846 bool old_state_; | 797 bool old_state_; |
| 847 DISALLOW_COPY_AND_ASSIGN(IgnoreScope); | 798 DISALLOW_COPY_AND_ASSIGN(IgnoreScope); |
| 848 }; | 799 }; |
| 849 | 800 |
| 850 private: | 801 private: |
| 851 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); |
| 852 | 819 |
| 853 void CallEventCallback(v8::DebugEvent event, | 820 void CallEventCallback(v8::DebugEvent event, |
| 854 Handle<Object> exec_state, | 821 Handle<Object> exec_state, |
| 855 Handle<Object> event_data, | 822 Handle<Object> event_data, |
| 856 v8::Debug::ClientData* client_data); | 823 v8::Debug::ClientData* client_data); |
| 857 void CallCEventCallback(v8::DebugEvent event, | 824 void CallCEventCallback(v8::DebugEvent event, |
| 858 Handle<Object> exec_state, | 825 Handle<Object> exec_state, |
| 859 Handle<Object> event_data, | 826 Handle<Object> event_data, |
| 860 v8::Debug::ClientData* client_data); | 827 v8::Debug::ClientData* client_data); |
| 861 void CallJSEventCallback(v8::DebugEvent event, | 828 void CallJSEventCallback(v8::DebugEvent event, |
| 862 Handle<Object> exec_state, | 829 Handle<Object> exec_state, |
| 863 Handle<Object> event_data); | 830 Handle<Object> event_data); |
| 864 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); |
| 865 | 840 |
| 866 // Invoke the message handler function. | 841 // Invoke the message handler function. |
| 867 void InvokeMessageHandler(MessageImpl message); | 842 void InvokeMessageHandler(MessageImpl message); |
| 868 | 843 |
| 869 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 |
| 870 Handle<Object> event_listener_; // Global handle to listener. | 851 Handle<Object> event_listener_; // Global handle to listener. |
| 871 Handle<Object> event_listener_data_; | 852 Handle<Object> event_listener_data_; |
| 872 bool is_active_; | 853 bool is_active_; |
| 873 bool ignore_debugger_; // Are we temporarily ignoring the debugger? | 854 bool ignore_debugger_; // Are we temporarily ignoring the debugger? |
| 874 bool live_edit_enabled_; // Enable LiveEdit. | 855 bool live_edit_enabled_; // Enable LiveEdit. |
| 875 bool never_unload_debugger_; // Can we unload the debugger? | |
| 876 v8::Debug::MessageHandler message_handler_; | 856 v8::Debug::MessageHandler message_handler_; |
| 877 bool debugger_unload_pending_; // Was message handler cleared? | 857 bool debugger_unload_pending_; // Was message handler cleared? |
| 878 | 858 |
| 879 static const int kQueueInitialSize = 4; | 859 static const int kQueueInitialSize = 4; |
| 880 LockingCommandMessageQueue command_queue_; | 860 LockingCommandMessageQueue command_queue_; |
| 881 Semaphore command_received_; // Signaled for each command received. | 861 Semaphore command_received_; // Signaled for each command received. |
| 882 LockingCommandMessageQueue event_command_queue_; | 862 LockingCommandMessageQueue event_command_queue_; |
| 883 | 863 |
| 884 Isolate* isolate_; | 864 Isolate* isolate_; |
| 885 | 865 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 904 | 884 |
| 905 // Check whether there are any JavaScript frames on the stack. | 885 // Check whether there are any JavaScript frames on the stack. |
| 906 inline bool HasJavaScriptFrames() { return has_js_frames_; } | 886 inline bool HasJavaScriptFrames() { return has_js_frames_; } |
| 907 | 887 |
| 908 // Get the active context from before entering the debugger. | 888 // Get the active context from before entering the debugger. |
| 909 inline Handle<Context> GetContext() { return save_.context(); } | 889 inline Handle<Context> GetContext() { return save_.context(); } |
| 910 | 890 |
| 911 private: | 891 private: |
| 912 Isolate* isolate_; | 892 Isolate* isolate_; |
| 913 EnterDebugger* prev_; // Previous debugger entry if entered recursively. | 893 EnterDebugger* prev_; // Previous debugger entry if entered recursively. |
| 914 JavaScriptFrameIterator it_; | 894 bool has_js_frames_; // Were there any JavaScript frames? |
| 915 const bool has_js_frames_; // Were there any JavaScript frames? | |
| 916 StackFrame::Id break_frame_id_; // Previous break frame id. | 895 StackFrame::Id break_frame_id_; // Previous break frame id. |
| 917 int break_id_; // Previous break id. | 896 int break_id_; // Previous break id. |
| 918 bool load_failed_; // Did the debugger fail to load? | 897 bool load_failed_; // Did the debugger fail to load? |
| 919 SaveContext save_; // Saves previous context. | 898 SaveContext save_; // Saves previous context. |
| 920 }; | 899 }; |
| 921 | 900 |
| 922 | 901 |
| 923 // Stack allocated class for disabling break. | 902 // Stack allocated class for disabling break. |
| 924 class DisableBreak BASE_EMBEDDED { | 903 class DisableBreak BASE_EMBEDDED { |
| 925 public: | 904 public: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 } | 947 } |
| 969 } | 948 } |
| 970 | 949 |
| 971 private: | 950 private: |
| 972 Debug::AddressId id_; | 951 Debug::AddressId id_; |
| 973 }; | 952 }; |
| 974 | 953 |
| 975 } } // namespace v8::internal | 954 } } // namespace v8::internal |
| 976 | 955 |
| 977 #endif // V8_DEBUG_H_ | 956 #endif // V8_DEBUG_H_ |
| OLD | NEW |