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