| 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 |