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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
687 | 687 |
688 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { | 688 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { |
689 EnterApiExitFrame(arg_stack_space); | 689 EnterApiExitFrame(arg_stack_space); |
690 } | 690 } |
691 | 691 |
692 | 692 |
693 void MacroAssembler::CallApiFunctionAndReturn(Address function_address, | 693 void MacroAssembler::CallApiFunctionAndReturn(Address function_address, |
694 Address thunk_address, | 694 Address thunk_address, |
695 Register thunk_last_arg, | 695 Register thunk_last_arg, |
696 int stack_space, | 696 int stack_space, |
697 int return_value_offset) { | 697 int return_value_offset, |
698 int restore_context_offset) { | |
698 Label prologue; | 699 Label prologue; |
699 Label promote_scheduled_exception; | 700 Label promote_scheduled_exception; |
701 Label exception_handled; | |
700 Label delete_allocated_handles; | 702 Label delete_allocated_handles; |
701 Label leave_exit_frame; | 703 Label leave_exit_frame; |
702 Label write_back; | 704 Label write_back; |
703 | 705 |
704 Factory* factory = isolate()->factory(); | 706 Factory* factory = isolate()->factory(); |
705 ExternalReference next_address = | 707 ExternalReference next_address = |
706 ExternalReference::handle_scope_next_address(isolate()); | 708 ExternalReference::handle_scope_next_address(isolate()); |
707 const int kNextOffset = 0; | 709 const int kNextOffset = 0; |
708 const int kLimitOffset = Offset( | 710 const int kLimitOffset = Offset( |
709 ExternalReference::handle_scope_limit_address(isolate()), | 711 ExternalReference::handle_scope_limit_address(isolate()), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 subl(Operand(base_reg, kLevelOffset), Immediate(1)); | 777 subl(Operand(base_reg, kLevelOffset), Immediate(1)); |
776 movq(Operand(base_reg, kNextOffset), prev_next_address_reg); | 778 movq(Operand(base_reg, kNextOffset), prev_next_address_reg); |
777 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); | 779 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); |
778 j(not_equal, &delete_allocated_handles); | 780 j(not_equal, &delete_allocated_handles); |
779 bind(&leave_exit_frame); | 781 bind(&leave_exit_frame); |
780 | 782 |
781 // Check if the function scheduled an exception. | 783 // Check if the function scheduled an exception. |
782 movq(rsi, scheduled_exception_address); | 784 movq(rsi, scheduled_exception_address); |
783 Cmp(Operand(rsi, 0), factory->the_hole_value()); | 785 Cmp(Operand(rsi, 0), factory->the_hole_value()); |
784 j(not_equal, &promote_scheduled_exception); | 786 j(not_equal, &promote_scheduled_exception); |
787 bind(&exception_handled); | |
785 | 788 |
786 #if ENABLE_EXTRA_CHECKS | 789 #if ENABLE_EXTRA_CHECKS |
787 // Check if the function returned a valid JavaScript value. | 790 // Check if the function returned a valid JavaScript value. |
788 Label ok; | 791 Label ok; |
789 Register return_value = rax; | 792 Register return_value = rax; |
790 Register map = rcx; | 793 Register map = rcx; |
791 | 794 |
792 JumpIfSmi(return_value, &ok, Label::kNear); | 795 JumpIfSmi(return_value, &ok, Label::kNear); |
793 movq(map, FieldOperand(return_value, HeapObject::kMapOffset)); | 796 movq(map, FieldOperand(return_value, HeapObject::kMapOffset)); |
794 | 797 |
(...skipping 16 matching lines...) Expand all Loading... | |
811 j(equal, &ok, Label::kNear); | 814 j(equal, &ok, Label::kNear); |
812 | 815 |
813 CompareRoot(return_value, Heap::kNullValueRootIndex); | 816 CompareRoot(return_value, Heap::kNullValueRootIndex); |
814 j(equal, &ok, Label::kNear); | 817 j(equal, &ok, Label::kNear); |
815 | 818 |
816 Abort(kAPICallReturnedInvalidObject); | 819 Abort(kAPICallReturnedInvalidObject); |
817 | 820 |
818 bind(&ok); | 821 bind(&ok); |
819 #endif | 822 #endif |
820 | 823 |
821 LeaveApiExitFrame(); | 824 bool restore_context = restore_context_offset != 0; |
Michael Starzinger
2013/09/12 18:38:51
Hmpf! The context is not restored when the offset
| |
825 if (restore_context) { | |
826 movq(rsi, Operand(rbp, restore_context_offset * kPointerSize)); | |
827 } | |
828 LeaveApiExitFrame(!restore_context); | |
822 ret(stack_space * kPointerSize); | 829 ret(stack_space * kPointerSize); |
823 | 830 |
824 bind(&promote_scheduled_exception); | 831 bind(&promote_scheduled_exception); |
825 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 832 CallRuntime(Runtime::kPromoteScheduledException, 0); |
833 jmp(&exception_handled); | |
826 | 834 |
827 // HandleScope limit has changed. Delete allocated extensions. | 835 // HandleScope limit has changed. Delete allocated extensions. |
828 bind(&delete_allocated_handles); | 836 bind(&delete_allocated_handles); |
829 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); | 837 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); |
830 movq(prev_limit_reg, rax); | 838 movq(prev_limit_reg, rax); |
831 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); | 839 LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); |
832 LoadAddress(rax, | 840 LoadAddress(rax, |
833 ExternalReference::delete_handle_scope_extensions(isolate())); | 841 ExternalReference::delete_handle_scope_extensions(isolate())); |
834 call(rax); | 842 call(rax); |
835 movq(rax, prev_limit_reg); | 843 movq(rax, prev_limit_reg); |
(...skipping 2728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3564 // Get the return address from the stack and restore the frame pointer. | 3572 // Get the return address from the stack and restore the frame pointer. |
3565 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 3573 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
3566 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 3574 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
3567 | 3575 |
3568 // Drop everything up to and including the arguments and the receiver | 3576 // Drop everything up to and including the arguments and the receiver |
3569 // from the caller stack. | 3577 // from the caller stack. |
3570 lea(rsp, Operand(r15, 1 * kPointerSize)); | 3578 lea(rsp, Operand(r15, 1 * kPointerSize)); |
3571 | 3579 |
3572 PushReturnAddressFrom(rcx); | 3580 PushReturnAddressFrom(rcx); |
3573 | 3581 |
3574 LeaveExitFrameEpilogue(); | 3582 LeaveExitFrameEpilogue(true); |
3575 } | 3583 } |
3576 | 3584 |
3577 | 3585 |
3578 void MacroAssembler::LeaveApiExitFrame() { | 3586 void MacroAssembler::LeaveApiExitFrame(bool restore_context) { |
3579 movq(rsp, rbp); | 3587 movq(rsp, rbp); |
3580 pop(rbp); | 3588 pop(rbp); |
3581 | 3589 |
3582 LeaveExitFrameEpilogue(); | 3590 LeaveExitFrameEpilogue(restore_context); |
3583 } | 3591 } |
3584 | 3592 |
3585 | 3593 |
3586 void MacroAssembler::LeaveExitFrameEpilogue() { | 3594 void MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { |
3587 // Restore current context from top and clear it in debug mode. | 3595 // Restore current context from top and clear it in debug mode. |
3588 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 3596 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
3589 Operand context_operand = ExternalOperand(context_address); | 3597 Operand context_operand = ExternalOperand(context_address); |
3590 movq(rsi, context_operand); | 3598 if (restore_context) { |
3599 movq(rsi, context_operand); | |
3600 } | |
3591 #ifdef DEBUG | 3601 #ifdef DEBUG |
3592 movq(context_operand, Immediate(0)); | 3602 movq(context_operand, Immediate(0)); |
3593 #endif | 3603 #endif |
3594 | 3604 |
3595 // Clear the top frame. | 3605 // Clear the top frame. |
3596 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, | 3606 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, |
3597 isolate()); | 3607 isolate()); |
3598 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); | 3608 Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); |
3599 movq(c_entry_fp_operand, Immediate(0)); | 3609 movq(c_entry_fp_operand, Immediate(0)); |
3600 } | 3610 } |
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4695 j(greater, &no_memento_available); | 4705 j(greater, &no_memento_available); |
4696 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), | 4706 CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), |
4697 Heap::kAllocationMementoMapRootIndex); | 4707 Heap::kAllocationMementoMapRootIndex); |
4698 bind(&no_memento_available); | 4708 bind(&no_memento_available); |
4699 } | 4709 } |
4700 | 4710 |
4701 | 4711 |
4702 } } // namespace v8::internal | 4712 } } // namespace v8::internal |
4703 | 4713 |
4704 #endif // V8_TARGET_ARCH_X64 | 4714 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |