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 10 matching lines...) Expand all Loading... |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
31 #include "debug.h" | |
32 #include "runtime.h" | |
33 | 31 |
34 namespace v8 { namespace internal { | 32 namespace v8 { namespace internal { |
35 | 33 |
36 | 34 |
37 #define __ masm-> | 35 #define __ masm-> |
38 | 36 |
39 | 37 |
40 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { | 38 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { |
41 // TODO(1238487): Don't pass the function in a static variable. | 39 // TODO(1238487): Don't pass the function in a static variable. |
42 ExternalReference passed = ExternalReference::builtin_passed_function(); | 40 ExternalReference passed = ExternalReference::builtin_passed_function(); |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 __ ret(0); | 747 __ ret(0); |
750 | 748 |
751 // ------------------------------------------- | 749 // ------------------------------------------- |
752 // Dont adapt arguments. | 750 // Dont adapt arguments. |
753 // ------------------------------------------- | 751 // ------------------------------------------- |
754 __ bind(&dont_adapt_arguments); | 752 __ bind(&dont_adapt_arguments); |
755 __ jmp(Operand(edx)); | 753 __ jmp(Operand(edx)); |
756 } | 754 } |
757 | 755 |
758 | 756 |
759 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | |
760 RegList pointer_regs, | |
761 bool convert_call_to_jmp) { | |
762 // Save the content of all general purpose registers in memory. This copy in | |
763 // memory is later pushed onto the JS expression stack for the fake JS frame | |
764 // generated and also to the C frame generated on top of that. In the JS | |
765 // frame ONLY the registers containing pointers will be pushed on the | |
766 // expression stack. This causes the GC to update these pointers so that | |
767 // they will have the correct value when returning from the debugger. | |
768 __ SaveRegistersToMemory(kJSCallerSaved); | |
769 | |
770 // Enter an internal frame. | |
771 __ EnterInternalFrame(); | |
772 | |
773 // Store the registers containing object pointers on the expression stack to | |
774 // make sure that these are correctly updated during GC. | |
775 __ PushRegistersFromMemory(pointer_regs); | |
776 | |
777 #ifdef DEBUG | |
778 __ RecordComment("// Calling from debug break to runtime - come in - over"); | |
779 #endif | |
780 __ Set(eax, Immediate(0)); // no arguments | |
781 __ mov(ebx, Immediate(ExternalReference::debug_break())); | |
782 | |
783 CEntryDebugBreakStub ceb; | |
784 __ CallStub(&ceb); | |
785 | |
786 // Restore the register values containing object pointers from the expression | |
787 // stack in the reverse order as they where pushed. | |
788 __ PopRegistersToMemory(pointer_regs); | |
789 | |
790 // Get rid of the internal frame. | |
791 __ LeaveInternalFrame(); | |
792 | |
793 // If this call did not replace a call but patched other code then there will | |
794 // be an unwanted return address left on the stack. Here we get rid of that. | |
795 if (convert_call_to_jmp) { | |
796 __ pop(eax); | |
797 } | |
798 | |
799 // Finally restore all registers. | |
800 __ RestoreRegistersFromMemory(kJSCallerSaved); | |
801 | |
802 // Now that the break point has been handled, resume normal execution by | |
803 // jumping to the target address intended by the caller and that was | |
804 // overwritten by the address of DebugBreakXXX. | |
805 ExternalReference after_break_target = | |
806 ExternalReference(Debug_Address::AfterBreakTarget()); | |
807 __ jmp(Operand::StaticVariable(after_break_target)); | |
808 } | |
809 | |
810 | |
811 void Builtins::Generate_LoadIC_DebugBreak(MacroAssembler* masm) { | |
812 // Register state for IC load call (from ic-ia32.cc). | |
813 // ----------- S t a t e ------------- | |
814 // -- ecx : name | |
815 // ----------------------------------- | |
816 Generate_DebugBreakCallHelper(masm, ecx.bit(), false); | |
817 } | |
818 | |
819 | |
820 void Builtins::Generate_StoreIC_DebugBreak(MacroAssembler* masm) { | |
821 // REgister state for IC store call (from ic-ia32.cc). | |
822 // ----------- S t a t e ------------- | |
823 // -- eax : value | |
824 // -- ecx : name | |
825 // ----------------------------------- | |
826 Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), false); | |
827 } | |
828 | |
829 | |
830 void Builtins::Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) { | |
831 // Register state for keyed IC load call (from ic-ia32.cc). | |
832 // ----------- S t a t e ------------- | |
833 // No registers used on entry. | |
834 // ----------------------------------- | |
835 Generate_DebugBreakCallHelper(masm, 0, false); | |
836 } | |
837 | |
838 | |
839 void Builtins::Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) { | |
840 // Register state for keyed IC load call (from ic-ia32.cc). | |
841 // ----------- S t a t e ------------- | |
842 // -- eax : value | |
843 // ----------------------------------- | |
844 // Register eax contains an object that needs to be pushed on the | |
845 // expression stack of the fake JS frame. | |
846 Generate_DebugBreakCallHelper(masm, eax.bit(), false); | |
847 } | |
848 | |
849 | |
850 void Builtins::Generate_CallIC_DebugBreak(MacroAssembler* masm) { | |
851 // Register state for keyed IC call call (from ic-ia32.cc) | |
852 // ----------- S t a t e ------------- | |
853 // -- eax: number of arguments | |
854 // ----------------------------------- | |
855 // The number of arguments in eax is not smi encoded. | |
856 Generate_DebugBreakCallHelper(masm, 0, false); | |
857 } | |
858 | |
859 | |
860 void Builtins::Generate_ConstructCall_DebugBreak(MacroAssembler* masm) { | |
861 // Register state just before return from JS function (from codegen-ia32.cc). | |
862 // eax is the actual number of arguments not encoded as a smi see comment | |
863 // above IC call. | |
864 // ----------- S t a t e ------------- | |
865 // -- eax: number of arguments | |
866 // ----------------------------------- | |
867 // The number of arguments in eax is not smi encoded. | |
868 Generate_DebugBreakCallHelper(masm, 0, false); | |
869 } | |
870 | |
871 | |
872 void Builtins::Generate_Return_DebugBreak(MacroAssembler* masm) { | |
873 // Register state just before return from JS function (from codegen-ia32.cc). | |
874 // ----------- S t a t e ------------- | |
875 // -- eax: return value | |
876 // ----------------------------------- | |
877 Generate_DebugBreakCallHelper(masm, eax.bit(), true); | |
878 } | |
879 | |
880 | |
881 void Builtins::Generate_Return_DebugBreakEntry(MacroAssembler* masm) { | |
882 // OK to clobber ebx as we are returning from a JS function in the code | |
883 // generated by Ia32CodeGenerator::ExitJSFrame. | |
884 ExternalReference debug_break_return = | |
885 ExternalReference(Debug_Address::DebugBreakReturn()); | |
886 __ mov(ebx, Operand::StaticVariable(debug_break_return)); | |
887 __ add(Operand(ebx), Immediate(Code::kHeaderSize - kHeapObjectTag)); | |
888 __ jmp(Operand(ebx)); | |
889 } | |
890 | |
891 | |
892 void Builtins::Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) { | |
893 // Register state for stub CallFunction (from CallFunctionStub in ic-ia32.cc). | |
894 // ----------- S t a t e ------------- | |
895 // No registers used on entry. | |
896 // ----------------------------------- | |
897 Generate_DebugBreakCallHelper(masm, 0, false); | |
898 } | |
899 | |
900 #undef __ | 757 #undef __ |
901 | 758 |
902 } } // namespace v8::internal | 759 } } // namespace v8::internal |
OLD | NEW |