blob: b773c916ecbff19be72d97f42d792848d36bc653 [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) \
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
57class CallInterfaceDescriptorData {
58 public:
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
72 bool IsInitialized() const { return register_param_count_ >= 0; }
73
74 int register_param_count() const { return register_param_count_; }
75 Register register_param(int index) const { return register_params_[index]; }
76 Register* register_params() const { return register_params_.get(); }
77 Representation register_param_representation(int index) const {
78 return register_param_representations_[index];
79 }
80 Representation* register_param_representations() const {
81 return register_param_representations_.get();
82 }
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
107class 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
118class CallInterfaceDescriptor {
119 public:
120 CallInterfaceDescriptor() : data_(NULL) {}
121
122 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
123 : data_(isolate->call_descriptor_data(key)) {}
124
125 int GetEnvironmentLength() const { return data()->register_param_count(); }
126
127 int GetRegisterParameterCount() const {
128 return data()->register_param_count();
129 }
130
131 Register GetParameterRegister(int index) const {
132 return data()->register_param(index);
133 }
134
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.
146 int GetEnvironmentParameterCount() const {
147 return GetEnvironmentLength() - 1;
148 }
149
150 Register GetEnvironmentParameterRegister(int index) const {
151 return GetParameterRegister(index + 1);
152 }
153
154 Representation GetEnvironmentParameterRepresentation(int index) const {
155 return GetParameterRepresentation(index + 1);
156 }
157
158 // Some platforms have extra information to associate with the 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:
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.
190class 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
200class 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
216class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
217 public:
218 DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
219
220 static const Register MapRegister();
221};
222
223
224class 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
234class 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
244class 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
259class FastNewClosureDescriptor : public CallInterfaceDescriptor {
260 public:
261 DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
262};
263
264
265class FastNewContextDescriptor : public CallInterfaceDescriptor {
266 public:
267 DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
268};
269
270
271class ToNumberDescriptor : public CallInterfaceDescriptor {
272 public:
273 DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
274};
275
276
277class NumberToStringDescriptor : public CallInterfaceDescriptor {
278 public:
279 DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
280};
281
282
283class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
284 public:
285 DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
286};
287
288
289class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
290 public:
291 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
292};
293
294
295class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
296 public:
297 DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
298};
299
300
301class CallFunctionDescriptor : public CallInterfaceDescriptor {
302 public:
303 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
304};
305
306
307class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
308 public:
309 DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
310 CallInterfaceDescriptor)
311};
312
313
314class CallConstructDescriptor : public CallInterfaceDescriptor {
315 public:
316 DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
317};
318
319
320class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
321 public:
322 DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
323};
324
325
326class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
327 public:
328 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
329};
330
331
332class ArrayConstructorConstantArgCountDescriptor
333 : public CallInterfaceDescriptor {
334 public:
335 DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
336 CallInterfaceDescriptor)
337};
338
339
340class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
341 public:
342 DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
343};
344
345
346class InternalArrayConstructorConstantArgCountDescriptor
347 : public CallInterfaceDescriptor {
348 public:
349 DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
350 CallInterfaceDescriptor)
351};
352
353
354class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
355 public:
356 DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
357 CallInterfaceDescriptor)
358};
359
360
361class CompareNilDescriptor : public CallInterfaceDescriptor {
362 public:
363 DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
364};
365
366
367class ToBooleanDescriptor : public CallInterfaceDescriptor {
368 public:
369 DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
370};
371
372
373class BinaryOpDescriptor : public CallInterfaceDescriptor {
374 public:
375 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
376};
377
378
379class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
380 public:
381 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
382 CallInterfaceDescriptor)
383};
384
385
386class StringAddDescriptor : public CallInterfaceDescriptor {
387 public:
388 DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
389};
390
391
392class KeyedDescriptor : public CallInterfaceDescriptor {
393 public:
394 DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
395};
396
397
398class NamedDescriptor : public CallInterfaceDescriptor {
399 public:
400 DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
401};
402
403
404class CallHandlerDescriptor : public CallInterfaceDescriptor {
405 public:
406 DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
407};
408
409
410class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
411 public:
412 DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
413};
414
415
416class ApiFunctionDescriptor : public CallInterfaceDescriptor {
417 public:
418 DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
419};
420
421
422class ApiGetterDescriptor : public CallInterfaceDescriptor {
423 public:
424 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
425
426 static const Register function_address();
427};
428
429
430class 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
439class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
440 public:
441 DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
442 CallInterfaceDescriptor)
443};
444
445
446class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
447 public:
448 DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
449
450 static const Register exponent();
451};
452
453
454class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
455 public:
456 DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
457
458 static const Register exponent();
459};
460
461
462class 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; }
474INTERFACE_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_