• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(ElementTransitionAndStore)                \
20   V(Instanceof)                               \
21   V(VectorLoadICTrampoline)                   \
22   V(VectorLoadIC)                             \
23   V(FastNewClosure)                           \
24   V(FastNewContext)                           \
25   V(ToNumber)                                 \
26   V(NumberToString)                           \
27   V(FastCloneShallowArray)                    \
28   V(FastCloneShallowObject)                   \
29   V(CreateAllocationSite)                     \
30   V(CallFunction)                             \
31   V(CallFunctionWithFeedback)                 \
32   V(CallConstruct)                            \
33   V(RegExpConstructResult)                    \
34   V(TransitionElementsKind)                   \
35   V(ArrayConstructorConstantArgCount)         \
36   V(ArrayConstructor)                         \
37   V(InternalArrayConstructorConstantArgCount) \
38   V(InternalArrayConstructor)                 \
39   V(CompareNil)                               \
40   V(ToBoolean)                                \
41   V(BinaryOp)                                 \
42   V(BinaryOpWithAllocationSite)               \
43   V(StringAdd)                                \
44   V(Keyed)                                    \
45   V(Named)                                    \
46   V(CallHandler)                              \
47   V(ArgumentAdaptor)                          \
48   V(ApiGetter)                                \
49   V(ApiFunction)                              \
50   V(ArgumentsAccessRead)                      \
51   V(StoreArrayLiteralElement)                 \
52   V(MathPowTagged)                            \
53   V(MathPowInteger)                           \
54   V(ContextOnly)
55 
56 
57 class CallInterfaceDescriptorData {
58  public:
CallInterfaceDescriptorData()59   CallInterfaceDescriptorData() : register_param_count_(-1) {}
60 
61   // A copy of the passed in registers and param_representations is made
62   // and owned by the CallInterfaceDescriptorData.
63 
64   // TODO(mvstanton): Instead of taking parallel arrays register and
65   // param_representations, how about a struct that puts the representation
66   // and register side by side (eg, RegRep(r1, Representation::Tagged()).
67   // The same should go for the CodeStubDescriptor class.
68   void Initialize(int register_parameter_count, Register* registers,
69                   Representation* param_representations,
70                   PlatformInterfaceDescriptor* platform_descriptor = NULL);
71 
IsInitialized()72   bool IsInitialized() const { return register_param_count_ >= 0; }
73 
register_param_count()74   int register_param_count() const { return register_param_count_; }
register_param(int index)75   Register register_param(int index) const { return register_params_[index]; }
register_params()76   Register* register_params() const { return register_params_.get(); }
register_param_representation(int index)77   Representation register_param_representation(int index) const {
78     return register_param_representations_[index];
79   }
register_param_representations()80   Representation* register_param_representations() const {
81     return register_param_representations_.get();
82   }
platform_specific_descriptor()83   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
84     return platform_specific_descriptor_;
85   }
86 
87  private:
88   int register_param_count_;
89 
90   // The Register params are allocated dynamically by the
91   // InterfaceDescriptor, and freed on destruction. This is because static
92   // arrays of Registers cause creation of runtime static initializers
93   // which we don't want.
94   SmartArrayPointer<Register> register_params_;
95   // Specifies Representations for the stub's parameter. Points to an array of
96   // Representations of the same length of the numbers of parameters to the
97   // stub, or if NULL (the default value), Representation of each parameter
98   // assumed to be Tagged().
99   SmartArrayPointer<Representation> register_param_representations_;
100 
101   PlatformInterfaceDescriptor* platform_specific_descriptor_;
102 
103   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
104 };
105 
106 
107 class CallDescriptors {
108  public:
109   enum Key {
110 #define DEF_ENUM(name) name,
111     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
112 #undef DEF_ENUM
113     NUMBER_OF_DESCRIPTORS
114   };
115 };
116 
117 
118 class CallInterfaceDescriptor {
119  public:
CallInterfaceDescriptor()120   CallInterfaceDescriptor() : data_(NULL) {}
121 
CallInterfaceDescriptor(Isolate * isolate,CallDescriptors::Key key)122   CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
123       : data_(isolate->call_descriptor_data(key)) {}
124 
GetEnvironmentLength()125   int GetEnvironmentLength() const { return data()->register_param_count(); }
126 
GetRegisterParameterCount()127   int GetRegisterParameterCount() const {
128     return data()->register_param_count();
129   }
130 
GetParameterRegister(int index)131   Register GetParameterRegister(int index) const {
132     return data()->register_param(index);
133   }
134 
GetParameterRepresentation(int index)135   Representation GetParameterRepresentation(int index) const {
136     DCHECK(index < data()->register_param_count());
137     if (data()->register_param_representations() == NULL) {
138       return Representation::Tagged();
139     }
140 
141     return data()->register_param_representation(index);
142   }
143 
144   // "Environment" versions of parameter functions. The first register
145   // parameter (context) is not included.
GetEnvironmentParameterCount()146   int GetEnvironmentParameterCount() const {
147     return GetEnvironmentLength() - 1;
148   }
149 
GetEnvironmentParameterRegister(int index)150   Register GetEnvironmentParameterRegister(int index) const {
151     return GetParameterRegister(index + 1);
152   }
153 
GetEnvironmentParameterRepresentation(int index)154   Representation GetEnvironmentParameterRepresentation(int index) const {
155     return GetParameterRepresentation(index + 1);
156   }
157 
158   // Some platforms have extra information to associate with the descriptor.
platform_specific_descriptor()159   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
160     return data()->platform_specific_descriptor();
161   }
162 
163   static const Register ContextRegister();
164 
165   const char* DebugName(Isolate* isolate);
166 
167  protected:
data()168   const CallInterfaceDescriptorData* data() const { return data_; }
169 
170  private:
171   const CallInterfaceDescriptorData* data_;
172 };
173 
174 
175 #define DECLARE_DESCRIPTOR(name, base)                                     \
176   explicit name(Isolate* isolate) : base(isolate, key()) {                 \
177     if (!data()->IsInitialized())                                          \
178       Initialize(isolate->call_descriptor_data(key()));                    \
179   }                                                                        \
180                                                                            \
181  protected:                                                                \
182   void Initialize(CallInterfaceDescriptorData* data);                      \
183   name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
184                                                                            \
185  public:                                                                   \
186   static inline CallDescriptors::Key key();
187 
188 
189 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
190 class LoadDescriptor : public CallInterfaceDescriptor {
191  public:
192   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
193 
194   enum ParameterIndices { kReceiverIndex, kNameIndex };
195   static const Register ReceiverRegister();
196   static const Register NameRegister();
197 };
198 
199 
200 class StoreDescriptor : public CallInterfaceDescriptor {
201  public:
202   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
203 
204   enum ParameterIndices {
205     kReceiverIndex,
206     kNameIndex,
207     kValueIndex,
208     kParameterCount
209   };
210   static const Register ReceiverRegister();
211   static const Register NameRegister();
212   static const Register ValueRegister();
213 };
214 
215 
216 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
217  public:
218   DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
219 
220   static const Register MapRegister();
221 };
222 
223 
224 class InstanceofDescriptor : public CallInterfaceDescriptor {
225  public:
226   DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor)
227 
228   enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
229   static const Register left();
230   static const Register right();
231 };
232 
233 
234 class VectorLoadICTrampolineDescriptor : public LoadDescriptor {
235  public:
236   DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor)
237 
238   enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex };
239 
240   static const Register SlotRegister();
241 };
242 
243 
244 class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor {
245  public:
246   DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor)
247 
248   enum ParameterIndices {
249     kReceiverIndex,
250     kNameIndex,
251     kSlotIndex,
252     kVectorIndex
253   };
254 
255   static const Register VectorRegister();
256 };
257 
258 
259 class FastNewClosureDescriptor : public CallInterfaceDescriptor {
260  public:
261   DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
262 };
263 
264 
265 class FastNewContextDescriptor : public CallInterfaceDescriptor {
266  public:
267   DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
268 };
269 
270 
271 class ToNumberDescriptor : public CallInterfaceDescriptor {
272  public:
273   DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
274 };
275 
276 
277 class NumberToStringDescriptor : public CallInterfaceDescriptor {
278  public:
279   DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
280 };
281 
282 
283 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
284  public:
285   DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
286 };
287 
288 
289 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
290  public:
291   DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
292 };
293 
294 
295 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
296  public:
297   DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
298 };
299 
300 
301 class CallFunctionDescriptor : public CallInterfaceDescriptor {
302  public:
303   DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
304 };
305 
306 
307 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
308  public:
309   DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
310                      CallInterfaceDescriptor)
311 };
312 
313 
314 class CallConstructDescriptor : public CallInterfaceDescriptor {
315  public:
316   DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
317 };
318 
319 
320 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
321  public:
322   DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
323 };
324 
325 
326 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
327  public:
328   DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
329 };
330 
331 
332 class ArrayConstructorConstantArgCountDescriptor
333     : public CallInterfaceDescriptor {
334  public:
335   DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
336                      CallInterfaceDescriptor)
337 };
338 
339 
340 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
341  public:
342   DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
343 };
344 
345 
346 class InternalArrayConstructorConstantArgCountDescriptor
347     : public CallInterfaceDescriptor {
348  public:
349   DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
350                      CallInterfaceDescriptor)
351 };
352 
353 
354 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
355  public:
356   DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
357                      CallInterfaceDescriptor)
358 };
359 
360 
361 class CompareNilDescriptor : public CallInterfaceDescriptor {
362  public:
363   DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
364 };
365 
366 
367 class ToBooleanDescriptor : public CallInterfaceDescriptor {
368  public:
369   DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
370 };
371 
372 
373 class BinaryOpDescriptor : public CallInterfaceDescriptor {
374  public:
375   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
376 };
377 
378 
379 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
380  public:
381   DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
382                      CallInterfaceDescriptor)
383 };
384 
385 
386 class StringAddDescriptor : public CallInterfaceDescriptor {
387  public:
388   DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
389 };
390 
391 
392 class KeyedDescriptor : public CallInterfaceDescriptor {
393  public:
394   DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
395 };
396 
397 
398 class NamedDescriptor : public CallInterfaceDescriptor {
399  public:
400   DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
401 };
402 
403 
404 class CallHandlerDescriptor : public CallInterfaceDescriptor {
405  public:
406   DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
407 };
408 
409 
410 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
411  public:
412   DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
413 };
414 
415 
416 class ApiFunctionDescriptor : public CallInterfaceDescriptor {
417  public:
418   DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
419 };
420 
421 
422 class ApiGetterDescriptor : public CallInterfaceDescriptor {
423  public:
424   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
425 
426   static const Register function_address();
427 };
428 
429 
430 class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
431  public:
432   DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor)
433 
434   static const Register index();
435   static const Register parameter_count();
436 };
437 
438 
439 class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
440  public:
441   DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
442                      CallInterfaceDescriptor)
443 };
444 
445 
446 class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
447  public:
448   DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
449 
450   static const Register exponent();
451 };
452 
453 
454 class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
455  public:
456   DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
457 
458   static const Register exponent();
459 };
460 
461 
462 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
463  public:
464   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
465 };
466 
467 #undef DECLARE_DESCRIPTOR
468 
469 
470 // We define the association between CallDescriptors::Key and the specialized
471 // descriptor here to reduce boilerplate and mistakes.
472 #define DEF_KEY(name) \
473   CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
474 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
475 #undef DEF_KEY
476 }
477 }  // namespace v8::internal
478 
479 
480 #if V8_TARGET_ARCH_ARM64
481 #include "src/arm64/interface-descriptors-arm64.h"
482 #elif V8_TARGET_ARCH_ARM
483 #include "src/arm/interface-descriptors-arm.h"
484 #endif
485 
486 #endif  // V8_CALL_INTERFACE_DESCRIPTOR_H_
487