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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 // MANUAL indicates that the scope shouldn't actually generate code to set up | 686 // MANUAL indicates that the scope shouldn't actually generate code to set up |
687 // the frame (that is done below). | 687 // the frame (that is done below). |
688 FrameScope frame_scope(masm, StackFrame::MANUAL); | 688 FrameScope frame_scope(masm, StackFrame::MANUAL); |
689 __ pushq(rbp); // Caller's frame pointer. | 689 __ pushq(rbp); // Caller's frame pointer. |
690 __ movp(rbp, rsp); | 690 __ movp(rbp, rsp); |
691 __ Push(rsi); // Callee's context. | 691 __ Push(rsi); // Callee's context. |
692 __ Push(rdi); // Callee's JS function. | 692 __ Push(rdi); // Callee's JS function. |
693 | 693 |
694 // Get the bytecode array from the function object and load the pointer to the | 694 // Get the bytecode array from the function object and load the pointer to the |
695 // first entry into edi (InterpreterBytecodeRegister). | 695 // first entry into edi (InterpreterBytecodeRegister). |
696 __ movp(r14, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 696 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
697 __ movp(r14, FieldOperand(r14, SharedFunctionInfo::kFunctionDataOffset)); | 697 __ movp(kInterpreterBytecodeArrayRegister, |
| 698 FieldOperand(rax, SharedFunctionInfo::kFunctionDataOffset)); |
698 | 699 |
699 if (FLAG_debug_code) { | 700 if (FLAG_debug_code) { |
700 // Check function data field is actually a BytecodeArray object. | 701 // Check function data field is actually a BytecodeArray object. |
701 __ AssertNotSmi(r14); | 702 __ AssertNotSmi(kInterpreterBytecodeArrayRegister); |
702 __ CmpObjectType(r14, BYTECODE_ARRAY_TYPE, rax); | 703 __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE, |
| 704 rax); |
703 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); | 705 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
704 } | 706 } |
705 | 707 |
706 // Allocate the local and temporary register file on the stack. | 708 // Allocate the local and temporary register file on the stack. |
707 { | 709 { |
708 // Load frame size from the BytecodeArray object. | 710 // Load frame size from the BytecodeArray object. |
709 __ movl(rcx, FieldOperand(r14, BytecodeArray::kFrameSizeOffset)); | 711 __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, |
| 712 BytecodeArray::kFrameSizeOffset)); |
710 | 713 |
711 // Do a stack check to ensure we don't go over the limit. | 714 // Do a stack check to ensure we don't go over the limit. |
712 Label ok; | 715 Label ok; |
713 __ movp(rdx, rsp); | 716 __ movp(rdx, rsp); |
714 __ subp(rdx, rcx); | 717 __ subp(rdx, rcx); |
715 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); | 718 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); |
716 __ j(above_equal, &ok, Label::kNear); | 719 __ j(above_equal, &ok, Label::kNear); |
717 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | 720 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
718 __ bind(&ok); | 721 __ bind(&ok); |
719 | 722 |
720 // If ok, push undefined as the initial value for all register file entries. | 723 // If ok, push undefined as the initial value for all register file entries. |
721 // Note: there should always be at least one stack slot for the return | |
722 // register in the register file. | |
723 Label loop_header; | 724 Label loop_header; |
| 725 Label loop_check; |
724 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 726 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
| 727 __ j(always, &loop_check); |
725 __ bind(&loop_header); | 728 __ bind(&loop_header); |
726 // TODO(rmcilroy): Consider doing more than one push per loop iteration. | 729 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
727 __ Push(rdx); | 730 __ Push(rdx); |
728 // Continue loop if not done. | 731 // Continue loop if not done. |
| 732 __ bind(&loop_check); |
729 __ subp(rcx, Immediate(kPointerSize)); | 733 __ subp(rcx, Immediate(kPointerSize)); |
730 __ j(not_equal, &loop_header, Label::kNear); | 734 __ j(greater_equal, &loop_header, Label::kNear); |
731 } | 735 } |
732 | 736 |
733 // TODO(rmcilroy): List of things not currently dealt with here but done in | 737 // TODO(rmcilroy): List of things not currently dealt with here but done in |
734 // fullcodegen's prologue: | 738 // fullcodegen's prologue: |
735 // - Support profiler (specifically profiling_counter). | 739 // - Support profiler (specifically profiling_counter). |
736 // - Call ProfileEntryHookStub when isolate has a function_entry_hook. | 740 // - Call ProfileEntryHookStub when isolate has a function_entry_hook. |
737 // - Allow simulator stop operations if FLAG_stop_at is set. | 741 // - Allow simulator stop operations if FLAG_stop_at is set. |
738 // - Deal with sloppy mode functions which need to replace the | 742 // - Deal with sloppy mode functions which need to replace the |
739 // receiver with the global proxy when called as functions (without an | 743 // receiver with the global proxy when called as functions (without an |
740 // explicit receiver object). | 744 // explicit receiver object). |
(...skipping 12 matching lines...) Expand all Loading... |
753 | 757 |
754 // Perform stack guard check. | 758 // Perform stack guard check. |
755 { | 759 { |
756 Label ok; | 760 Label ok; |
757 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); | 761 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
758 __ j(above_equal, &ok, Label::kNear); | 762 __ j(above_equal, &ok, Label::kNear); |
759 __ CallRuntime(Runtime::kStackGuard, 0); | 763 __ CallRuntime(Runtime::kStackGuard, 0); |
760 __ bind(&ok); | 764 __ bind(&ok); |
761 } | 765 } |
762 | 766 |
763 // Load bytecode offset and dispatch table into registers. | 767 // Load accumulator, register file, bytecode offset, dispatch table into |
764 __ movp(r12, Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); | 768 // registers. |
765 __ LoadRoot(r15, Heap::kInterpreterTableRootIndex); | 769 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); |
766 __ addp(r15, Immediate(FixedArray::kHeaderSize - kHeapObjectTag)); | 770 __ movp(kInterpreterRegisterFileRegister, rbp); |
| 771 __ subp( |
| 772 kInterpreterRegisterFileRegister, |
| 773 Immediate(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 774 __ movp(kInterpreterBytecodeOffsetRegister, |
| 775 Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
| 776 __ LoadRoot(kInterpreterDispatchTableRegister, |
| 777 Heap::kInterpreterTableRootIndex); |
| 778 __ addp(kInterpreterDispatchTableRegister, |
| 779 Immediate(FixedArray::kHeaderSize - kHeapObjectTag)); |
767 | 780 |
768 // Dispatch to the first bytecode handler for the function. | 781 // Dispatch to the first bytecode handler for the function. |
769 __ movzxbp(rax, Operand(r14, r12, times_1, 0)); | 782 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
770 __ movp(rax, Operand(r15, rax, times_pointer_size, 0)); | 783 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
| 784 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
| 785 times_pointer_size, 0)); |
771 // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging | 786 // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging |
772 // and header removal. | 787 // and header removal. |
773 __ addp(rax, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 788 __ addp(rbx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
774 __ jmp(rax); | 789 __ call(rbx); |
775 } | 790 } |
776 | 791 |
777 | 792 |
778 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { | 793 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
779 // TODO(rmcilroy): List of things not currently dealt with here but done in | 794 // TODO(rmcilroy): List of things not currently dealt with here but done in |
780 // fullcodegen's EmitReturnSequence. | 795 // fullcodegen's EmitReturnSequence. |
781 // - Supporting FLAG_trace for Runtime::TraceExit. | 796 // - Supporting FLAG_trace for Runtime::TraceExit. |
782 // - Support profiler (specifically decrementing profiling_counter | 797 // - Support profiler (specifically decrementing profiling_counter |
783 // appropriately and calling out to HandleInterrupts if necessary). | 798 // appropriately and calling out to HandleInterrupts if necessary). |
784 | 799 |
785 // Load return value into r0. | 800 // The return value is in accumulator, which is already in rax. |
786 __ movp(rax, Operand(rbp, -kPointerSize - | 801 |
787 StandardFrameConstants::kFixedFrameSizeFromFp)); | |
788 // Leave the frame (also dropping the register file). | 802 // Leave the frame (also dropping the register file). |
789 __ leave(); | 803 __ leave(); |
790 // Return droping receiver + arguments. | 804 // Return droping receiver + arguments. |
791 // TODO(rmcilroy): Get number of arguments from BytecodeArray. | 805 // TODO(rmcilroy): Get number of arguments from BytecodeArray. |
792 __ Ret(1 * kPointerSize, rcx); | 806 __ Ret(1 * kPointerSize, rcx); |
793 } | 807 } |
794 | 808 |
795 | 809 |
796 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 810 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
797 CallRuntimePassFunction(masm, Runtime::kCompileLazy); | 811 CallRuntimePassFunction(masm, Runtime::kCompileLazy); |
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 __ ret(0); | 1849 __ ret(0); |
1836 } | 1850 } |
1837 | 1851 |
1838 | 1852 |
1839 #undef __ | 1853 #undef __ |
1840 | 1854 |
1841 } // namespace internal | 1855 } // namespace internal |
1842 } // namespace v8 | 1856 } // namespace v8 |
1843 | 1857 |
1844 #endif // V8_TARGET_ARCH_X64 | 1858 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |