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

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

Issue 836093007: split api call stubs into accessor and function call 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/interface-descriptors.h ('k') | src/x64/interface-descriptors-x64.cc » ('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 void CallApiFunctionStub::Generate(MacroAssembler* masm) { 4624 static void CallApiFunctionStubHelper(MacroAssembler* masm,
4625 const ParameterCount& argc,
4626 bool return_first_arg,
4627 bool call_data_undefined) {
4625 // ----------- S t a t e ------------- 4628 // ----------- S t a t e -------------
4626 // -- rax : callee 4629 // -- rax : callee
4627 // -- rbx : call_data 4630 // -- rbx : call_data
4628 // -- rcx : holder 4631 // -- rcx : holder
4629 // -- rdx : api_function_address 4632 // -- rdx : api_function_address
4630 // -- rsi : context 4633 // -- rsi : context
4631 // -- 4634 // -- rdi : number of arguments if argc is a register
4632 // -- rsp[0] : return address 4635 // -- rsp[0] : return address
4633 // -- rsp[8] : last argument 4636 // -- rsp[8] : last argument
4634 // -- ... 4637 // -- ...
4635 // -- rsp[argc * 8] : first argument 4638 // -- rsp[argc * 8] : first argument
4636 // -- rsp[(argc + 1) * 8] : receiver 4639 // -- rsp[(argc + 1) * 8] : receiver
4637 // ----------------------------------- 4640 // -----------------------------------
4638 4641
4639 Register callee = rax; 4642 Register callee = rax;
4640 Register call_data = rbx; 4643 Register call_data = rbx;
4641 Register holder = rcx; 4644 Register holder = rcx;
4642 Register api_function_address = rdx; 4645 Register api_function_address = rdx;
4643 Register return_address = rdi;
4644 Register context = rsi; 4646 Register context = rsi;
4645 4647
4646 int argc = this->argc();
4647 bool is_store = this->is_store();
4648 bool call_data_undefined = this->call_data_undefined();
4649
4650 typedef FunctionCallbackArguments FCA; 4648 typedef FunctionCallbackArguments FCA;
4651 4649
4652 STATIC_ASSERT(FCA::kContextSaveIndex == 6); 4650 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
4653 STATIC_ASSERT(FCA::kCalleeIndex == 5); 4651 STATIC_ASSERT(FCA::kCalleeIndex == 5);
4654 STATIC_ASSERT(FCA::kDataIndex == 4); 4652 STATIC_ASSERT(FCA::kDataIndex == 4);
4655 STATIC_ASSERT(FCA::kReturnValueOffset == 3); 4653 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
4656 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); 4654 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
4657 STATIC_ASSERT(FCA::kIsolateIndex == 1); 4655 STATIC_ASSERT(FCA::kIsolateIndex == 1);
4658 STATIC_ASSERT(FCA::kHolderIndex == 0); 4656 STATIC_ASSERT(FCA::kHolderIndex == 0);
4659 STATIC_ASSERT(FCA::kArgsLength == 7); 4657 STATIC_ASSERT(FCA::kArgsLength == 7);
4660 4658
4661 __ PopReturnAddressTo(return_address); 4659 DCHECK(argc.is_immediate() || rdi.is(argc.reg()));
4662 4660
4663 // context save 4661 if (kPointerSize == kInt64Size) {
4664 __ Push(context); 4662 // pop return address and save context
4665 // load context from callee 4663 __ xchgq(context, Operand(rsp, 0));
4666 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset)); 4664 } else {
4665 // x32 handling.
4666 __ PopReturnAddressTo(kScratchRegister);
4667 __ Push(context);
4668 __ movq(context, kScratchRegister);
4669 }
4667 4670
4668 // callee 4671 // callee
4669 __ Push(callee); 4672 __ Push(callee);
4670 4673
4671 // call data 4674 // call data
4672 __ Push(call_data); 4675 __ Push(call_data);
4673 Register scratch = call_data; 4676 Register scratch = call_data;
4674 if (!call_data_undefined) { 4677 if (!call_data_undefined) {
4675 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 4678 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
4676 } 4679 }
4677 // return value 4680 // return value
4678 __ Push(scratch); 4681 __ Push(scratch);
4679 // return value default 4682 // return value default
4680 __ Push(scratch); 4683 __ Push(scratch);
4681 // isolate 4684 // isolate
4682 __ Move(scratch, 4685 __ Move(scratch, ExternalReference::isolate_address(masm->isolate()));
4683 ExternalReference::isolate_address(isolate()));
4684 __ Push(scratch); 4686 __ Push(scratch);
4685 // holder 4687 // holder
4686 __ Push(holder); 4688 __ Push(holder);
4687 4689
4688 __ movp(scratch, rsp); 4690 __ movp(scratch, rsp);
4689 // Push return address back on stack. 4691 // Push return address back on stack.
4690 __ PushReturnAddressFrom(return_address); 4692 __ PushReturnAddressFrom(context);
4693
4694 // load context from callee
4695 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset));
4691 4696
4692 // Allocate the v8::Arguments structure in the arguments' space since 4697 // Allocate the v8::Arguments structure in the arguments' space since
4693 // it's not controlled by GC. 4698 // it's not controlled by GC.
4694 const int kApiStackSpace = 4; 4699 const int kApiStackSpace = 4;
4695 4700
4696 __ PrepareCallApiFunction(kApiStackSpace); 4701 __ PrepareCallApiFunction(kApiStackSpace);
4697 4702
4698 // FunctionCallbackInfo::implicit_args_. 4703 // FunctionCallbackInfo::implicit_args_.
4699 __ movp(StackSpaceOperand(0), scratch); 4704 __ movp(StackSpaceOperand(0), scratch);
4700 __ addp(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize)); 4705 if (argc.is_immediate()) {
4701 __ movp(StackSpaceOperand(1), scratch); // FunctionCallbackInfo::values_. 4706 __ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) *
4702 __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_. 4707 kPointerSize));
4703 // FunctionCallbackInfo::is_construct_call_. 4708 // FunctionCallbackInfo::values_.
4704 __ Set(StackSpaceOperand(3), 0); 4709 __ movp(StackSpaceOperand(1), scratch);
4710 // FunctionCallbackInfo::length_.
4711 __ Set(StackSpaceOperand(2), argc.immediate());
4712 // FunctionCallbackInfo::is_construct_call_.
4713 __ Set(StackSpaceOperand(3), 0);
4714 } else {
4715 __ leap(scratch, Operand(scratch, argc.reg(), times_pointer_size,
4716 (FCA::kArgsLength - 1) * kPointerSize));
4717 // FunctionCallbackInfo::values_.
4718 __ movp(StackSpaceOperand(1), scratch);
4719 // FunctionCallbackInfo::length_.
4720 __ movp(StackSpaceOperand(2), argc.reg());
4721 // FunctionCallbackInfo::is_construct_call_.
4722 __ leap(argc.reg(), Operand(argc.reg(), times_pointer_size,
4723 (FCA::kArgsLength + 1) * kPointerSize));
4724 __ movp(StackSpaceOperand(3), argc.reg());
4725 }
4705 4726
4706 #if defined(__MINGW64__) || defined(_WIN64) 4727 #if defined(__MINGW64__) || defined(_WIN64)
4707 Register arguments_arg = rcx; 4728 Register arguments_arg = rcx;
4708 Register callback_arg = rdx; 4729 Register callback_arg = rdx;
4709 #else 4730 #else
4710 Register arguments_arg = rdi; 4731 Register arguments_arg = rdi;
4711 Register callback_arg = rsi; 4732 Register callback_arg = rsi;
4712 #endif 4733 #endif
4713 4734
4714 // It's okay if api_function_address == callback_arg 4735 // It's okay if api_function_address == callback_arg
4715 // but not arguments_arg 4736 // but not arguments_arg
4716 DCHECK(!api_function_address.is(arguments_arg)); 4737 DCHECK(!api_function_address.is(arguments_arg));
4717 4738
4718 // v8::InvocationCallback's argument. 4739 // v8::InvocationCallback's argument.
4719 __ leap(arguments_arg, StackSpaceOperand(0)); 4740 __ leap(arguments_arg, StackSpaceOperand(0));
4720 4741
4721 ExternalReference thunk_ref = 4742 ExternalReference thunk_ref =
4722 ExternalReference::invoke_function_callback(isolate()); 4743 ExternalReference::invoke_function_callback(masm->isolate());
4723 4744
4724 // Accessor for FunctionCallbackInfo and first js arg. 4745 // Accessor for FunctionCallbackInfo and first js arg.
4725 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1, 4746 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1,
4726 ARGUMENTS_DONT_CONTAIN_RECEIVER); 4747 ARGUMENTS_DONT_CONTAIN_RECEIVER);
4727 Operand context_restore_operand = args_from_rbp.GetArgumentOperand( 4748 Operand context_restore_operand = args_from_rbp.GetArgumentOperand(
4728 FCA::kArgsLength - FCA::kContextSaveIndex); 4749 FCA::kArgsLength - FCA::kContextSaveIndex);
4729 // Stores return the first js argument 4750 Operand is_construct_call_operand = StackSpaceOperand(3);
4730 Operand return_value_operand = args_from_rbp.GetArgumentOperand( 4751 Operand return_value_operand = args_from_rbp.GetArgumentOperand(
4731 is_store ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset); 4752 return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset);
4732 __ CallApiFunctionAndReturn( 4753 int stack_space = 0;
4733 api_function_address, 4754 Operand* stack_space_operand = &is_construct_call_operand;
4734 thunk_ref, 4755 if (argc.is_immediate()) {
4735 callback_arg, 4756 stack_space = argc.immediate() + FCA::kArgsLength + 1;
4736 argc + FCA::kArgsLength + 1, 4757 stack_space_operand = nullptr;
4737 return_value_operand, 4758 }
4738 &context_restore_operand); 4759 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, callback_arg,
4760 stack_space, stack_space_operand,
4761 return_value_operand, &context_restore_operand);
4739 } 4762 }
4740 4763
4741 4764
4765 void CallApiFunctionStub::Generate(MacroAssembler* masm) {
4766 // TODO(dcarney): make rax contain the function address.
4767 bool call_data_undefined = this->call_data_undefined();
4768 CallApiFunctionStubHelper(masm, ParameterCount(rdi), false,
4769 call_data_undefined);
4770 }
4771
4772
4773 void CallApiAccessorStub::Generate(MacroAssembler* masm) {
4774 bool is_store = this->is_store();
4775 int argc = is_store ? 1 : 0;
4776 bool call_data_undefined = this->call_data_undefined();
4777 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store,
4778 call_data_undefined);
4779 }
4780
4781
4742 void CallApiGetterStub::Generate(MacroAssembler* masm) { 4782 void CallApiGetterStub::Generate(MacroAssembler* masm) {
4743 // ----------- S t a t e ------------- 4783 // ----------- S t a t e -------------
4744 // -- rsp[0] : return address 4784 // -- rsp[0] : return address
4745 // -- rsp[8] : name 4785 // -- rsp[8] : name
4746 // -- rsp[16 - kArgsLength*8] : PropertyCallbackArguments object 4786 // -- rsp[16 - kArgsLength*8] : PropertyCallbackArguments object
4747 // -- ... 4787 // -- ...
4748 // -- r8 : api_function_address 4788 // -- r8 : api_function_address
4749 // ----------------------------------- 4789 // -----------------------------------
4750 4790
4751 #if defined(__MINGW64__) || defined(_WIN64) 4791 #if defined(__MINGW64__) || defined(_WIN64)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4785 // It's okay if api_function_address == getter_arg 4825 // It's okay if api_function_address == getter_arg
4786 // but not accessor_info_arg or name_arg 4826 // but not accessor_info_arg or name_arg
4787 DCHECK(!api_function_address.is(accessor_info_arg) && 4827 DCHECK(!api_function_address.is(accessor_info_arg) &&
4788 !api_function_address.is(name_arg)); 4828 !api_function_address.is(name_arg));
4789 4829
4790 // The name handler is counted as an argument. 4830 // The name handler is counted as an argument.
4791 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 4831 StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength);
4792 Operand return_value_operand = args.GetArgumentOperand( 4832 Operand return_value_operand = args.GetArgumentOperand(
4793 PropertyCallbackArguments::kArgsLength - 1 - 4833 PropertyCallbackArguments::kArgsLength - 1 -
4794 PropertyCallbackArguments::kReturnValueOffset); 4834 PropertyCallbackArguments::kReturnValueOffset);
4795 __ CallApiFunctionAndReturn(api_function_address, 4835 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, getter_arg,
4796 thunk_ref, 4836 kStackSpace, nullptr, return_value_operand, NULL);
4797 getter_arg,
4798 kStackSpace,
4799 return_value_operand,
4800 NULL);
4801 } 4837 }
4802 4838
4803 4839
4804 #undef __ 4840 #undef __
4805 4841
4806 } } // namespace v8::internal 4842 } } // namespace v8::internal
4807 4843
4808 #endif // V8_TARGET_ARCH_X64 4844 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/interface-descriptors.h ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698