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
3 // found in the LICENSE file.
5 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_
6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_
8 #include "src/assembler.h"
9 #include "src/macro-assembler.h"
14 class PlatformInterfaceDescriptor;
16 #define INTERFACE_DESCRIPTOR_LIST(V) \
20 V(ElementTransitionAndStore) \
22 V(VectorLoadICTrampoline) \
28 V(FastCloneShallowArray) \
29 V(FastCloneShallowObject) \
30 V(CreateAllocationSite) \
33 V(CallFunctionWithFeedback) \
34 V(CallFunctionWithFeedbackAndVector) \
36 V(RegExpConstructResult) \
37 V(TransitionElementsKind) \
38 V(AllocateHeapNumber) \
39 V(ArrayConstructorConstantArgCount) \
41 V(InternalArrayConstructorConstantArgCount) \
42 V(InternalArrayConstructor) \
46 V(BinaryOpWithAllocationSite) \
55 V(ArgumentsAccessRead) \
56 V(StoreArrayLiteralElement) \
62 class CallInterfaceDescriptorData {
64 CallInterfaceDescriptorData() : register_param_count_(-1) {}
66 // A copy of the passed in registers and param_representations is made
67 // and owned by the CallInterfaceDescriptorData.
69 // TODO(mvstanton): Instead of taking parallel arrays register and
70 // param_representations, how about a struct that puts the representation
71 // and register side by side (eg, RegRep(r1, Representation::Tagged()).
72 // The same should go for the CodeStubDescriptor class.
73 void Initialize(int register_parameter_count, Register* registers,
74 Representation* param_representations,
75 PlatformInterfaceDescriptor* platform_descriptor = NULL);
77 bool IsInitialized() const { return register_param_count_ >= 0; }
79 int register_param_count() const { return register_param_count_; }
80 Register register_param(int index) const { return register_params_[index]; }
81 Register* register_params() const { return register_params_.get(); }
82 Representation register_param_representation(int index) const {
83 return register_param_representations_[index];
85 Representation* register_param_representations() const {
86 return register_param_representations_.get();
88 PlatformInterfaceDescriptor* platform_specific_descriptor() const {
89 return platform_specific_descriptor_;
93 int register_param_count_;
95 // The Register params are allocated dynamically by the
96 // InterfaceDescriptor, and freed on destruction. This is because static
97 // arrays of Registers cause creation of runtime static initializers
98 // which we don't want.
99 SmartArrayPointer<Register> register_params_;
100 // Specifies Representations for the stub's parameter. Points to an array of
101 // Representations of the same length of the numbers of parameters to the
102 // stub, or if NULL (the default value), Representation of each parameter
103 // assumed to be Tagged().
104 SmartArrayPointer<Representation> register_param_representations_;
106 PlatformInterfaceDescriptor* platform_specific_descriptor_;
108 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
112 class CallDescriptors {
115 #define DEF_ENUM(name) name,
116 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
118 NUMBER_OF_DESCRIPTORS
123 class CallInterfaceDescriptor {
125 CallInterfaceDescriptor() : data_(NULL) {}
127 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
128 : data_(isolate->call_descriptor_data(key)) {}
130 int GetEnvironmentLength() const { return data()->register_param_count(); }
132 int GetRegisterParameterCount() const {
133 return data()->register_param_count();
136 Register GetParameterRegister(int index) const {
137 return data()->register_param(index);
140 Representation GetParameterRepresentation(int index) const {
141 DCHECK(index < data()->register_param_count());
142 if (data()->register_param_representations() == NULL) {
143 return Representation::Tagged();
146 return data()->register_param_representation(index);
149 // "Environment" versions of parameter functions. The first register
150 // parameter (context) is not included.
151 int GetEnvironmentParameterCount() const {
152 return GetEnvironmentLength() - 1;
155 Register GetEnvironmentParameterRegister(int index) const {
156 return GetParameterRegister(index + 1);
159 Representation GetEnvironmentParameterRepresentation(int index) const {
160 return GetParameterRepresentation(index + 1);
163 // Some platforms have extra information to associate with the descriptor.
164 PlatformInterfaceDescriptor* platform_specific_descriptor() const {
165 return data()->platform_specific_descriptor();
168 static const Register ContextRegister();
170 const char* DebugName(Isolate* isolate) const;
173 const CallInterfaceDescriptorData* data() const { return data_; }
176 const CallInterfaceDescriptorData* data_;
180 #define DECLARE_DESCRIPTOR(name, base) \
181 explicit name(Isolate* isolate) : base(isolate, key()) { \
182 if (!data()->IsInitialized()) \
183 Initialize(isolate->call_descriptor_data(key())); \
187 void Initialize(CallInterfaceDescriptorData* data); \
188 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
191 static inline CallDescriptors::Key key();
194 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
195 class LoadDescriptor : public CallInterfaceDescriptor {
197 DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
199 enum ParameterIndices { kReceiverIndex, kNameIndex };
200 static const Register ReceiverRegister();
201 static const Register NameRegister();
205 class StoreDescriptor : public CallInterfaceDescriptor {
207 DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
209 enum ParameterIndices {
215 static const Register ReceiverRegister();
216 static const Register NameRegister();
217 static const Register ValueRegister();
221 class StoreTransitionDescriptor : public StoreDescriptor {
223 DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
225 // Extends StoreDescriptor with Map parameter.
226 enum ParameterIndices {
233 static const Register MapRegister();
237 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
239 DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
241 static const Register MapRegister();
245 class InstanceofDescriptor : public CallInterfaceDescriptor {
247 DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor)
249 enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
250 static const Register left();
251 static const Register right();
255 class VectorLoadICTrampolineDescriptor : public LoadDescriptor {
257 DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor)
259 enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex };
261 static const Register SlotRegister();
265 class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor {
267 DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor)
269 enum ParameterIndices {
276 static const Register VectorRegister();
280 class FastNewClosureDescriptor : public CallInterfaceDescriptor {
282 DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
286 class FastNewContextDescriptor : public CallInterfaceDescriptor {
288 DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
292 class ToNumberDescriptor : public CallInterfaceDescriptor {
294 DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
298 class NumberToStringDescriptor : public CallInterfaceDescriptor {
300 DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
304 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
306 DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
310 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
312 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
316 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
318 DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
322 class CreateWeakCellDescriptor : public CallInterfaceDescriptor {
324 enum ParameterIndices {
331 DECLARE_DESCRIPTOR(CreateWeakCellDescriptor, CallInterfaceDescriptor)
335 class CallFunctionDescriptor : public CallInterfaceDescriptor {
337 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
341 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
343 DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
344 CallInterfaceDescriptor)
348 class CallFunctionWithFeedbackAndVectorDescriptor
349 : public CallInterfaceDescriptor {
351 DECLARE_DESCRIPTOR(CallFunctionWithFeedbackAndVectorDescriptor,
352 CallInterfaceDescriptor)
356 class CallConstructDescriptor : public CallInterfaceDescriptor {
358 DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
362 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
364 DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
368 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
370 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
374 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
376 DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
380 class ArrayConstructorConstantArgCountDescriptor
381 : public CallInterfaceDescriptor {
383 DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
384 CallInterfaceDescriptor)
388 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
390 DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
394 class InternalArrayConstructorConstantArgCountDescriptor
395 : public CallInterfaceDescriptor {
397 DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
398 CallInterfaceDescriptor)
402 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
404 DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
405 CallInterfaceDescriptor)
409 class CompareNilDescriptor : public CallInterfaceDescriptor {
411 DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
415 class ToBooleanDescriptor : public CallInterfaceDescriptor {
417 DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
421 class BinaryOpDescriptor : public CallInterfaceDescriptor {
423 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
427 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
429 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
430 CallInterfaceDescriptor)
434 class StringAddDescriptor : public CallInterfaceDescriptor {
436 DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
440 class KeyedDescriptor : public CallInterfaceDescriptor {
442 DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
446 class NamedDescriptor : public CallInterfaceDescriptor {
448 DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
452 class CallHandlerDescriptor : public CallInterfaceDescriptor {
454 DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
458 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
460 DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
464 class ApiFunctionDescriptor : public CallInterfaceDescriptor {
466 DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
470 class ApiAccessorDescriptor : public CallInterfaceDescriptor {
472 DECLARE_DESCRIPTOR(ApiAccessorDescriptor, CallInterfaceDescriptor)
476 class ApiGetterDescriptor : public CallInterfaceDescriptor {
478 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
480 static const Register function_address();
484 class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
486 DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor)
488 static const Register index();
489 static const Register parameter_count();
493 class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
495 DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
496 CallInterfaceDescriptor)
500 class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
502 DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
504 static const Register exponent();
508 class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
510 DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
512 static const Register exponent();
516 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
518 DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
521 #undef DECLARE_DESCRIPTOR
524 // We define the association between CallDescriptors::Key and the specialized
525 // descriptor here to reduce boilerplate and mistakes.
526 #define DEF_KEY(name) \
527 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
528 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
531 } // namespace v8::internal
534 #if V8_TARGET_ARCH_ARM64
535 #include "src/arm64/interface-descriptors-arm64.h"
536 #elif V8_TARGET_ARCH_ARM
537 #include "src/arm/interface-descriptors-arm.h"
540 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_