OLD | NEW |
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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
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 5025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5036 | 5036 |
5037 Label fast_elements_case; | 5037 Label fast_elements_case; |
5038 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); | 5038 __ CompareAndBranch(kind, FAST_ELEMENTS, eq, &fast_elements_case); |
5039 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 5039 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
5040 | 5040 |
5041 __ Bind(&fast_elements_case); | 5041 __ Bind(&fast_elements_case); |
5042 GenerateCase(masm, FAST_ELEMENTS); | 5042 GenerateCase(masm, FAST_ELEMENTS); |
5043 } | 5043 } |
5044 | 5044 |
5045 | 5045 |
5046 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | 5046 static void CallApiFunctionStubHelper(MacroAssembler* masm, |
| 5047 const ParameterCount& argc, |
| 5048 bool return_first_arg, |
| 5049 bool call_data_undefined) { |
5047 // ----------- S t a t e ------------- | 5050 // ----------- S t a t e ------------- |
5048 // -- x0 : callee | 5051 // -- x0 : callee |
5049 // -- x4 : call_data | 5052 // -- x4 : call_data |
5050 // -- x2 : holder | 5053 // -- x2 : holder |
5051 // -- x1 : api_function_address | 5054 // -- x1 : api_function_address |
| 5055 // -- x3 : number of arguments if argc is a register |
5052 // -- cp : context | 5056 // -- cp : context |
5053 // -- | 5057 // -- |
5054 // -- sp[0] : last argument | 5058 // -- sp[0] : last argument |
5055 // -- ... | 5059 // -- ... |
5056 // -- sp[(argc - 1) * 8] : first argument | 5060 // -- sp[(argc - 1) * 8] : first argument |
5057 // -- sp[argc * 8] : receiver | 5061 // -- sp[argc * 8] : receiver |
5058 // ----------------------------------- | 5062 // ----------------------------------- |
5059 | 5063 |
5060 Register callee = x0; | 5064 Register callee = x0; |
5061 Register call_data = x4; | 5065 Register call_data = x4; |
5062 Register holder = x2; | 5066 Register holder = x2; |
5063 Register api_function_address = x1; | 5067 Register api_function_address = x1; |
5064 Register context = cp; | 5068 Register context = cp; |
5065 | 5069 |
5066 int argc = this->argc(); | |
5067 bool is_store = this->is_store(); | |
5068 bool call_data_undefined = this->call_data_undefined(); | |
5069 | |
5070 typedef FunctionCallbackArguments FCA; | 5070 typedef FunctionCallbackArguments FCA; |
5071 | 5071 |
5072 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5072 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5073 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5073 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
5074 STATIC_ASSERT(FCA::kDataIndex == 4); | 5074 STATIC_ASSERT(FCA::kDataIndex == 4); |
5075 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 5075 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
5076 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 5076 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
5077 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 5077 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
5078 STATIC_ASSERT(FCA::kHolderIndex == 0); | 5078 STATIC_ASSERT(FCA::kHolderIndex == 0); |
5079 STATIC_ASSERT(FCA::kArgsLength == 7); | 5079 STATIC_ASSERT(FCA::kArgsLength == 7); |
5080 | 5080 |
| 5081 DCHECK(argc.is_immediate() || x3.is(argc.reg())); |
| 5082 |
5081 // FunctionCallbackArguments: context, callee and call data. | 5083 // FunctionCallbackArguments: context, callee and call data. |
5082 __ Push(context, callee, call_data); | 5084 __ Push(context, callee, call_data); |
5083 | 5085 |
5084 // Load context from callee | 5086 // Load context from callee |
5085 __ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset)); | 5087 __ Ldr(context, FieldMemOperand(callee, JSFunction::kContextOffset)); |
5086 | 5088 |
5087 if (!call_data_undefined) { | 5089 if (!call_data_undefined) { |
5088 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); | 5090 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
5089 } | 5091 } |
5090 Register isolate_reg = x5; | 5092 Register isolate_reg = x5; |
5091 __ Mov(isolate_reg, ExternalReference::isolate_address(isolate())); | 5093 __ Mov(isolate_reg, ExternalReference::isolate_address(masm->isolate())); |
5092 | 5094 |
5093 // FunctionCallbackArguments: | 5095 // FunctionCallbackArguments: |
5094 // return value, return value default, isolate, holder. | 5096 // return value, return value default, isolate, holder. |
5095 __ Push(call_data, call_data, isolate_reg, holder); | 5097 __ Push(call_data, call_data, isolate_reg, holder); |
5096 | 5098 |
5097 // Prepare arguments. | 5099 // Prepare arguments. |
5098 Register args = x6; | 5100 Register args = x6; |
5099 __ Mov(args, masm->StackPointer()); | 5101 __ Mov(args, masm->StackPointer()); |
5100 | 5102 |
5101 // Allocate the v8::Arguments structure in the arguments' space, since it's | 5103 // Allocate the v8::Arguments structure in the arguments' space, since it's |
5102 // not controlled by GC. | 5104 // not controlled by GC. |
5103 const int kApiStackSpace = 4; | 5105 const int kApiStackSpace = 4; |
5104 | 5106 |
5105 // Allocate space for CallApiFunctionAndReturn can store some scratch | 5107 // Allocate space for CallApiFunctionAndReturn can store some scratch |
5106 // registeres on the stack. | 5108 // registeres on the stack. |
5107 const int kCallApiFunctionSpillSpace = 4; | 5109 const int kCallApiFunctionSpillSpace = 4; |
5108 | 5110 |
5109 FrameScope frame_scope(masm, StackFrame::MANUAL); | 5111 FrameScope frame_scope(masm, StackFrame::MANUAL); |
5110 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); | 5112 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); |
5111 | 5113 |
5112 DCHECK(!AreAliased(x0, api_function_address)); | 5114 DCHECK(!AreAliased(x0, api_function_address)); |
5113 // x0 = FunctionCallbackInfo& | 5115 // x0 = FunctionCallbackInfo& |
5114 // Arguments is after the return address. | 5116 // Arguments is after the return address. |
5115 __ Add(x0, masm->StackPointer(), 1 * kPointerSize); | 5117 __ Add(x0, masm->StackPointer(), 1 * kPointerSize); |
5116 // FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_ | 5118 if (argc.is_immediate()) { |
5117 __ Add(x10, args, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); | 5119 // FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_ |
5118 __ Stp(args, x10, MemOperand(x0, 0 * kPointerSize)); | 5120 __ Add(x10, args, |
5119 // FunctionCallbackInfo::length_ = argc and | 5121 Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize)); |
5120 // FunctionCallbackInfo::is_construct_call = 0 | 5122 __ Stp(args, x10, MemOperand(x0, 0 * kPointerSize)); |
5121 __ Mov(x10, argc); | 5123 // FunctionCallbackInfo::length_ = argc and |
5122 __ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize)); | 5124 // FunctionCallbackInfo::is_construct_call = 0 |
| 5125 __ Mov(x10, argc.immediate()); |
| 5126 __ Stp(x10, xzr, MemOperand(x0, 2 * kPointerSize)); |
| 5127 } else { |
| 5128 // FunctionCallbackInfo::implicit_args_ and FunctionCallbackInfo::values_ |
| 5129 __ Add(x10, args, Operand(argc.reg(), LSL, kPointerSizeLog2)); |
| 5130 __ Add(x10, x10, (FCA::kArgsLength - 1) * kPointerSize); |
| 5131 __ Stp(args, x10, MemOperand(x0, 0 * kPointerSize)); |
| 5132 // FunctionCallbackInfo::length_ = argc and |
| 5133 // FunctionCallbackInfo::is_construct_call |
| 5134 __ Add(x10, argc.reg(), FCA::kArgsLength + 1); |
| 5135 __ Mov(x10, Operand(x10, LSL, kPointerSizeLog2)); |
| 5136 __ Stp(argc.reg(), x10, MemOperand(x0, 2 * kPointerSize)); |
| 5137 } |
5123 | 5138 |
5124 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; | |
5125 ExternalReference thunk_ref = | 5139 ExternalReference thunk_ref = |
5126 ExternalReference::invoke_function_callback(isolate()); | 5140 ExternalReference::invoke_function_callback(masm->isolate()); |
5127 | 5141 |
5128 AllowExternalCallThatCantCauseGC scope(masm); | 5142 AllowExternalCallThatCantCauseGC scope(masm); |
5129 MemOperand context_restore_operand( | 5143 MemOperand context_restore_operand( |
5130 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); | 5144 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
5131 // Stores return the first js argument | 5145 // Stores return the first js argument |
5132 int return_value_offset = 0; | 5146 int return_value_offset = 0; |
5133 if (is_store) { | 5147 if (return_first_arg) { |
5134 return_value_offset = 2 + FCA::kArgsLength; | 5148 return_value_offset = 2 + FCA::kArgsLength; |
5135 } else { | 5149 } else { |
5136 return_value_offset = 2 + FCA::kReturnValueOffset; | 5150 return_value_offset = 2 + FCA::kReturnValueOffset; |
5137 } | 5151 } |
5138 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); | 5152 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); |
| 5153 int stack_space = 0; |
| 5154 MemOperand is_construct_call_operand = |
| 5155 MemOperand(masm->StackPointer(), 4 * kPointerSize); |
| 5156 MemOperand* stack_space_operand = &is_construct_call_operand; |
| 5157 if (argc.is_immediate()) { |
| 5158 stack_space = argc.immediate() + FCA::kArgsLength + 1; |
| 5159 stack_space_operand = NULL; |
| 5160 } |
5139 | 5161 |
5140 const int spill_offset = 1 + kApiStackSpace; | 5162 const int spill_offset = 1 + kApiStackSpace; |
5141 __ CallApiFunctionAndReturn(api_function_address, | 5163 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space, |
5142 thunk_ref, | 5164 stack_space_operand, spill_offset, |
5143 kStackUnwindSpace, | 5165 return_value_operand, &context_restore_operand); |
5144 spill_offset, | |
5145 return_value_operand, | |
5146 &context_restore_operand); | |
5147 } | 5166 } |
5148 | 5167 |
5149 | 5168 |
| 5169 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
| 5170 bool call_data_undefined = this->call_data_undefined(); |
| 5171 CallApiFunctionStubHelper(masm, ParameterCount(x3), false, |
| 5172 call_data_undefined); |
| 5173 } |
| 5174 |
| 5175 |
| 5176 void CallApiAccessorStub::Generate(MacroAssembler* masm) { |
| 5177 bool is_store = this->is_store(); |
| 5178 int argc = is_store ? 1 : 0; |
| 5179 bool call_data_undefined = this->call_data_undefined(); |
| 5180 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, |
| 5181 call_data_undefined); |
| 5182 } |
| 5183 |
| 5184 |
5150 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5185 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
5151 // ----------- S t a t e ------------- | 5186 // ----------- S t a t e ------------- |
5152 // -- sp[0] : name | 5187 // -- sp[0] : name |
5153 // -- sp[8 - kArgsLength*8] : PropertyCallbackArguments object | 5188 // -- sp[8 - kArgsLength*8] : PropertyCallbackArguments object |
5154 // -- ... | 5189 // -- ... |
5155 // -- x2 : api_function_address | 5190 // -- x2 : api_function_address |
5156 // ----------------------------------- | 5191 // ----------------------------------- |
5157 | 5192 |
5158 Register api_function_address = ApiGetterDescriptor::function_address(); | 5193 Register api_function_address = ApiGetterDescriptor::function_address(); |
5159 DCHECK(api_function_address.is(x2)); | 5194 DCHECK(api_function_address.is(x2)); |
(...skipping 14 matching lines...) Expand all Loading... |
5174 // x1 (internal::Object** args_) as the data. | 5209 // x1 (internal::Object** args_) as the data. |
5175 __ Poke(x1, 1 * kPointerSize); | 5210 __ Poke(x1, 1 * kPointerSize); |
5176 __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo& | 5211 __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo& |
5177 | 5212 |
5178 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 5213 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
5179 | 5214 |
5180 ExternalReference thunk_ref = | 5215 ExternalReference thunk_ref = |
5181 ExternalReference::invoke_accessor_getter_callback(isolate()); | 5216 ExternalReference::invoke_accessor_getter_callback(isolate()); |
5182 | 5217 |
5183 const int spill_offset = 1 + kApiStackSpace; | 5218 const int spill_offset = 1 + kApiStackSpace; |
5184 __ CallApiFunctionAndReturn(api_function_address, | 5219 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, |
5185 thunk_ref, | 5220 kStackUnwindSpace, NULL, spill_offset, |
5186 kStackUnwindSpace, | 5221 MemOperand(fp, 6 * kPointerSize), NULL); |
5187 spill_offset, | |
5188 MemOperand(fp, 6 * kPointerSize), | |
5189 NULL); | |
5190 } | 5222 } |
5191 | 5223 |
5192 | 5224 |
5193 #undef __ | 5225 #undef __ |
5194 | 5226 |
5195 } } // namespace v8::internal | 5227 } } // namespace v8::internal |
5196 | 5228 |
5197 #endif // V8_TARGET_ARCH_ARM64 | 5229 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |