OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_ | 5 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_ |
6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_ | 6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_ |
7 | 7 |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/assembler.h" | 10 #include "src/assembler.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 V(MathPowInteger) \ | 99 V(MathPowInteger) \ |
100 V(GrowArrayElements) \ | 100 V(GrowArrayElements) \ |
101 V(InterpreterDispatch) \ | 101 V(InterpreterDispatch) \ |
102 V(InterpreterPushArgsAndCall) \ | 102 V(InterpreterPushArgsAndCall) \ |
103 V(InterpreterPushArgsAndConstruct) \ | 103 V(InterpreterPushArgsAndConstruct) \ |
104 V(InterpreterCEntry) \ | 104 V(InterpreterCEntry) \ |
105 V(ResumeGenerator) | 105 V(ResumeGenerator) |
106 | 106 |
107 class CallInterfaceDescriptorData { | 107 class CallInterfaceDescriptorData { |
108 public: | 108 public: |
109 CallInterfaceDescriptorData() | 109 CallInterfaceDescriptorData() : register_param_count_(-1), param_count_(-1) {} |
110 : register_param_count_(-1), function_type_(nullptr) {} | |
111 | 110 |
112 // A copy of the passed in registers and param_representations is made | 111 // A copy of the passed in registers and param_representations is made |
113 // and owned by the CallInterfaceDescriptorData. | 112 // and owned by the CallInterfaceDescriptorData. |
114 | 113 |
115 void InitializePlatformIndependent(FunctionType* function_type) { | |
116 function_type_ = function_type; | |
117 } | |
118 | |
119 // TODO(mvstanton): Instead of taking parallel arrays register and | |
120 // param_representations, how about a struct that puts the representation | |
121 // and register side by side (eg, RegRep(r1, Representation::Tagged()). | |
122 // The same should go for the CodeStubDescriptor class. | |
123 void InitializePlatformSpecific( | 114 void InitializePlatformSpecific( |
124 int register_parameter_count, const Register* registers, | 115 int register_parameter_count, const Register* registers, |
125 PlatformInterfaceDescriptor* platform_descriptor = NULL); | 116 PlatformInterfaceDescriptor* platform_descriptor = NULL); |
126 | 117 |
127 bool IsInitialized() const { return register_param_count_ >= 0; } | 118 // if machine_types is null, then an array of size |
| 119 // (register_parameter_count + extra_parameter_count) will be created |
| 120 // with MachineType::AnyTagged() for each member. |
| 121 // |
| 122 // if machine_types is not null, then it should be of the size |
| 123 // register_parameter_count. Those members of the parameter array |
| 124 // will be initialized from {machine_types}, and the rest initialized |
| 125 // to MachineType::AnyTagged(). |
| 126 void InitializePlatformIndependent(int parameter_count, |
| 127 int extra_parameter_count, |
| 128 const MachineType* machine_types); |
128 | 129 |
129 int param_count() const { return function_type_->Arity(); } | 130 bool IsInitialized() const { |
| 131 return register_param_count_ >= 0 && param_count_ >= 0; |
| 132 } |
| 133 |
| 134 int param_count() const { return param_count_; } |
130 int register_param_count() const { return register_param_count_; } | 135 int register_param_count() const { return register_param_count_; } |
131 Register register_param(int index) const { return register_params_[index]; } | 136 Register register_param(int index) const { return register_params_[index]; } |
132 Register* register_params() const { return register_params_.get(); } | 137 Register* register_params() const { return register_params_.get(); } |
133 Type* param_type(int index) const { return function_type_->Parameter(index); } | 138 MachineType param_type(int index) const { return machine_types_[index]; } |
134 PlatformInterfaceDescriptor* platform_specific_descriptor() const { | 139 PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
135 return platform_specific_descriptor_; | 140 return platform_specific_descriptor_; |
136 } | 141 } |
137 | 142 |
138 private: | 143 private: |
139 int register_param_count_; | 144 int register_param_count_; |
| 145 int param_count_; |
140 | 146 |
141 // The Register params are allocated dynamically by the | 147 // The Register params are allocated dynamically by the |
142 // InterfaceDescriptor, and freed on destruction. This is because static | 148 // InterfaceDescriptor, and freed on destruction. This is because static |
143 // arrays of Registers cause creation of runtime static initializers | 149 // arrays of Registers cause creation of runtime static initializers |
144 // which we don't want. | 150 // which we don't want. |
145 std::unique_ptr<Register[]> register_params_; | 151 std::unique_ptr<Register[]> register_params_; |
146 | 152 std::unique_ptr<MachineType[]> machine_types_; |
147 // Specifies types for parameters and return | |
148 FunctionType* function_type_; | |
149 | 153 |
150 PlatformInterfaceDescriptor* platform_specific_descriptor_; | 154 PlatformInterfaceDescriptor* platform_specific_descriptor_; |
151 | 155 |
152 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); | 156 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); |
153 }; | 157 }; |
154 | 158 |
155 | 159 |
156 class CallDescriptors { | 160 class CallDescriptors { |
157 public: | 161 public: |
158 enum Key { | 162 enum Key { |
(...skipping 20 matching lines...) Expand all Loading... |
179 } | 183 } |
180 | 184 |
181 int GetStackParameterCount() const { | 185 int GetStackParameterCount() const { |
182 return data()->param_count() - data()->register_param_count(); | 186 return data()->param_count() - data()->register_param_count(); |
183 } | 187 } |
184 | 188 |
185 Register GetRegisterParameter(int index) const { | 189 Register GetRegisterParameter(int index) const { |
186 return data()->register_param(index); | 190 return data()->register_param(index); |
187 } | 191 } |
188 | 192 |
189 Type* GetParameterType(int index) const { | 193 MachineType GetParameterType(int index) const { |
190 DCHECK(index < data()->param_count()); | 194 DCHECK(index < data()->param_count()); |
191 return data()->param_type(index); | 195 return data()->param_type(index); |
192 } | 196 } |
193 | 197 |
194 // Some platforms have extra information to associate with the descriptor. | 198 // Some platforms have extra information to associate with the descriptor. |
195 PlatformInterfaceDescriptor* platform_specific_descriptor() const { | 199 PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
196 return data()->platform_specific_descriptor(); | 200 return data()->platform_specific_descriptor(); |
197 } | 201 } |
198 | 202 |
199 static const Register ContextRegister(); | 203 static const Register ContextRegister(); |
200 | 204 |
201 const char* DebugName(Isolate* isolate) const; | 205 const char* DebugName(Isolate* isolate) const; |
202 | 206 |
203 static FunctionType* BuildDefaultFunctionType(Isolate* isolate, | |
204 int parameter_count); | |
205 | |
206 protected: | 207 protected: |
207 const CallInterfaceDescriptorData* data() const { return data_; } | 208 const CallInterfaceDescriptorData* data() const { return data_; } |
208 | 209 |
209 virtual FunctionType* BuildCallInterfaceDescriptorFunctionType( | |
210 Isolate* isolate, int register_param_count) { | |
211 return BuildDefaultFunctionType(isolate, register_param_count); | |
212 } | |
213 | |
214 virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) { | 210 virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) { |
215 UNREACHABLE(); | 211 UNREACHABLE(); |
216 } | 212 } |
217 | 213 |
| 214 virtual void InitializePlatformIndependent( |
| 215 CallInterfaceDescriptorData* data) { |
| 216 data->InitializePlatformIndependent(data->register_param_count(), 0, NULL); |
| 217 } |
| 218 |
218 void Initialize(Isolate* isolate, CallDescriptors::Key key) { | 219 void Initialize(Isolate* isolate, CallDescriptors::Key key) { |
219 if (!data()->IsInitialized()) { | 220 if (!data()->IsInitialized()) { |
220 // We should only initialize descriptors on the isolate's main thread. | 221 // We should only initialize descriptors on the isolate's main thread. |
221 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); | 222 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
222 CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key); | 223 CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key); |
223 DCHECK(d == data()); // d should be a modifiable pointer to data(). | 224 DCHECK(d == data()); // d should be a modifiable pointer to data(). |
224 InitializePlatformSpecific(d); | 225 InitializePlatformSpecific(d); |
225 FunctionType* function_type = BuildCallInterfaceDescriptorFunctionType( | 226 InitializePlatformIndependent(d); |
226 isolate, d->register_param_count()); | |
227 d->InitializePlatformIndependent(function_type); | |
228 } | 227 } |
229 } | 228 } |
230 | 229 |
231 // Initializes |data| using the platform dependent default set of registers. | 230 // Initializes |data| using the platform dependent default set of registers. |
232 // It is intended to be used for TurboFan stubs when particular set of | 231 // It is intended to be used for TurboFan stubs when particular set of |
233 // registers does not matter. | 232 // registers does not matter. |
234 static void DefaultInitializePlatformSpecific( | 233 static void DefaultInitializePlatformSpecific( |
235 CallInterfaceDescriptorData* data, int register_parameter_count); | 234 CallInterfaceDescriptorData* data, int register_parameter_count); |
236 | 235 |
237 private: | 236 private: |
(...skipping 19 matching lines...) Expand all Loading... |
257 public: | 256 public: |
258 | 257 |
259 #define DECLARE_DESCRIPTOR(name, base) \ | 258 #define DECLARE_DESCRIPTOR(name, base) \ |
260 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ | 259 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ |
261 protected: \ | 260 protected: \ |
262 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \ | 261 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \ |
263 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ | 262 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ |
264 \ | 263 \ |
265 public: | 264 public: |
266 | 265 |
267 #define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \ | 266 #define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \ |
268 DECLARE_DESCRIPTOR(name, base) \ | 267 DECLARE_DESCRIPTOR(name, base) \ |
269 protected: \ | 268 protected: \ |
270 FunctionType* BuildCallInterfaceDescriptorFunctionType( \ | 269 void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \ |
271 Isolate* isolate, int register_param_count) override; \ | 270 override; \ |
272 \ | 271 \ |
273 public: | 272 public: |
274 | 273 |
275 #define DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(name, base, arg) \ | 274 #define DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(name, base, arg) \ |
276 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ | 275 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ |
277 protected: \ | 276 protected: \ |
278 FunctionType* BuildCallInterfaceDescriptorFunctionType( \ | 277 int extra_args() const override { return arg; } \ |
279 Isolate* isolate, int register_param_count) override { \ | |
280 return BuildCallInterfaceDescriptorFunctionTypeWithArg( \ | |
281 isolate, register_param_count, arg); \ | |
282 } \ | |
283 \ | 278 \ |
284 public: | 279 public: |
285 | 280 |
286 #define DEFINE_PARAMETERS(...) \ | 281 #define DEFINE_PARAMETERS(...) \ |
287 enum ParameterIndices { \ | 282 enum ParameterIndices { \ |
288 __VA_ARGS__, \ | 283 __VA_ARGS__, \ |
289 \ | 284 \ |
290 kParameterCount, \ | 285 kParameterCount, \ |
291 kContext = kParameterCount /* implicit parameter */ \ | 286 kContext = kParameterCount /* implicit parameter */ \ |
292 }; | 287 }; |
(...skipping 12 matching lines...) Expand all Loading... |
305 // OnStackArgsDescriptorBase is not meant to be instantiated directly and has no | 300 // OnStackArgsDescriptorBase is not meant to be instantiated directly and has no |
306 // public constructors to ensure this is so.contains all the logic, and the | 301 // public constructors to ensure this is so.contains all the logic, and the |
307 // | 302 // |
308 // Use OnStackArgsDescriptorBase::ForArgs(isolate, parameter_count) to | 303 // Use OnStackArgsDescriptorBase::ForArgs(isolate, parameter_count) to |
309 // instantiate a descriptor with the number of args. | 304 // instantiate a descriptor with the number of args. |
310 class OnStackArgsDescriptorBase : public CallInterfaceDescriptor { | 305 class OnStackArgsDescriptorBase : public CallInterfaceDescriptor { |
311 public: | 306 public: |
312 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int parameter_count); | 307 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int parameter_count); |
313 | 308 |
314 protected: | 309 protected: |
| 310 virtual int extra_args() const { return 0; } |
315 OnStackArgsDescriptorBase(Isolate* isolate, CallDescriptors::Key key) | 311 OnStackArgsDescriptorBase(Isolate* isolate, CallDescriptors::Key key) |
316 : CallInterfaceDescriptor(isolate, key) {} | 312 : CallInterfaceDescriptor(isolate, key) {} |
317 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; | 313 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; |
318 FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg( | 314 void InitializePlatformIndependent( |
319 Isolate* isolate, int register_parameter_count, int parameter_count); | 315 CallInterfaceDescriptorData* data) override; |
320 }; | 316 }; |
321 | 317 |
322 class OnStackWith1ArgsDescriptor : public OnStackArgsDescriptorBase { | 318 class OnStackWith1ArgsDescriptor : public OnStackArgsDescriptorBase { |
323 public: | 319 public: |
324 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith1ArgsDescriptor, | 320 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith1ArgsDescriptor, |
325 OnStackArgsDescriptorBase, | 321 OnStackArgsDescriptorBase, |
326 1) | 322 1) |
327 }; | 323 }; |
328 | 324 |
329 class OnStackWith2ArgsDescriptor : public OnStackArgsDescriptorBase { | 325 class OnStackWith2ArgsDescriptor : public OnStackArgsDescriptorBase { |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // | 784 // |
789 // The simplest usage for all the ApiCallback*Descriptors is probably | 785 // The simplest usage for all the ApiCallback*Descriptors is probably |
790 // ApiCallbackDescriptorBase::ForArgs(isolate, argc) | 786 // ApiCallbackDescriptorBase::ForArgs(isolate, argc) |
791 // | 787 // |
792 class ApiCallbackDescriptorBase : public CallInterfaceDescriptor { | 788 class ApiCallbackDescriptorBase : public CallInterfaceDescriptor { |
793 public: | 789 public: |
794 DEFINE_PARAMETERS(kFunction, kCallData, kHolder, kApiFunctionAddress) | 790 DEFINE_PARAMETERS(kFunction, kCallData, kHolder, kApiFunctionAddress) |
795 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int argc); | 791 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int argc); |
796 | 792 |
797 protected: | 793 protected: |
| 794 virtual int extra_args() const { return 0; } |
798 ApiCallbackDescriptorBase(Isolate* isolate, CallDescriptors::Key key) | 795 ApiCallbackDescriptorBase(Isolate* isolate, CallDescriptors::Key key) |
799 : CallInterfaceDescriptor(isolate, key) {} | 796 : CallInterfaceDescriptor(isolate, key) {} |
800 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; | 797 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; |
801 FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg( | 798 void InitializePlatformIndependent( |
802 Isolate* isolate, int parameter_count, int argc); | 799 CallInterfaceDescriptorData* data) override; |
803 }; | 800 }; |
804 | 801 |
805 class ApiCallbackWith0ArgsDescriptor : public ApiCallbackDescriptorBase { | 802 class ApiCallbackWith0ArgsDescriptor : public ApiCallbackDescriptorBase { |
806 public: | 803 public: |
807 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( | 804 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( |
808 ApiCallbackWith0ArgsDescriptor, ApiCallbackDescriptorBase, 0) | 805 ApiCallbackWith0ArgsDescriptor, ApiCallbackDescriptorBase, 0) |
809 }; | 806 }; |
810 | 807 |
811 class ApiCallbackWith1ArgsDescriptor : public ApiCallbackDescriptorBase { | 808 class ApiCallbackWith1ArgsDescriptor : public ApiCallbackDescriptorBase { |
812 public: | 809 public: |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 } // namespace v8 | 940 } // namespace v8 |
944 | 941 |
945 | 942 |
946 #if V8_TARGET_ARCH_ARM64 | 943 #if V8_TARGET_ARCH_ARM64 |
947 #include "src/arm64/interface-descriptors-arm64.h" | 944 #include "src/arm64/interface-descriptors-arm64.h" |
948 #elif V8_TARGET_ARCH_ARM | 945 #elif V8_TARGET_ARCH_ARM |
949 #include "src/arm/interface-descriptors-arm.h" | 946 #include "src/arm/interface-descriptors-arm.h" |
950 #endif | 947 #endif |
951 | 948 |
952 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ | 949 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ |
OLD | NEW |