OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 ASSERT(static_cast<int>(offset) == offset); | 684 ASSERT(static_cast<int>(offset) == offset); |
685 return static_cast<int>(offset); | 685 return static_cast<int>(offset); |
686 } | 686 } |
687 | 687 |
688 | 688 |
689 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { | 689 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { |
690 EnterApiExitFrame(arg_stack_space); | 690 EnterApiExitFrame(arg_stack_space); |
691 } | 691 } |
692 | 692 |
693 | 693 |
694 void MacroAssembler::CallApiFunctionAndReturn(Address function_address, | 694 void MacroAssembler::CallApiFunctionAndReturn( |
695 Address thunk_address, | 695 Address function_address, |
696 Register thunk_last_arg, | 696 Address thunk_address, |
697 int stack_space, | 697 Register thunk_last_arg, |
698 int return_value_offset) { | 698 int stack_space, |
| 699 Operand return_value_operand, |
| 700 Operand* context_restore_operand) { |
699 Label prologue; | 701 Label prologue; |
700 Label promote_scheduled_exception; | 702 Label promote_scheduled_exception; |
| 703 Label exception_handled; |
701 Label delete_allocated_handles; | 704 Label delete_allocated_handles; |
702 Label leave_exit_frame; | 705 Label leave_exit_frame; |
703 Label write_back; | 706 Label write_back; |
704 | 707 |
705 Factory* factory = isolate()->factory(); | 708 Factory* factory = isolate()->factory(); |
706 ExternalReference next_address = | 709 ExternalReference next_address = |
707 ExternalReference::handle_scope_next_address(isolate()); | 710 ExternalReference::handle_scope_next_address(isolate()); |
708 const int kNextOffset = 0; | 711 const int kNextOffset = 0; |
709 const int kLimitOffset = Offset( | 712 const int kLimitOffset = Offset( |
710 ExternalReference::handle_scope_limit_address(isolate()), | 713 ExternalReference::handle_scope_limit_address(isolate()), |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 if (FLAG_log_timer_events) { | 764 if (FLAG_log_timer_events) { |
762 FrameScope frame(this, StackFrame::MANUAL); | 765 FrameScope frame(this, StackFrame::MANUAL); |
763 PushSafepointRegisters(); | 766 PushSafepointRegisters(); |
764 PrepareCallCFunction(1); | 767 PrepareCallCFunction(1); |
765 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); | 768 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); |
766 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | 769 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); |
767 PopSafepointRegisters(); | 770 PopSafepointRegisters(); |
768 } | 771 } |
769 | 772 |
770 // Load the value from ReturnValue | 773 // Load the value from ReturnValue |
771 movq(rax, Operand(rbp, return_value_offset * kPointerSize)); | 774 movq(rax, return_value_operand); |
772 bind(&prologue); | 775 bind(&prologue); |
773 | 776 |
774 // No more valid handles (the result handle was the last one). Restore | 777 // No more valid handles (the result handle was the last one). Restore |
775 // previous handle scope. | 778 // previous handle scope. |
776 subl(Operand(base_reg, kLevelOffset), Immediate(1)); | 779 subl(Operand(base_reg, kLevelOffset), Immediate(1)); |
777 movq(Operand(base_reg, kNextOffset), prev_next_address_reg); | 780 movq(Operand(base_reg, kNextOffset), prev_next_address_reg); |
778 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); | 781 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); |
779 j(not_equal, &delete_allocated_handles); | 782 j(not_equal, &delete_allocated_handles); |
780 bind(&leave_exit_frame); | 783 bind(&leave_exit_frame); |
781 | 784 |
782 // Check if the function scheduled an exception. | 785 // Check if the function scheduled an exception. |
783 movq(rsi, scheduled_exception_address); | 786 movq(rsi, scheduled_exception_address); |
784 Cmp(Operand(rsi, 0), factory->the_hole_value()); | 787 Cmp(Operand(rsi, 0), factory->the_hole_value()); |
785 j(not_equal, &promote_scheduled_exception); | 788 j(not_equal, &promote_scheduled_exception); |
| 789 bind(&exception_handled); |
786 | 790 |
787 #if ENABLE_EXTRA_CHECKS | 791 #if ENABLE_EXTRA_CHECKS |
788 // Check if the function returned a valid JavaScript value. | 792 // Check if the function returned a valid JavaScript value. |
789 Label ok; | 793 Label ok; |
790 Register return_value = rax; | 794 Register return_value = rax; |
791 Register map = rcx; | 795 Register map = rcx; |
792 | 796 |
793 JumpIfSmi(return_value, &ok, Label::kNear); | 797 JumpIfSmi(return_value, &ok, Label::kNear); |
794 movq(map, FieldOperand(return_value, HeapObject::kMapOffset)); | 798 movq(map, FieldOperand(return_value, HeapObject::kMapOffset)); |
795 | 799 |
(...skipping 16 matching lines...) Expand all Loading... |
812 j(equal, &ok, Label::kNear); | 816 j(equal, &ok, Label::kNear); |
813 | 817 |
814 CompareRoot(return_value, Heap::kNullValueRootIndex); | 818 CompareRoot(return_value, Heap::kNullValueRootIndex); |
815 j(equal, &ok, Label::kNear); | 819 j(equal, &ok, Label::kNear); |
816 | 820 |
817 Abort(kAPICallReturnedInvalidObject); | 821 Abort(kAPICallReturnedInvalidObject); |
818 | 822 |
819 bind(&ok); | 823 bind(&ok); |
820 #endif | 824 #endif |
821 | 825 |
822 LeaveApiExitFrame(); | 826 bool restore_context = context_restore_operand != NULL; |
| 827 if (restore_context) { |
| 828 movq(rsi, *context_restore_operand); |
| 829 } |
| 830 LeaveApiExitFrame(!restore_context); |
823 ret(stack_space * kPointerSize); | 831 ret(stack_space * kPointerSize); |
824 | 832 |
825 bind(&promote_scheduled_exception); | 833 bind(&promote_scheduled_exception); |
826 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 834 { |
| 835 FrameScope frame(this, StackFrame::INTERNAL); |
| 836 CallRuntime(Runtime::kPromoteScheduledException, 0); |
| 837 } |
| 838 jmp(&exception_handled); |
827 | 839 |
828 // HandleScope limit has changed. Delete allocated extensions. | 840 // HandleScope limit has changed. Delete allocated extensions. |
829 bind(&delete_allocated_handles); | 841 bind(&delete_allocated_handles); |
830 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); | 842 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); |
831 movq(prev_limit_reg, rax); | 843 movq(prev_limit_reg, rax); |
832 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); | 844 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); |
833 LoadAddress(rax, | 845 LoadAddress(rax, |
834 ExternalReference::delete_handle_scope_extensions(isolate())); | 846 ExternalReference::delete_handle_scope_extensions(isolate())); |
835 call(rax); | 847 call(rax); |
836 movq(rax, prev_limit_reg); | 848 movq(rax, prev_limit_reg); |
(...skipping 2851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3688 // Get the return address from the stack and restore the frame pointer. | 3700 // Get the return address from the stack and restore the frame pointer. |
3689 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 3701 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
3690 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 3702 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
3691 | 3703 |
3692 // Drop everything up to and including the arguments and the receiver | 3704 // Drop everything up to and including the arguments and the receiver |
3693 // from the caller stack. | 3705 // from the caller stack. |
3694 lea(rsp, Operand(r15, 1 * kPointerSize)); | 3706 lea(rsp, Operand(r15, 1 * kPointerSize)); |
3695 | 3707 |
3696 PushReturnAddressFrom(rcx); | 3708 PushReturnAddressFrom(rcx); |
3697 | 3709 |
3698 LeaveExitFrameEpilogue(); | 3710 LeaveExitFrameEpilogue(true); |
3699 } | 3711 } |
3700 | 3712 |
3701 | 3713 |
3702 void MacroAssembler::LeaveApiExitFrame() { | 3714 void MacroAssembler::LeaveApiExitFrame(bool restore_context) { |
3703 movq(rsp, rbp); | 3715 movq(rsp, rbp); |
3704 pop(rbp); | 3716 pop(rbp); |
3705 | 3717 |
3706 LeaveExitFrameEpilogue(); | 3718 LeaveExitFrameEpilogue(restore_context); |
3707 } | 3719 } |
3708 | 3720 |
3709 | 3721 |
3710 void MacroAssembler::LeaveExitFrameEpilogue() { | 3722 void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { |
3711 // Restore current context from top and clear it in debug mode. | 3723 // Restore current context from top and clear it in debug mode. |
3712 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 3724 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
3713 Operand context_operand = ExternalOperand(context_address); | 3725 Operand context_operand = ExternalOperand(context_address); |
3714 movq(rsi, context_operand); | 3726 if (restore_context) { |
| 3727 movq(rsi, context_operand); |
| 3728 } |
3715 #ifdef DEBUG | 3729 #ifdef DEBUG |
3716 movq(context_operand, Immediate(0)); | 3730 movq(context_operand, Immediate(0)); |
3717 #endif | 3731 #endif |
3718 | 3732 |
3719 // Clear the top frame. | 3733 // Clear the top frame. |
3720 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, | 3734 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, |
3721 isolate()); | 3735 isolate()); |
3722 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); | 3736 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); |
3723 movq(c_entry_fp_operand, Immediate(0)); | 3737 movq(c_entry_fp_operand, Immediate(0)); |
3724 } | 3738 } |
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4819 j(greater, &no_memento_available); | 4833 j(greater, &no_memento_available); |
4820 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), | 4834 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), |
4821 Heap::kAllocationMementoMapRootIndex); | 4835 Heap::kAllocationMementoMapRootIndex); |
4822 bind(&no_memento_available); | 4836 bind(&no_memento_available); |
4823 } | 4837 } |
4824 | 4838 |
4825 | 4839 |
4826 } } // namespace v8::internal | 4840 } } // namespace v8::internal |
4827 | 4841 |
4828 #endif // V8_TARGET_ARCH_X64 | 4842 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |