51fb9204f200b0be082bde27b64c02096c23857c
[platform/upstream/nodejs.git] / deps / v8 / src / interface-descriptors.h
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.
4
5 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_
6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_
7
8 #include "src/assembler.h"
9 #include "src/macro-assembler.h"
10
11 namespace v8 {
12 namespace internal {
13
14 class PlatformInterfaceDescriptor;
15
16 #define INTERFACE_DESCRIPTOR_LIST(V)          \
17   V(Load)                                     \
18   V(Store)                                    \
19   V(StoreTransition)                          \
20   V(ElementTransitionAndStore)                \
21   V(Instanceof)                               \
22   V(VectorLoadICTrampoline)                   \
23   V(VectorLoadIC)                             \
24   V(FastNewClosure)                           \
25   V(FastNewContext)                           \
26   V(ToNumber)                                 \
27   V(NumberToString)                           \
28   V(FastCloneShallowArray)                    \
29   V(FastCloneShallowObject)                   \
30   V(CreateAllocationSite)                     \
31   V(CreateWeakCell)                           \
32   V(CallFunction)                             \
33   V(CallFunctionWithFeedback)                 \
34   V(CallFunctionWithFeedbackAndVector)        \
35   V(CallConstruct)                            \
36   V(RegExpConstructResult)                    \
37   V(TransitionElementsKind)                   \
38   V(AllocateHeapNumber)                       \
39   V(ArrayConstructorConstantArgCount)         \
40   V(ArrayConstructor)                         \
41   V(InternalArrayConstructorConstantArgCount) \
42   V(InternalArrayConstructor)                 \
43   V(CompareNil)                               \
44   V(ToBoolean)                                \
45   V(BinaryOp)                                 \
46   V(BinaryOpWithAllocationSite)               \
47   V(StringAdd)                                \
48   V(Keyed)                                    \
49   V(Named)                                    \
50   V(CallHandler)                              \
51   V(ArgumentAdaptor)                          \
52   V(ApiFunction)                              \
53   V(ApiAccessor)                              \
54   V(ApiGetter)                                \
55   V(ArgumentsAccessRead)                      \
56   V(StoreArrayLiteralElement)                 \
57   V(MathPowTagged)                            \
58   V(MathPowInteger)                           \
59   V(ContextOnly)
60
61
62 class CallInterfaceDescriptorData {
63  public:
64   CallInterfaceDescriptorData() : register_param_count_(-1) {}
65
66   // A copy of the passed in registers and param_representations is made
67   // and owned by the CallInterfaceDescriptorData.
68
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);
76
77   bool IsInitialized() const { return register_param_count_ >= 0; }
78
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];
84   }
85   Representation* register_param_representations() const {
86     return register_param_representations_.get();
87   }
88   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
89     return platform_specific_descriptor_;
90   }
91
92  private:
93   int register_param_count_;
94
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_;
105
106   PlatformInterfaceDescriptor* platform_specific_descriptor_;
107
108   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
109 };
110
111
112 class CallDescriptors {
113  public:
114   enum Key {
115 #define DEF_ENUM(name) name,
116     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
117 #undef DEF_ENUM
118     NUMBER_OF_DESCRIPTORS
119   };
120 };
121
122
123 class CallInterfaceDescriptor {
124  public:
125   CallInterfaceDescriptor() : data_(NULL) {}
126
127   CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
128       : data_(isolate->call_descriptor_data(key)) {}
129
130   int GetEnvironmentLength() const { return data()->register_param_count(); }
131
132   int GetRegisterParameterCount() const {
133     return data()->register_param_count();
134   }
135
136   Register GetParameterRegister(int index) const {
137     return data()->register_param(index);
138   }
139
140   Representation GetParameterRepresentation(int index) const {
141     DCHECK(index < data()->register_param_count());
142     if (data()->register_param_representations() == NULL) {
143       return Representation::Tagged();
144     }
145
146     return data()->register_param_representation(index);
147   }
148
149   // "Environment" versions of parameter functions. The first register
150   // parameter (context) is not included.
151   int GetEnvironmentParameterCount() const {
152     return GetEnvironmentLength() - 1;
153   }
154
155   Register GetEnvironmentParameterRegister(int index) const {
156     return GetParameterRegister(index + 1);
157   }
158
159   Representation GetEnvironmentParameterRepresentation(int index) const {
160     return GetParameterRepresentation(index + 1);
161   }
162
163   // Some platforms have extra information to associate with the descriptor.
164   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
165     return data()->platform_specific_descriptor();
166   }
167
168   static const Register ContextRegister();
169
170   const char* DebugName(Isolate* isolate) const;
171
172  protected:
173   const CallInterfaceDescriptorData* data() const { return data_; }
174
175  private:
176   const CallInterfaceDescriptorData* data_;
177 };
178
179
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()));                    \
184   }                                                                        \
185                                                                            \
186  protected:                                                                \
187   void Initialize(CallInterfaceDescriptorData* data);                      \
188   name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
189                                                                            \
190  public:                                                                   \
191   static inline CallDescriptors::Key key();
192
193
194 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
195 class LoadDescriptor : public CallInterfaceDescriptor {
196  public:
197   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
198
199   enum ParameterIndices { kReceiverIndex, kNameIndex };
200   static const Register ReceiverRegister();
201   static const Register NameRegister();
202 };
203
204
205 class StoreDescriptor : public CallInterfaceDescriptor {
206  public:
207   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
208
209   enum ParameterIndices {
210     kReceiverIndex,
211     kNameIndex,
212     kValueIndex,
213     kParameterCount
214   };
215   static const Register ReceiverRegister();
216   static const Register NameRegister();
217   static const Register ValueRegister();
218 };
219
220
221 class StoreTransitionDescriptor : public StoreDescriptor {
222  public:
223   DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
224
225   // Extends StoreDescriptor with Map parameter.
226   enum ParameterIndices {
227     kReceiverIndex,
228     kNameIndex,
229     kValueIndex,
230     kMapIndex,
231     kParameterCount
232   };
233   static const Register MapRegister();
234 };
235
236
237 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
238  public:
239   DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
240
241   static const Register MapRegister();
242 };
243
244
245 class InstanceofDescriptor : public CallInterfaceDescriptor {
246  public:
247   DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor)
248
249   enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
250   static const Register left();
251   static const Register right();
252 };
253
254
255 class VectorLoadICTrampolineDescriptor : public LoadDescriptor {
256  public:
257   DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor)
258
259   enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex };
260
261   static const Register SlotRegister();
262 };
263
264
265 class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor {
266  public:
267   DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor)
268
269   enum ParameterIndices {
270     kReceiverIndex,
271     kNameIndex,
272     kSlotIndex,
273     kVectorIndex
274   };
275
276   static const Register VectorRegister();
277 };
278
279
280 class FastNewClosureDescriptor : public CallInterfaceDescriptor {
281  public:
282   DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
283 };
284
285
286 class FastNewContextDescriptor : public CallInterfaceDescriptor {
287  public:
288   DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
289 };
290
291
292 class ToNumberDescriptor : public CallInterfaceDescriptor {
293  public:
294   DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
295 };
296
297
298 class NumberToStringDescriptor : public CallInterfaceDescriptor {
299  public:
300   DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
301 };
302
303
304 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
305  public:
306   DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
307 };
308
309
310 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
311  public:
312   DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
313 };
314
315
316 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
317  public:
318   DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
319 };
320
321
322 class CreateWeakCellDescriptor : public CallInterfaceDescriptor {
323  public:
324   enum ParameterIndices {
325     kVectorIndex,
326     kSlotIndex,
327     kValueIndex,
328     kParameterCount
329   };
330
331   DECLARE_DESCRIPTOR(CreateWeakCellDescriptor, CallInterfaceDescriptor)
332 };
333
334
335 class CallFunctionDescriptor : public CallInterfaceDescriptor {
336  public:
337   DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
338 };
339
340
341 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
342  public:
343   DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
344                      CallInterfaceDescriptor)
345 };
346
347
348 class CallFunctionWithFeedbackAndVectorDescriptor
349     : public CallInterfaceDescriptor {
350  public:
351   DECLARE_DESCRIPTOR(CallFunctionWithFeedbackAndVectorDescriptor,
352                      CallInterfaceDescriptor)
353 };
354
355
356 class CallConstructDescriptor : public CallInterfaceDescriptor {
357  public:
358   DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
359 };
360
361
362 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
363  public:
364   DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
365 };
366
367
368 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
369  public:
370   DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
371 };
372
373
374 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
375  public:
376   DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
377 };
378
379
380 class ArrayConstructorConstantArgCountDescriptor
381     : public CallInterfaceDescriptor {
382  public:
383   DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
384                      CallInterfaceDescriptor)
385 };
386
387
388 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
389  public:
390   DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
391 };
392
393
394 class InternalArrayConstructorConstantArgCountDescriptor
395     : public CallInterfaceDescriptor {
396  public:
397   DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
398                      CallInterfaceDescriptor)
399 };
400
401
402 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
403  public:
404   DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
405                      CallInterfaceDescriptor)
406 };
407
408
409 class CompareNilDescriptor : public CallInterfaceDescriptor {
410  public:
411   DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
412 };
413
414
415 class ToBooleanDescriptor : public CallInterfaceDescriptor {
416  public:
417   DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
418 };
419
420
421 class BinaryOpDescriptor : public CallInterfaceDescriptor {
422  public:
423   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
424 };
425
426
427 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
428  public:
429   DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
430                      CallInterfaceDescriptor)
431 };
432
433
434 class StringAddDescriptor : public CallInterfaceDescriptor {
435  public:
436   DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
437 };
438
439
440 class KeyedDescriptor : public CallInterfaceDescriptor {
441  public:
442   DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
443 };
444
445
446 class NamedDescriptor : public CallInterfaceDescriptor {
447  public:
448   DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
449 };
450
451
452 class CallHandlerDescriptor : public CallInterfaceDescriptor {
453  public:
454   DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
455 };
456
457
458 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
459  public:
460   DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
461 };
462
463
464 class ApiFunctionDescriptor : public CallInterfaceDescriptor {
465  public:
466   DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
467 };
468
469
470 class ApiAccessorDescriptor : public CallInterfaceDescriptor {
471  public:
472   DECLARE_DESCRIPTOR(ApiAccessorDescriptor, CallInterfaceDescriptor)
473 };
474
475
476 class ApiGetterDescriptor : public CallInterfaceDescriptor {
477  public:
478   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
479
480   static const Register function_address();
481 };
482
483
484 class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
485  public:
486   DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor)
487
488   static const Register index();
489   static const Register parameter_count();
490 };
491
492
493 class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
494  public:
495   DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
496                      CallInterfaceDescriptor)
497 };
498
499
500 class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
501  public:
502   DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
503
504   static const Register exponent();
505 };
506
507
508 class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
509  public:
510   DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
511
512   static const Register exponent();
513 };
514
515
516 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
517  public:
518   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
519 };
520
521 #undef DECLARE_DESCRIPTOR
522
523
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)
529 #undef DEF_KEY
530 }
531 }  // namespace v8::internal
532
533
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"
538 #endif
539
540 #endif  // V8_CALL_INTERFACE_DESCRIPTOR_H_