Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 860013002: move CallApiFunctionAndReturn to code-stubs-* (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips64/macro-assembler-mips64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 4603 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 Label fast_elements_case; 4614 Label fast_elements_case;
4615 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); 4615 __ cmpl(rcx, Immediate(FAST_ELEMENTS));
4616 __ j(equal, &fast_elements_case); 4616 __ j(equal, &fast_elements_case);
4617 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 4617 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
4618 4618
4619 __ bind(&fast_elements_case); 4619 __ bind(&fast_elements_case);
4620 GenerateCase(masm, FAST_ELEMENTS); 4620 GenerateCase(masm, FAST_ELEMENTS);
4621 } 4621 }
4622 4622
4623 4623
4624 static int Offset(ExternalReference ref0, ExternalReference ref1) {
4625 int64_t offset = (ref0.address() - ref1.address());
4626 // Check that fits into int.
4627 DCHECK(static_cast<int>(offset) == offset);
4628 return static_cast<int>(offset);
4629 }
4630
4631
4632 // Prepares stack to put arguments (aligns and so on). WIN64 calling
4633 // convention requires to put the pointer to the return value slot into
4634 // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves
4635 // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize
4636 // inside the exit frame (not GCed) accessible via StackSpaceOperand.
4637 static void PrepareCallApiFunction(MacroAssembler* masm, int arg_stack_space) {
4638 __ EnterApiExitFrame(arg_stack_space);
4639 }
4640
4641
4642 // Calls an API function. Allocates HandleScope, extracts returned value
4643 // from handle and propagates exceptions. Clobbers r14, r15, rbx and
4644 // caller-save registers. Restores context. On return removes
4645 // stack_space * kPointerSize (GCed).
4646 static void CallApiFunctionAndReturn(MacroAssembler* masm,
4647 Register function_address,
4648 ExternalReference thunk_ref,
4649 Register thunk_last_arg, int stack_space,
4650 Operand* stack_space_operand,
4651 Operand return_value_operand,
4652 Operand* context_restore_operand) {
4653 Label prologue;
4654 Label promote_scheduled_exception;
4655 Label exception_handled;
4656 Label delete_allocated_handles;
4657 Label leave_exit_frame;
4658 Label write_back;
4659
4660 Isolate* isolate = masm->isolate();
4661 Factory* factory = isolate->factory();
4662 ExternalReference next_address =
4663 ExternalReference::handle_scope_next_address(isolate);
4664 const int kNextOffset = 0;
4665 const int kLimitOffset = Offset(
4666 ExternalReference::handle_scope_limit_address(isolate), next_address);
4667 const int kLevelOffset = Offset(
4668 ExternalReference::handle_scope_level_address(isolate), next_address);
4669 ExternalReference scheduled_exception_address =
4670 ExternalReference::scheduled_exception_address(isolate);
4671
4672 DCHECK(rdx.is(function_address) || r8.is(function_address));
4673 // Allocate HandleScope in callee-save registers.
4674 Register prev_next_address_reg = r14;
4675 Register prev_limit_reg = rbx;
4676 Register base_reg = r15;
4677 __ Move(base_reg, next_address);
4678 __ movp(prev_next_address_reg, Operand(base_reg, kNextOffset));
4679 __ movp(prev_limit_reg, Operand(base_reg, kLimitOffset));
4680 __ addl(Operand(base_reg, kLevelOffset), Immediate(1));
4681
4682 if (FLAG_log_timer_events) {
4683 FrameScope frame(masm, StackFrame::MANUAL);
4684 __ PushSafepointRegisters();
4685 __ PrepareCallCFunction(1);
4686 __ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate));
4687 __ CallCFunction(ExternalReference::log_enter_external_function(isolate),
4688 1);
4689 __ PopSafepointRegisters();
4690 }
4691
4692 Label profiler_disabled;
4693 Label end_profiler_check;
4694 __ Move(rax, ExternalReference::is_profiling_address(isolate));
4695 __ cmpb(Operand(rax, 0), Immediate(0));
4696 __ j(zero, &profiler_disabled);
4697
4698 // Third parameter is the address of the actual getter function.
4699 __ Move(thunk_last_arg, function_address);
4700 __ Move(rax, thunk_ref);
4701 __ jmp(&end_profiler_check);
4702
4703 __ bind(&profiler_disabled);
4704 // Call the api function!
4705 __ Move(rax, function_address);
4706
4707 __ bind(&end_profiler_check);
4708
4709 // Call the api function!
4710 __ call(rax);
4711
4712 if (FLAG_log_timer_events) {
4713 FrameScope frame(masm, StackFrame::MANUAL);
4714 __ PushSafepointRegisters();
4715 __ PrepareCallCFunction(1);
4716 __ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate));
4717 __ CallCFunction(ExternalReference::log_leave_external_function(isolate),
4718 1);
4719 __ PopSafepointRegisters();
4720 }
4721
4722 // Load the value from ReturnValue
4723 __ movp(rax, return_value_operand);
4724 __ bind(&prologue);
4725
4726 // No more valid handles (the result handle was the last one). Restore
4727 // previous handle scope.
4728 __ subl(Operand(base_reg, kLevelOffset), Immediate(1));
4729 __ movp(Operand(base_reg, kNextOffset), prev_next_address_reg);
4730 __ cmpp(prev_limit_reg, Operand(base_reg, kLimitOffset));
4731 __ j(not_equal, &delete_allocated_handles);
4732 __ bind(&leave_exit_frame);
4733
4734 // Check if the function scheduled an exception.
4735 __ Move(rsi, scheduled_exception_address);
4736 __ Cmp(Operand(rsi, 0), factory->the_hole_value());
4737 __ j(not_equal, &promote_scheduled_exception);
4738 __ bind(&exception_handled);
4739
4740 #if DEBUG
4741 // Check if the function returned a valid JavaScript value.
4742 Label ok;
4743 Register return_value = rax;
4744 Register map = rcx;
4745
4746 __ JumpIfSmi(return_value, &ok, Label::kNear);
4747 __ movp(map, FieldOperand(return_value, HeapObject::kMapOffset));
4748
4749 __ CmpInstanceType(map, LAST_NAME_TYPE);
4750 __ j(below_equal, &ok, Label::kNear);
4751
4752 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
4753 __ j(above_equal, &ok, Label::kNear);
4754
4755 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
4756 __ j(equal, &ok, Label::kNear);
4757
4758 __ CompareRoot(return_value, Heap::kUndefinedValueRootIndex);
4759 __ j(equal, &ok, Label::kNear);
4760
4761 __ CompareRoot(return_value, Heap::kTrueValueRootIndex);
4762 __ j(equal, &ok, Label::kNear);
4763
4764 __ CompareRoot(return_value, Heap::kFalseValueRootIndex);
4765 __ j(equal, &ok, Label::kNear);
4766
4767 __ CompareRoot(return_value, Heap::kNullValueRootIndex);
4768 __ j(equal, &ok, Label::kNear);
4769
4770 __ Abort(kAPICallReturnedInvalidObject);
4771
4772 __ bind(&ok);
4773 #endif
4774
4775 bool restore_context = context_restore_operand != NULL;
4776 if (restore_context) {
4777 __ movp(rsi, *context_restore_operand);
4778 }
4779 if (stack_space_operand != nullptr) {
4780 __ movp(rbx, *stack_space_operand);
4781 }
4782 __ LeaveApiExitFrame(!restore_context);
4783 if (stack_space_operand != nullptr) {
4784 DCHECK_EQ(stack_space, 0);
4785 __ PopReturnAddressTo(rcx);
4786 __ addq(rsp, rbx);
4787 __ jmp(rcx);
4788 } else {
4789 __ ret(stack_space * kPointerSize);
4790 }
4791
4792 __ bind(&promote_scheduled_exception);
4793 {
4794 FrameScope frame(masm, StackFrame::INTERNAL);
4795 __ CallRuntime(Runtime::kPromoteScheduledException, 0);
4796 }
4797 __ jmp(&exception_handled);
4798
4799 // HandleScope limit has changed. Delete allocated extensions.
4800 __ bind(&delete_allocated_handles);
4801 __ movp(Operand(base_reg, kLimitOffset), prev_limit_reg);
4802 __ movp(prev_limit_reg, rax);
4803 __ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate));
4804 __ LoadAddress(rax,
4805 ExternalReference::delete_handle_scope_extensions(isolate));
4806 __ call(rax);
4807 __ movp(rax, prev_limit_reg);
4808 __ jmp(&leave_exit_frame);
4809 }
4810
4811
4624 static void CallApiFunctionStubHelper(MacroAssembler* masm, 4812 static void CallApiFunctionStubHelper(MacroAssembler* masm,
4625 const ParameterCount& argc, 4813 const ParameterCount& argc,
4626 bool return_first_arg, 4814 bool return_first_arg,
4627 bool call_data_undefined) { 4815 bool call_data_undefined) {
4628 // ----------- S t a t e ------------- 4816 // ----------- S t a t e -------------
4629 // -- rax : callee 4817 // -- rax : callee
4630 // -- rbx : call_data 4818 // -- rbx : call_data
4631 // -- rcx : holder 4819 // -- rcx : holder
4632 // -- rdx : api_function_address 4820 // -- rdx : api_function_address
4633 // -- rsi : context 4821 // -- rsi : context
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
4691 // Push return address back on stack. 4879 // Push return address back on stack.
4692 __ PushReturnAddressFrom(context); 4880 __ PushReturnAddressFrom(context);
4693 4881
4694 // load context from callee 4882 // load context from callee
4695 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset)); 4883 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
4696 4884
4697 // Allocate the v8::Arguments structure in the arguments' space since 4885 // Allocate the v8::Arguments structure in the arguments' space since
4698 // it's not controlled by GC. 4886 // it's not controlled by GC.
4699 const int kApiStackSpace = 4; 4887 const int kApiStackSpace = 4;
4700 4888
4701 __ PrepareCallApiFunction(kApiStackSpace); 4889 PrepareCallApiFunction(masm, kApiStackSpace);
4702 4890
4703 // FunctionCallbackInfo::implicit_args_. 4891 // FunctionCallbackInfo::implicit_args_.
4704 __ movp(StackSpaceOperand(0), scratch); 4892 __ movp(StackSpaceOperand(0), scratch);
4705 if (argc.is_immediate()) { 4893 if (argc.is_immediate()) {
4706 __ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) * 4894 __ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) *
4707 kPointerSize)); 4895 kPointerSize));
4708 // FunctionCallbackInfo::values_. 4896 // FunctionCallbackInfo::values_.
4709 __ movp(StackSpaceOperand(1), scratch); 4897 __ movp(StackSpaceOperand(1), scratch);
4710 // FunctionCallbackInfo::length_. 4898 // FunctionCallbackInfo::length_.
4711 __ Set(StackSpaceOperand(2), argc.immediate()); 4899 __ Set(StackSpaceOperand(2), argc.immediate());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4749 FCA::kArgsLength - FCA::kContextSaveIndex); 4937 FCA::kArgsLength - FCA::kContextSaveIndex);
4750 Operand is_construct_call_operand = StackSpaceOperand(3); 4938 Operand is_construct_call_operand = StackSpaceOperand(3);
4751 Operand return_value_operand = args_from_rbp.GetArgumentOperand( 4939 Operand return_value_operand = args_from_rbp.GetArgumentOperand(
4752 return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset); 4940 return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
4753 int stack_space = 0; 4941 int stack_space = 0;
4754 Operand* stack_space_operand = &is_construct_call_operand; 4942 Operand* stack_space_operand = &is_construct_call_operand;
4755 if (argc.is_immediate()) { 4943 if (argc.is_immediate()) {
4756 stack_space = argc.immediate() + FCA::kArgsLength + 1; 4944 stack_space = argc.immediate() + FCA::kArgsLength + 1;
4757 stack_space_operand = nullptr; 4945 stack_space_operand = nullptr;
4758 } 4946 }
4759 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, callback_arg, 4947 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg,
4760 stack_space, stack_space_operand, 4948 stack_space, stack_space_operand,
4761 return_value_operand, &context_restore_operand); 4949 return_value_operand, &context_restore_operand);
4762 } 4950 }
4763 4951
4764 4952
4765 void CallApiFunctionStub::Generate(MacroAssembler* masm) { 4953 void CallApiFunctionStub::Generate(MacroAssembler* masm) {
4766 // TODO(dcarney): make rax contain the function address. 4954 // TODO(dcarney): make rax contain the function address.
4767 bool call_data_undefined = this->call_data_undefined(); 4955 bool call_data_undefined = this->call_data_undefined();
4768 CallApiFunctionStubHelper(masm, ParameterCount(rdi), false, 4956 CallApiFunctionStubHelper(masm, ParameterCount(rdi), false,
4769 call_data_undefined); 4957 call_data_undefined);
4770 } 4958 }
4771 4959
(...skipping 30 matching lines...) Expand all
4802 Register scratch = rax; 4990 Register scratch = rax;
4803 4991
4804 // v8::Arguments::values_ and handler for name. 4992 // v8::Arguments::values_ and handler for name.
4805 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; 4993 const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1;
4806 4994
4807 // Allocate v8::AccessorInfo in non-GCed stack space. 4995 // Allocate v8::AccessorInfo in non-GCed stack space.
4808 const int kArgStackSpace = 1; 4996 const int kArgStackSpace = 1;
4809 4997
4810 __ leap(name_arg, Operand(rsp, kPCOnStackSize)); 4998 __ leap(name_arg, Operand(rsp, kPCOnStackSize));
4811 4999
4812 __ PrepareCallApiFunction(kArgStackSpace); 5000 PrepareCallApiFunction(masm, kArgStackSpace);
4813 __ leap(scratch, Operand(name_arg, 1 * kPointerSize)); 5001 __ leap(scratch, Operand(name_arg, 1 * kPointerSize));
4814 5002
4815 // v8::PropertyAccessorInfo::args_. 5003 // v8::PropertyAccessorInfo::args_.
4816 __ movp(StackSpaceOperand(0), scratch); 5004 __ movp(StackSpaceOperand(0), scratch);
4817 5005
4818 // The context register (rsi) has been saved in PrepareCallApiFunction and 5006 // The context register (rsi) has been saved in PrepareCallApiFunction and
4819 // could be used to pass arguments. 5007 // could be used to pass arguments.
4820 __ leap(accessor_info_arg, StackSpaceOperand(0)); 5008 __ leap(accessor_info_arg, StackSpaceOperand(0));
4821 5009
4822 ExternalReference thunk_ref = 5010 ExternalReference thunk_ref =
4823 ExternalReference::invoke_accessor_getter_callback(isolate()); 5011 ExternalReference::invoke_accessor_getter_callback(isolate());
4824 5012
4825 // It's okay if api_function_address == getter_arg 5013 // It's okay if api_function_address == getter_arg
4826 // but not accessor_info_arg or name_arg 5014 // but not accessor_info_arg or name_arg
4827 DCHECK(!api_function_address.is(accessor_info_arg) && 5015 DCHECK(!api_function_address.is(accessor_info_arg) &&
4828 !api_function_address.is(name_arg)); 5016 !api_function_address.is(name_arg));
4829 5017
4830 // The name handler is counted as an argument. 5018 // The name handler is counted as an argument.
4831 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 5019 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
4832 Operand return_value_operand = args.GetArgumentOperand( 5020 Operand return_value_operand = args.GetArgumentOperand(
4833 PropertyCallbackArguments::kArgsLength - 1 - 5021 PropertyCallbackArguments::kArgsLength - 1 -
4834 PropertyCallbackArguments::kReturnValueOffset); 5022 PropertyCallbackArguments::kReturnValueOffset);
4835 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, getter_arg, 5023 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg,
4836 kStackSpace, nullptr, return_value_operand, NULL); 5024 kStackSpace, nullptr, return_value_operand, NULL);
4837 } 5025 }
4838 5026
4839 5027
4840 #undef __ 5028 #undef __
4841 5029
4842 } } // namespace v8::internal 5030 } } // namespace v8::internal
4843 5031
4844 #endif // V8_TARGET_ARCH_X64 5032 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips64/macro-assembler-mips64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698