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