Chromium Code Reviews| 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 591 __ SmiToInteger64( | 591 __ SmiToInteger64( |
| 592 rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); | 592 rcx, FieldOperand(rbx, JSGeneratorObject::kContinuationOffset)); |
| 593 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); | 593 __ leap(rdx, FieldOperand(rdx, rcx, times_1, Code::kHeaderSize)); |
| 594 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), | 594 __ Move(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset), |
| 595 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); | 595 Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)); |
| 596 __ movp(rax, rbx); // Continuation expects generator object in rax. | 596 __ movp(rax, rbx); // Continuation expects generator object in rax. |
| 597 __ jmp(rdx); | 597 __ jmp(rdx); |
| 598 } | 598 } |
| 599 } | 599 } |
| 600 | 600 |
| 601 static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch1, | |
| 602 Register scratch2) { | |
| 603 Register args_count = scratch1; | |
| 604 Register return_pc = scratch2; | |
| 605 | |
| 606 // Get the arguments + reciever count. | |
| 607 __ movp(args_count, | |
| 608 Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | |
| 609 __ movl(args_count, | |
| 610 FieldOperand(args_count, BytecodeArray::kParameterSizeOffset)); | |
| 611 | |
| 612 // Leave the before recompiling for baseline so that we don't count as an | |
| 613 // activation on the stack. | |
|
Michael Starzinger
2016/05/13 09:01:40
nit: Can we keep the generic "Leave the frame (als
rmcilroy
2016/05/17 11:28:30
Done.
| |
| 614 __ leave(); | |
| 615 | |
| 616 // Drop receiver + arguments and return. | |
|
Michael Starzinger
2016/05/13 09:01:40
nit: The "and return" part of the comment no longe
rmcilroy
2016/05/17 11:28:30
Done.
| |
| 617 __ PopReturnAddressTo(return_pc); | |
| 618 __ addp(rsp, args_count); | |
| 619 __ PushReturnAddressFrom(return_pc); | |
| 620 } | |
| 621 | |
| 601 // Generate code for entering a JS function with the interpreter. | 622 // Generate code for entering a JS function with the interpreter. |
| 602 // On entry to the function the receiver and arguments have been pushed on the | 623 // On entry to the function the receiver and arguments have been pushed on the |
| 603 // stack left to right. The actual argument count matches the formal parameter | 624 // stack left to right. The actual argument count matches the formal parameter |
| 604 // count expected by the function. | 625 // count expected by the function. |
| 605 // | 626 // |
| 606 // The live registers are: | 627 // The live registers are: |
| 607 // o rdi: the JS function object being called | 628 // o rdi: the JS function object being called |
| 608 // o rdx: the new target | 629 // o rdx: the new target |
| 609 // o rsi: our context | 630 // o rsi: our context |
| 610 // o rbp: the caller's frame pointer | 631 // o rbp: the caller's frame pointer |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 | 717 |
| 697 // Dispatch to the first bytecode handler for the function. | 718 // Dispatch to the first bytecode handler for the function. |
| 698 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, | 719 __ movzxbp(rbx, Operand(kInterpreterBytecodeArrayRegister, |
| 699 kInterpreterBytecodeOffsetRegister, times_1, 0)); | 720 kInterpreterBytecodeOffsetRegister, times_1, 0)); |
| 700 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, | 721 __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, |
| 701 times_pointer_size, 0)); | 722 times_pointer_size, 0)); |
| 702 __ call(rbx); | 723 __ call(rbx); |
| 703 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); | 724 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); |
| 704 | 725 |
| 705 // The return value is in rax. | 726 // The return value is in rax. |
| 706 | 727 LeaveInterpreterFrame(masm, rbx, rcx); |
| 707 // Get the arguments + reciever count. | |
| 708 __ movp(rbx, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); | |
| 709 __ movl(rbx, FieldOperand(rbx, BytecodeArray::kParameterSizeOffset)); | |
| 710 | |
| 711 // Leave the frame (also dropping the register file). | |
| 712 __ leave(); | |
| 713 | |
| 714 // Drop receiver + arguments and return. | |
| 715 __ PopReturnAddressTo(rcx); | |
| 716 __ addp(rsp, rbx); | |
| 717 __ PushReturnAddressFrom(rcx); | |
| 718 __ ret(0); | 728 __ ret(0); |
| 719 | 729 |
| 720 // Load debug copy of the bytecode array. | 730 // Load debug copy of the bytecode array. |
| 721 __ bind(&load_debug_bytecode_array); | 731 __ bind(&load_debug_bytecode_array); |
| 722 Register debug_info = kInterpreterBytecodeArrayRegister; | 732 Register debug_info = kInterpreterBytecodeArrayRegister; |
| 723 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); | 733 __ movp(debug_info, FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset)); |
| 724 __ movp(kInterpreterBytecodeArrayRegister, | 734 __ movp(kInterpreterBytecodeArrayRegister, |
| 725 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); | 735 FieldOperand(debug_info, DebugInfo::kAbstractCodeIndex)); |
| 726 __ jmp(&bytecode_array_loaded); | 736 __ jmp(&bytecode_array_loaded); |
| 727 | 737 |
| 728 // If the bytecode array is no longer present, then the underlying function | 738 // If the bytecode array is no longer present, then the underlying function |
| 729 // has been switched to a different kind of code and we heal the closure by | 739 // has been switched to a different kind of code and we heal the closure by |
| 730 // switching the code entry field over to the new code object as well. | 740 // switching the code entry field over to the new code object as well. |
| 731 __ bind(&bytecode_array_not_present); | 741 __ bind(&bytecode_array_not_present); |
| 732 __ leave(); // Leave the frame so we can tail call. | 742 __ leave(); // Leave the frame so we can tail call. |
| 733 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 743 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
| 734 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); | 744 __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kCodeOffset)); |
| 735 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); | 745 __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize)); |
| 736 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); | 746 __ movp(FieldOperand(rdi, JSFunction::kCodeEntryOffset), rcx); |
| 737 __ RecordWriteCodeEntryField(rdi, rcx, r15); | 747 __ RecordWriteCodeEntryField(rdi, rcx, r15); |
| 738 __ jmp(rcx); | 748 __ jmp(rcx); |
| 739 } | 749 } |
| 740 | 750 |
| 751 void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) { | |
| 752 // Save the function and context for call to CompileBaseline. | |
| 753 __ movp(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset)); | |
| 754 __ movp(kContextRegister, | |
| 755 Operand(rbp, StandardFrameConstants::kContextOffset)); | |
| 756 | |
| 757 // Leave the frame before recompiling for baseline so that we don't count as | |
| 758 // an activation on the stack. | |
| 759 LeaveInterpreterFrame(masm, rbx, rcx); | |
| 760 | |
| 761 { | |
| 762 FrameScope frame_scope(masm, StackFrame::INTERNAL); | |
| 763 // Push return value. | |
| 764 __ Push(rax); | |
| 765 | |
| 766 // Push function as argument and compile for baseline. | |
| 767 __ Push(rdi); | |
| 768 __ CallRuntime(Runtime::kCompileBaseline); | |
| 769 | |
| 770 // Restore return value. | |
| 771 __ Pop(rax); | |
| 772 } | |
| 773 __ ret(0); | |
| 774 } | |
| 775 | |
| 741 static void Generate_InterpreterPushArgs(MacroAssembler* masm, | 776 static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
| 742 bool push_receiver) { | 777 bool push_receiver) { |
| 743 // ----------- S t a t e ------------- | 778 // ----------- S t a t e ------------- |
| 744 // -- rax : the number of arguments (not including the receiver) | 779 // -- rax : the number of arguments (not including the receiver) |
| 745 // -- rbx : the address of the first argument to be pushed. Subsequent | 780 // -- rbx : the address of the first argument to be pushed. Subsequent |
| 746 // arguments should be consecutive above this, in the same order as | 781 // arguments should be consecutive above this, in the same order as |
| 747 // they are to be pushed onto the stack. | 782 // they are to be pushed onto the stack. |
| 748 // ----------------------------------- | 783 // ----------------------------------- |
| 749 | 784 |
| 750 // Find the address of the last argument. | 785 // Find the address of the last argument. |
| (...skipping 2215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2966 __ ret(0); | 3001 __ ret(0); |
| 2967 } | 3002 } |
| 2968 | 3003 |
| 2969 | 3004 |
| 2970 #undef __ | 3005 #undef __ |
| 2971 | 3006 |
| 2972 } // namespace internal | 3007 } // namespace internal |
| 2973 } // namespace v8 | 3008 } // namespace v8 |
| 2974 | 3009 |
| 2975 #endif // V8_TARGET_ARCH_X64 | 3010 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |