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) \
47 V(BinaryOpWithAllocationSite) \
56 V(ArgumentsAccessRead) \
57 V(StoreArrayLiteralElement) \
63 class CallInterfaceDescriptorData {
65 CallInterfaceDescriptorData() : register_param_count_(-1) {}
67 // A copy of the passed in registers and param_representations is made
68 // and owned by the CallInterfaceDescriptorData.
70 // TODO(mvstanton): Instead of taking parallel arrays register and
71 // param_representations, how about a struct that puts the representation
72 // and register side by side (eg, RegRep(r1, Representation::Tagged()).
73 // The same should go for the CodeStubDescriptor class.
74 void Initialize(int register_parameter_count, Register* registers,
75 Representation* param_representations,
76 PlatformInterfaceDescriptor* platform_descriptor = NULL);
78 bool IsInitialized() const { return register_param_count_ >= 0; }
80 int register_param_count() const { return register_param_count_; }
81 Register register_param(int index) const { return register_params_[index]; }
82 Register* register_params() const { return register_params_.get(); }
83 Representation register_param_representation(int index) const {
84 return register_param_representations_[index];
86 Representation* register_param_representations() const {
87 return register_param_representations_.get();
89 PlatformInterfaceDescriptor* platform_specific_descriptor() const {
90 return platform_specific_descriptor_;
94 int register_param_count_;
96 // The Register params are allocated dynamically by the
97 // InterfaceDescriptor, and freed on destruction. This is because static
98 // arrays of Registers cause creation of runtime static initializers
99 // which we don't want.
100 SmartArrayPointer<Register> register_params_;
101 // Specifies Representations for the stub's parameter. Points to an array of
102 // Representations of the same length of the numbers of parameters to the
103 // stub, or if NULL (the default value), Representation of each parameter
104 // assumed to be Tagged().
105 SmartArrayPointer<Representation> register_param_representations_;
107 PlatformInterfaceDescriptor* platform_specific_descriptor_;
109 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
113 class CallDescriptors {
116 #define DEF_ENUM(name) name,
117 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
119 NUMBER_OF_DESCRIPTORS
124 class CallInterfaceDescriptor {
126 CallInterfaceDescriptor() : data_(NULL) {}
128 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
129 : data_(isolate->call_descriptor_data(key)) {}
131 int GetEnvironmentLength() const { return data()->register_param_count(); }
133 int GetRegisterParameterCount() const {
134 return data()->register_param_count();
137 Register GetParameterRegister(int index) const {
138 return data()->register_param(index);
141 Representation GetParameterRepresentation(int index) const {
142 DCHECK(index < data()->register_param_count());
143 if (data()->register_param_representations() == NULL) {
144 return Representation::Tagged();
147 return data()->register_param_representation(index);
150 // "Environment" versions of parameter functions. The first register
151 // parameter (context) is not included.
152 int GetEnvironmentParameterCount() const {
153 return GetEnvironmentLength() - 1;
156 Register GetEnvironmentParameterRegister(int index) const {
157 return GetParameterRegister(index + 1);
160 Representation GetEnvironmentParameterRepresentation(int index) const {
161 return GetParameterRepresentation(index + 1);
164 // Some platforms have extra information to associate with the descriptor.
165 PlatformInterfaceDescriptor* platform_specific_descriptor() const {
166 return data()->platform_specific_descriptor();
169 static const Register ContextRegister();
171 const char* DebugName(Isolate* isolate) const;
174 const CallInterfaceDescriptorData* data() const { return data_; }
177 const CallInterfaceDescriptorData* data_;
181 #define DECLARE_DESCRIPTOR(name, base) \
182 explicit name(Isolate* isolate) : base(isolate, key()) { \
183 if (!data()->IsInitialized()) \
184 Initialize(isolate->call_descriptor_data(key())); \
188 void Initialize(CallInterfaceDescriptorData* data); \
189 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
192 static inline CallDescriptors::Key key();
195 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
196 class LoadDescriptor : public CallInterfaceDescriptor {
198 DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
200 enum ParameterIndices { kReceiverIndex, kNameIndex };
201 static const Register ReceiverRegister();
202 static const Register NameRegister();
206 class StoreDescriptor : public CallInterfaceDescriptor {
208 DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
210 enum ParameterIndices {
216 static const Register ReceiverRegister();
217 static const Register NameRegister();
218 static const Register ValueRegister();
222 class StoreTransitionDescriptor : public StoreDescriptor {
224 DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
226 // Extends StoreDescriptor with Map parameter.
227 enum ParameterIndices {
234 static const Register MapRegister();
238 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
240 DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
242 static const Register MapRegister();
246 class InstanceofDescriptor : public CallInterfaceDescriptor {
248 DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor)
250 enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
251 static const Register left();
252 static const Register right();
256 class VectorLoadICTrampolineDescriptor : public LoadDescriptor {
258 DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor)
260 enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex };
262 static const Register SlotRegister();
266 class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor {
268 DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor)
270 enum ParameterIndices {
277 static const Register VectorRegister();
281 class FastNewClosureDescriptor : public CallInterfaceDescriptor {
283 DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
287 class FastNewContextDescriptor : public CallInterfaceDescriptor {
289 DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
293 class ToNumberDescriptor : public CallInterfaceDescriptor {
295 DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
299 class NumberToStringDescriptor : public CallInterfaceDescriptor {
301 DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
305 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
307 DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
311 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
313 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
317 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
319 DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
323 class CreateWeakCellDescriptor : public CallInterfaceDescriptor {
325 enum ParameterIndices {
332 DECLARE_DESCRIPTOR(CreateWeakCellDescriptor, CallInterfaceDescriptor)
336 class CallFunctionDescriptor : public CallInterfaceDescriptor {
338 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
342 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
344 DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
345 CallInterfaceDescriptor)
349 class CallFunctionWithFeedbackAndVectorDescriptor
350 : public CallInterfaceDescriptor {
352 DECLARE_DESCRIPTOR(CallFunctionWithFeedbackAndVectorDescriptor,
353 CallInterfaceDescriptor)
357 class CallConstructDescriptor : public CallInterfaceDescriptor {
359 DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
363 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
365 DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
369 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
371 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
375 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
377 DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
381 class ArrayConstructorConstantArgCountDescriptor
382 : public CallInterfaceDescriptor {
384 DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
385 CallInterfaceDescriptor)
389 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
391 DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
395 class InternalArrayConstructorConstantArgCountDescriptor
396 : public CallInterfaceDescriptor {
398 DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
399 CallInterfaceDescriptor)
403 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
405 DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
406 CallInterfaceDescriptor)
410 class CompareDescriptor : public CallInterfaceDescriptor {
412 DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
416 class CompareNilDescriptor : public CallInterfaceDescriptor {
418 DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
422 class ToBooleanDescriptor : public CallInterfaceDescriptor {
424 DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
428 class BinaryOpDescriptor : public CallInterfaceDescriptor {
430 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
434 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
436 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
437 CallInterfaceDescriptor)
441 class StringAddDescriptor : public CallInterfaceDescriptor {
443 DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
447 class KeyedDescriptor : public CallInterfaceDescriptor {
449 DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
453 class NamedDescriptor : public CallInterfaceDescriptor {
455 DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
459 class CallHandlerDescriptor : public CallInterfaceDescriptor {
461 DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
465 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
467 DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
471 class ApiFunctionDescriptor : public CallInterfaceDescriptor {
473 DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
477 class ApiAccessorDescriptor : public CallInterfaceDescriptor {
479 DECLARE_DESCRIPTOR(ApiAccessorDescriptor, CallInterfaceDescriptor)
483 class ApiGetterDescriptor : public CallInterfaceDescriptor {
485 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
487 static const Register function_address();
491 class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
493 DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor)
495 static const Register index();
496 static const Register parameter_count();
500 class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
502 DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
503 CallInterfaceDescriptor)
507 class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
509 DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
511 static const Register exponent();
515 class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
517 DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
519 static const Register exponent();
523 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
525 DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
528 #undef DECLARE_DESCRIPTOR
531 // We define the association between CallDescriptors::Key and the specialized
532 // descriptor here to reduce boilerplate and mistakes.
533 #define DEF_KEY(name) \
534 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
535 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
538 } // namespace v8::internal
541 #if V8_TARGET_ARCH_ARM64
542 #include "src/arm64/interface-descriptors-arm64.h"
543 #elif V8_TARGET_ARCH_ARM
544 #include "src/arm/interface-descriptors-arm.h"
547 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_