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