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 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 659 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
660 Generate_JSEntryTrampolineHelper(masm, false); | 660 Generate_JSEntryTrampolineHelper(masm, false); |
661 } | 661 } |
662 | 662 |
663 | 663 |
664 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 664 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
665 Generate_JSEntryTrampolineHelper(masm, true); | 665 Generate_JSEntryTrampolineHelper(masm, true); |
666 } | 666 } |
667 | 667 |
668 | 668 |
| 669 // Generate code for entering a JS function with the interpreter. |
| 670 // On entry to the function the receiver and arguments have been pushed on the |
| 671 // stack left to right. The actual argument count matches the formal parameter |
| 672 // count expected by the function. |
| 673 // |
| 674 // The live registers are: |
| 675 // o rdi: the JS function object being called |
| 676 // o rsi: our context |
| 677 // o rbp: the caller's frame pointer |
| 678 // o rsp: stack pointer (pointing to return address) |
| 679 // |
| 680 // The function builds a JS frame. Please see JavaScriptFrameConstants in |
| 681 // frames-x64.h for its layout. |
| 682 // TODO(rmcilroy): We will need to include the current bytecode pointer in the |
| 683 // frame. |
| 684 void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
| 685 // Open a frame scope to indicate that there is a frame on the stack. The |
| 686 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 687 // the frame (that is done below). |
| 688 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 689 __ pushq(rbp); // Caller's frame pointer. |
| 690 __ movp(rbp, rsp); |
| 691 __ Push(rsi); // Callee's context. |
| 692 __ Push(rdi); // Callee's JS function. |
| 693 |
| 694 // Get the bytecode array from the function object and load the pointer to the |
| 695 // first entry into edi (InterpreterBytecodeRegister). |
| 696 __ movp(r14, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 697 __ movp(r14, FieldOperand(r14, SharedFunctionInfo::kFunctionDataOffset)); |
| 698 |
| 699 if (FLAG_debug_code) { |
| 700 // Check function data field is actually a BytecodeArray object. |
| 701 __ AssertNotSmi(r14); |
| 702 __ CmpObjectType(r14, BYTECODE_ARRAY_TYPE, rax); |
| 703 __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
| 704 } |
| 705 |
| 706 // Allocate the local and temporary register file on the stack. |
| 707 { |
| 708 // Load frame size from the BytecodeArray object. |
| 709 __ movl(rcx, FieldOperand(r14, BytecodeArray::kFrameSizeOffset)); |
| 710 |
| 711 // Do a stack check to ensure we don't go over the limit. |
| 712 Label ok; |
| 713 __ movp(rdx, rsp); |
| 714 __ subp(rdx, rcx); |
| 715 __ CompareRoot(rdx, Heap::kRealStackLimitRootIndex); |
| 716 __ j(above_equal, &ok, Label::kNear); |
| 717 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 718 __ bind(&ok); |
| 719 |
| 720 // 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 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
| 725 __ bind(&loop_header); |
| 726 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
| 727 __ Push(rdx); |
| 728 // Continue loop if not done. |
| 729 __ subp(rcx, Immediate(kPointerSize)); |
| 730 __ j(not_equal, &loop_header, Label::kNear); |
| 731 } |
| 732 |
| 733 // TODO(rmcilroy): List of things not currently dealt with here but done in |
| 734 // fullcodegen's prologue: |
| 735 // - Support profiler (specifically profiling_counter). |
| 736 // - Call ProfileEntryHookStub when isolate has a function_entry_hook. |
| 737 // - Allow simulator stop operations if FLAG_stop_at is set. |
| 738 // - Deal with sloppy mode functions which need to replace the |
| 739 // receiver with the global proxy when called as functions (without an |
| 740 // explicit receiver object). |
| 741 // - Code aging of the BytecodeArray object. |
| 742 // - Supporting FLAG_trace. |
| 743 // |
| 744 // The following items are also not done here, and will probably be done using |
| 745 // explicit bytecodes instead: |
| 746 // - Allocating a new local context if applicable. |
| 747 // - Setting up a local binding to the this function, which is used in |
| 748 // derived constructors with super calls. |
| 749 // - Setting new.target if required. |
| 750 // - Dealing with REST parameters (only if |
| 751 // https://codereview.chromium.org/1235153006 doesn't land by then). |
| 752 // - Dealing with argument objects. |
| 753 |
| 754 // Perform stack guard check. |
| 755 { |
| 756 Label ok; |
| 757 __ CompareRoot(rsp, Heap::kStackLimitRootIndex); |
| 758 __ j(above_equal, &ok, Label::kNear); |
| 759 __ CallRuntime(Runtime::kStackGuard, 0); |
| 760 __ bind(&ok); |
| 761 } |
| 762 |
| 763 // Load bytecode offset and dispatch table into registers. |
| 764 __ movp(r12, Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
| 765 __ LoadRoot(r15, Heap::kInterpreterTableRootIndex); |
| 766 __ addp(r15, Immediate(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 767 |
| 768 // Dispatch to the first bytecode handler for the function. |
| 769 __ movzxbp(rax, Operand(r14, r12, times_1, 0)); |
| 770 __ movp(rax, Operand(r15, rax, times_pointer_size, 0)); |
| 771 // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging |
| 772 // and header removal. |
| 773 __ addp(rax, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 774 __ jmp(rax); |
| 775 } |
| 776 |
| 777 |
| 778 void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
| 779 // TODO(rmcilroy): List of things not currently dealt with here but done in |
| 780 // fullcodegen's EmitReturnSequence. |
| 781 // - Supporting FLAG_trace for Runtime::TraceExit. |
| 782 // - Support profiler (specifically decrementing profiling_counter |
| 783 // appropriately and calling out to HandleInterrupts if necessary). |
| 784 |
| 785 // Load return value into r0. |
| 786 __ movp(rax, Operand(rbp, -kPointerSize - |
| 787 StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 788 // Leave the frame (also dropping the register file). |
| 789 __ leave(); |
| 790 // Return droping receiver + arguments. |
| 791 // TODO(rmcilroy): Get number of arguments from BytecodeArray. |
| 792 __ Ret(1 * kPointerSize, rcx); |
| 793 } |
| 794 |
| 795 |
669 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 796 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
670 CallRuntimePassFunction(masm, Runtime::kCompileLazy); | 797 CallRuntimePassFunction(masm, Runtime::kCompileLazy); |
671 GenerateTailCallToReturnedCode(masm); | 798 GenerateTailCallToReturnedCode(masm); |
672 } | 799 } |
673 | 800 |
674 | 801 |
675 static void CallCompileOptimized(MacroAssembler* masm, | 802 static void CallCompileOptimized(MacroAssembler* masm, |
676 bool concurrent) { | 803 bool concurrent) { |
677 FrameScope scope(masm, StackFrame::INTERNAL); | 804 FrameScope scope(masm, StackFrame::INTERNAL); |
678 // Push a copy of the function onto the stack. | 805 // Push a copy of the function onto the stack. |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 __ ret(0); | 1832 __ ret(0); |
1706 } | 1833 } |
1707 | 1834 |
1708 | 1835 |
1709 #undef __ | 1836 #undef __ |
1710 | 1837 |
1711 } // namespace internal | 1838 } // namespace internal |
1712 } // namespace v8 | 1839 } // namespace v8 |
1713 | 1840 |
1714 #endif // V8_TARGET_ARCH_X64 | 1841 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |