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" |
11 #include "execution.h" | 11 #include "execution.h" |
12 #include "factory.h" | 12 #include "factory.h" |
13 #include "flags.h" | 13 #include "flags.h" |
14 #include "frames-inl.h" | 14 #include "frames-inl.h" |
15 #include "hashmap.h" | 15 #include "hashmap.h" |
| 16 #include "liveedit.h" |
16 #include "platform.h" | 17 #include "platform.h" |
17 #include "string-stream.h" | 18 #include "string-stream.h" |
18 #include "v8threads.h" | 19 #include "v8threads.h" |
19 | 20 |
20 #include "../include/v8-debug.h" | 21 #include "../include/v8-debug.h" |
21 | 22 |
22 namespace v8 { | 23 namespace v8 { |
23 namespace internal { | 24 namespace internal { |
24 | 25 |
25 | 26 |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 void set_disable_break(bool disable_break) { | 526 void set_disable_break(bool disable_break) { |
526 disable_break_ = disable_break; | 527 disable_break_ = disable_break; |
527 } | 528 } |
528 | 529 |
529 // Getters for the current exception break state. | 530 // Getters for the current exception break state. |
530 bool break_on_exception() { return break_on_exception_; } | 531 bool break_on_exception() { return break_on_exception_; } |
531 bool break_on_uncaught_exception() { | 532 bool break_on_uncaught_exception() { |
532 return break_on_uncaught_exception_; | 533 return break_on_uncaught_exception_; |
533 } | 534 } |
534 | 535 |
535 enum AddressId { | 536 void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, |
536 k_after_break_target_address, | 537 LiveEdit::FrameDropMode mode, |
537 k_restarter_frame_function_pointer | 538 Object** restarter_frame_function_pointer); |
538 }; | |
539 | 539 |
540 // Support for setting the address to jump to when returning from break point. | 540 // Support for setting the address to jump to when returning from break point. |
541 Address after_break_target_address() { | 541 Address after_break_target_address() { |
542 return reinterpret_cast<Address>(&thread_local_.after_break_target_); | 542 return reinterpret_cast<Address>(&thread_local_.after_break_target_); |
543 } | 543 } |
544 | 544 |
545 Address restarter_frame_function_pointer_address() { | 545 Address restarter_frame_function_pointer_address() { |
546 Object*** address = &thread_local_.restarter_frame_function_pointer_; | 546 Object*** address = &thread_local_.restarter_frame_function_pointer_; |
547 return reinterpret_cast<Address>(address); | 547 return reinterpret_cast<Address>(address); |
548 } | 548 } |
549 | 549 |
550 static const int kEstimatedNofDebugInfoEntries = 16; | |
551 static const int kEstimatedNofBreakPointsInFunction = 16; | 550 static const int kEstimatedNofBreakPointsInFunction = 16; |
552 | 551 |
553 // Passed to MakeWeak. | 552 // Passed to MakeWeak. |
554 static void HandleWeakDebugInfo( | 553 static void HandleWeakDebugInfo( |
555 const v8::WeakCallbackData<v8::Value, void>& data); | 554 const v8::WeakCallbackData<v8::Value, void>& data); |
556 | 555 |
557 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc | 556 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc |
558 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc | 557 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc |
559 | 558 |
560 // Threading support. | 559 // Threading support. |
(...skipping 10 matching lines...) Expand all Loading... |
571 void DestroyScriptCache(); | 570 void DestroyScriptCache(); |
572 void AddScriptToScriptCache(Handle<Script> script); | 571 void AddScriptToScriptCache(Handle<Script> script); |
573 Handle<FixedArray> GetLoadedScripts(); | 572 Handle<FixedArray> GetLoadedScripts(); |
574 | 573 |
575 // Record function from which eval was called. | 574 // Record function from which eval was called. |
576 static void RecordEvalCaller(Handle<Script> script); | 575 static void RecordEvalCaller(Handle<Script> script); |
577 | 576 |
578 // Garbage collection notifications. | 577 // Garbage collection notifications. |
579 void AfterGarbageCollection(); | 578 void AfterGarbageCollection(); |
580 | 579 |
581 // Describes how exactly a frame has been dropped from stack. | |
582 enum FrameDropMode { | |
583 // No frame has been dropped. | |
584 FRAMES_UNTOUCHED, | |
585 // The top JS frame had been calling IC stub. IC stub mustn't be called now. | |
586 FRAME_DROPPED_IN_IC_CALL, | |
587 // The top JS frame had been calling debug break slot stub. Patch the | |
588 // address this stub jumps to in the end. | |
589 FRAME_DROPPED_IN_DEBUG_SLOT_CALL, | |
590 // The top JS frame had been calling some C++ function. The return address | |
591 // gets patched automatically. | |
592 FRAME_DROPPED_IN_DIRECT_CALL, | |
593 FRAME_DROPPED_IN_RETURN_CALL, | |
594 CURRENTLY_SET_MODE | |
595 }; | |
596 | |
597 void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | |
598 FrameDropMode mode, | |
599 Object** restarter_frame_function_pointer); | |
600 | |
601 // Initializes an artificial stack frame. The data it contains is used for: | |
602 // a. successful work of frame dropper code which eventually gets control, | |
603 // b. being compatible with regular stack structure for various stack | |
604 // iterators. | |
605 // Returns address of stack allocated pointer to restarted function, | |
606 // the value that is called 'restarter_frame_function_pointer'. The value | |
607 // at this address (possibly updated by GC) may be used later when preparing | |
608 // 'step in' operation. | |
609 static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame, | |
610 Handle<Code> code); | |
611 | |
612 static const int kFrameDropperFrameSize; | |
613 | |
614 // Architecture-specific constant. | |
615 static const bool kFrameDropperSupported; | |
616 | |
617 /** | |
618 * Defines layout of a stack frame that supports padding. This is a regular | |
619 * internal frame that has a flexible stack structure. LiveEdit can shift | |
620 * its lower part up the stack, taking up the 'padding' space when additional | |
621 * stack memory is required. | |
622 * Such frame is expected immediately above the topmost JavaScript frame. | |
623 * | |
624 * Stack Layout: | |
625 * --- Top | |
626 * LiveEdit routine frames | |
627 * --- | |
628 * C frames of debug handler | |
629 * --- | |
630 * ... | |
631 * --- | |
632 * An internal frame that has n padding words: | |
633 * - any number of words as needed by code -- upper part of frame | |
634 * - padding size: a Smi storing n -- current size of padding | |
635 * - padding: n words filled with kPaddingValue in form of Smi | |
636 * - 3 context/type words of a regular InternalFrame | |
637 * - fp | |
638 * --- | |
639 * Topmost JavaScript frame | |
640 * --- | |
641 * ... | |
642 * --- Bottom | |
643 */ | |
644 class FramePaddingLayout : public AllStatic { | |
645 public: | |
646 // Architecture-specific constant. | |
647 static const bool kIsSupported; | |
648 | |
649 // A size of frame base including fp. Padding words starts right above | |
650 // the base. | |
651 static const int kFrameBaseSize = 4; | |
652 | |
653 // A number of words that should be reserved on stack for the LiveEdit use. | |
654 // Normally equals 1. Stored on stack in form of Smi. | |
655 static const int kInitialSize; | |
656 // A value that padding words are filled with (in form of Smi). Going | |
657 // bottom-top, the first word not having this value is a counter word. | |
658 static const int kPaddingValue; | |
659 }; | |
660 | |
661 private: | 580 private: |
662 explicit Debug(Isolate* isolate); | 581 explicit Debug(Isolate* isolate); |
663 | 582 |
664 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( | 583 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( |
665 Vector<const char> constructor_name, | 584 Vector<const char> constructor_name, |
666 int argc, | 585 int argc, |
667 Handle<Object> argv[]); | 586 Handle<Object> argv[]); |
668 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); | 587 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); |
669 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( | 588 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( |
670 Handle<Object> break_points_hit); | 589 Handle<Object> break_points_hit); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 bool disable_break_; | 679 bool disable_break_; |
761 bool break_on_exception_; | 680 bool break_on_exception_; |
762 bool break_on_uncaught_exception_; | 681 bool break_on_uncaught_exception_; |
763 | 682 |
764 ScriptCache* script_cache_; // Cache of all scripts in the heap. | 683 ScriptCache* script_cache_; // Cache of all scripts in the heap. |
765 DebugInfoListNode* debug_info_list_; // List of active debug info objects. | 684 DebugInfoListNode* debug_info_list_; // List of active debug info objects. |
766 | 685 |
767 // Per-thread data. | 686 // Per-thread data. |
768 class ThreadLocal { | 687 class ThreadLocal { |
769 public: | 688 public: |
| 689 // Top debugger entry. |
| 690 EnterDebugger* debugger_entry_; |
| 691 |
770 // Counter for generating next break id. | 692 // Counter for generating next break id. |
771 int break_count_; | 693 int break_count_; |
772 | 694 |
773 // Current break id. | 695 // Current break id. |
774 int break_id_; | 696 int break_id_; |
775 | 697 |
776 // Frame id for the frame of the current break. | 698 // Frame id for the frame of the current break. |
777 StackFrame::Id break_frame_id_; | 699 StackFrame::Id break_frame_id_; |
778 | 700 |
779 // Step action for last step performed. | 701 // Step action for last step performed. |
(...skipping 14 matching lines...) Expand all Loading... |
794 // Frame pointer for frame from which step in was performed. | 716 // Frame pointer for frame from which step in was performed. |
795 Address step_into_fp_; | 717 Address step_into_fp_; |
796 | 718 |
797 // Frame pointer for the frame where debugger should be called when current | 719 // Frame pointer for the frame where debugger should be called when current |
798 // step out action is completed. | 720 // step out action is completed. |
799 Address step_out_fp_; | 721 Address step_out_fp_; |
800 | 722 |
801 // Storage location for jump when exiting debug break calls. | 723 // Storage location for jump when exiting debug break calls. |
802 Address after_break_target_; | 724 Address after_break_target_; |
803 | 725 |
804 // Stores the way how LiveEdit has patched the stack. It is used when | |
805 // debugger returns control back to user script. | |
806 FrameDropMode frame_drop_mode_; | |
807 | |
808 // Top debugger entry. | |
809 EnterDebugger* debugger_entry_; | |
810 | |
811 // Pending interrupts scheduled while debugging. | 726 // Pending interrupts scheduled while debugging. |
812 bool has_pending_interrupt_; | 727 bool has_pending_interrupt_; |
813 | 728 |
| 729 // Stores the way how LiveEdit has patched the stack. It is used when |
| 730 // debugger returns control back to user script. |
| 731 LiveEdit::FrameDropMode frame_drop_mode_; |
| 732 |
814 // When restarter frame is on stack, stores the address | 733 // When restarter frame is on stack, stores the address |
815 // of the pointer to function being restarted. Otherwise (most of the time) | 734 // of the pointer to function being restarted. Otherwise (most of the time) |
816 // stores NULL. This pointer is used with 'step in' implementation. | 735 // stores NULL. This pointer is used with 'step in' implementation. |
817 Object** restarter_frame_function_pointer_; | 736 Object** restarter_frame_function_pointer_; |
818 | 737 |
819 // When a promise is being resolved, we may want to trigger a debug event | 738 // When a promise is being resolved, we may want to trigger a debug event |
820 // if we catch a throw. For this purpose we remember the try-catch | 739 // if we catch a throw. For this purpose we remember the try-catch |
821 // handler address that would catch the exception. We also hold onto a | 740 // handler address that would catch the exception. We also hold onto a |
822 // closure that returns a promise if the exception is considered uncaught. | 741 // closure that returns a promise if the exception is considered uncaught. |
823 // Due to the possibility of reentry we use a linked list. | 742 // Due to the possibility of reentry we use a linked list. |
824 PromiseOnStack* promise_on_stack_; | 743 PromiseOnStack* promise_on_stack_; |
825 }; | 744 }; |
826 | 745 |
827 // Storage location for registers when handling debug break calls | 746 // Storage location for registers when handling debug break calls |
828 ThreadLocal thread_local_; | 747 ThreadLocal thread_local_; |
829 | 748 |
830 Isolate* isolate_; | 749 Isolate* isolate_; |
831 | 750 |
832 friend class Isolate; | 751 friend class Isolate; |
833 friend class EnterDebugger; | 752 friend class EnterDebugger; |
| 753 friend class FrameDropper; |
834 | 754 |
835 DISALLOW_COPY_AND_ASSIGN(Debug); | 755 DISALLOW_COPY_AND_ASSIGN(Debug); |
836 }; | 756 }; |
837 | 757 |
838 | 758 |
839 DECLARE_RUNTIME_FUNCTION(Debug_Break); | 759 DECLARE_RUNTIME_FUNCTION(Debug_Break); |
840 | 760 |
841 | 761 |
842 // This class is used for entering the debugger. Create an instance in the stack | 762 // This class is used for entering the debugger. Create an instance in the stack |
843 // to enter the debugger. This will set the current break state, make sure the | 763 // to enter the debugger. This will set the current break state, make sure the |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
905 static void GenerateSlotDebugBreak(MacroAssembler* masm); | 825 static void GenerateSlotDebugBreak(MacroAssembler* masm); |
906 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm); | 826 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm); |
907 | 827 |
908 // FrameDropper is a code replacement for a JavaScript frame with possibly | 828 // FrameDropper is a code replacement for a JavaScript frame with possibly |
909 // several frames above. | 829 // several frames above. |
910 // There is no calling conventions here, because it never actually gets | 830 // There is no calling conventions here, because it never actually gets |
911 // called, it only gets returned to. | 831 // called, it only gets returned to. |
912 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); | 832 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); |
913 }; | 833 }; |
914 | 834 |
| 835 |
915 } } // namespace v8::internal | 836 } } // namespace v8::internal |
916 | 837 |
917 #endif // V8_DEBUG_H_ | 838 #endif // V8_DEBUG_H_ |
OLD | NEW |