| 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 __ Push(rdx); | 683 __ Push(rdx); |
| 684 // Continue loop if not done. | 684 // Continue loop if not done. |
| 685 __ bind(&loop_check); | 685 __ bind(&loop_check); |
| 686 __ subp(rcx, Immediate(kPointerSize)); | 686 __ subp(rcx, Immediate(kPointerSize)); |
| 687 __ j(greater_equal, &loop_header, Label::kNear); | 687 __ j(greater_equal, &loop_header, Label::kNear); |
| 688 } | 688 } |
| 689 | 689 |
| 690 // Load accumulator, register file, bytecode offset, dispatch table into | 690 // Load accumulator, register file, bytecode offset, dispatch table into |
| 691 // registers. | 691 // registers. |
| 692 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); | 692 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); |
| 693 __ movp(kInterpreterRegisterFileRegister, rbp); | 693 __ movp(r11, rbp); |
| 694 __ addp(kInterpreterRegisterFileRegister, | 694 __ addp(r11, Immediate(InterpreterFrameConstants::kRegisterFileFromFp)); |
| 695 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); | |
| 696 __ movp(kInterpreterBytecodeOffsetRegister, | 695 __ movp(kInterpreterBytecodeOffsetRegister, |
| 697 Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); | 696 Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
| 698 __ Move( | 697 __ Move( |
| 699 kInterpreterDispatchTableRegister, | 698 kInterpreterDispatchTableRegister, |
| 700 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); | 699 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); |
| 701 | 700 |
| 702 // Dispatch to the first bytecode handler for the function. | 701 // Dispatch to the first bytecode handler for the function. |
| 703 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, | 702 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
| 704 kInterpreterBytecodeOffsetRegister, times_1, 0)); | 703 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
| 705 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, | 704 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
| 706 times_pointer_size, 0)); | 705 times_pointer_size, 0)); |
| 707 __ call(rbx); | 706 __ call(rbx); |
| 708 | 707 |
| 709 // Even though the first bytecode handler was called, we will never return. | 708 // Even though the first bytecode handler was called, we will never return. |
| 710 __ Abort(kUnexpectedReturnFromBytecodeHandler); | 709 __ Abort(kUnexpectedReturnFromBytecodeHandler); |
| 711 | 710 |
| 712 // Load debug copy of the bytecode array. | 711 // Load debug copy of the bytecode array. |
| 713 __ bind(&load_debug_bytecode_array); | 712 __ bind(&load_debug_bytecode_array); |
| 714 Register debug_info = kInterpreterBytecodeArrayRegister; | 713 Register debug_info = kInterpreterBytecodeArrayRegister; |
| 715 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); | 714 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); |
| 716 __ movp(kInterpreterBytecodeArrayRegister, | 715 __ movp(kInterpreterBytecodeArrayRegister, |
| 717 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); | 716 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
| 718 __ jmp(&bytecode_array_loaded); | 717 __ jmp(&bytecode_array_loaded); |
| 719 } | 718 } |
| 720 | 719 |
| 721 | 720 |
| 722 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { | 721 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
| 723 // TODO(rmcilroy): List of things not currently dealt with here but done in | |
| 724 // fullcodegen's EmitReturnSequence. | |
| 725 // - Supporting FLAG_trace for Runtime::TraceExit. | |
| 726 // - Support profiler (specifically decrementing profiling_counter | |
| 727 // appropriately and calling out to HandleInterrupts if necessary). | |
| 728 | |
| 729 // The return value is in accumulator, which is already in rax. | 722 // The return value is in accumulator, which is already in rax. |
| 730 | 723 |
| 731 // Leave the frame (also dropping the register file). | 724 // Leave the frame (also dropping the register file). |
| 732 __ leave(); | 725 __ leave(); |
| 733 | 726 |
| 734 // Drop receiver + arguments and return. | 727 // Drop receiver + arguments and return. |
| 735 __ movl(rbx, FieldOperand(kInterpreterBytecodeArrayRegister, | 728 __ movl(rbx, FieldOperand(kInterpreterBytecodeArrayRegister, |
| 736 BytecodeArray::kParameterSizeOffset)); | 729 BytecodeArray::kParameterSizeOffset)); |
| 737 __ PopReturnAddressTo(rcx); | 730 __ PopReturnAddressTo(rcx); |
| 738 __ addp(rsp, rbx); | 731 __ addp(rsp, rbx); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 | 811 |
| 819 // Push return address in preparation for the tail-call. | 812 // Push return address in preparation for the tail-call. |
| 820 __ PushReturnAddressFrom(kScratchRegister); | 813 __ PushReturnAddressFrom(kScratchRegister); |
| 821 | 814 |
| 822 // Call the constructor (rax, rdx, rdi passed on). | 815 // Call the constructor (rax, rdx, rdi passed on). |
| 823 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 816 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 824 } | 817 } |
| 825 | 818 |
| 826 | 819 |
| 827 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { | 820 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { |
| 828 // Initialize register file register and dispatch table register. | 821 // Initialize dispatch table register. |
| 829 __ movp(kInterpreterRegisterFileRegister, rbp); | |
| 830 __ addp(kInterpreterRegisterFileRegister, | |
| 831 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); | |
| 832 __ Move( | 822 __ Move( |
| 833 kInterpreterDispatchTableRegister, | 823 kInterpreterDispatchTableRegister, |
| 834 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); | 824 ExternalReference::interpreter_dispatch_table_address(masm->isolate())); |
| 835 | 825 |
| 836 // Get the bytecode array pointer from the frame. | 826 // Get the bytecode array pointer from the frame. |
| 837 __ movp( | 827 __ movp(kInterpreterBytecodeArrayRegister, |
| 838 kInterpreterBytecodeArrayRegister, | 828 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); |
| 839 Operand(kInterpreterRegisterFileRegister, | |
| 840 InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer)); | |
| 841 | 829 |
| 842 if (FLAG_debug_code) { | 830 if (FLAG_debug_code) { |
| 843 // Check function data field is actually a BytecodeArray object. | 831 // Check function data field is actually a BytecodeArray object. |
| 844 __ AssertNotSmi(kInterpreterBytecodeArrayRegister); | 832 __ AssertNotSmi(kInterpreterBytecodeArrayRegister); |
| 845 __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, | 833 __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, |
| 846 rbx); | 834 rbx); |
| 847 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 835 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
| 848 } | 836 } |
| 849 | 837 |
| 850 // Get the target bytecode offset from the frame. | 838 // Get the target bytecode offset from the frame. |
| 851 __ movp( | 839 __ movp(kInterpreterBytecodeOffsetRegister, |
| 852 kInterpreterBytecodeOffsetRegister, | 840 Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); |
| 853 Operand(kInterpreterRegisterFileRegister, | |
| 854 InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer)); | |
| 855 __ SmiToInteger32(kInterpreterBytecodeOffsetRegister, | 841 __ SmiToInteger32(kInterpreterBytecodeOffsetRegister, |
| 856 kInterpreterBytecodeOffsetRegister); | 842 kInterpreterBytecodeOffsetRegister); |
| 857 | 843 |
| 858 // Dispatch to the target bytecode. | 844 // Dispatch to the target bytecode. |
| 859 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, | 845 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
| 860 kInterpreterBytecodeOffsetRegister, times_1, 0)); | 846 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
| 861 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, | 847 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
| 862 times_pointer_size, 0)); | 848 times_pointer_size, 0)); |
| 863 __ jmp(rbx); | 849 __ jmp(rbx); |
| 864 } | 850 } |
| (...skipping 2066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2931 __ ret(0); | 2917 __ ret(0); |
| 2932 } | 2918 } |
| 2933 | 2919 |
| 2934 | 2920 |
| 2935 #undef __ | 2921 #undef __ |
| 2936 | 2922 |
| 2937 } // namespace internal | 2923 } // namespace internal |
| 2938 } // namespace v8 | 2924 } // namespace v8 |
| 2939 | 2925 |
| 2940 #endif // V8_TARGET_ARCH_X64 | 2926 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |