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