interface-descriptors.cc revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
1// Copyright 2012 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#include "src/interface-descriptors.h"
6
7namespace v8 {
8namespace internal {
9
10namespace {
11// Constructors for common combined semantic and representation types.
12Type* SmiType(Zone* zone) {
13  return Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), zone);
14}
15
16
17Type* UntaggedIntegral32(Zone* zone) {
18  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone);
19}
20
21
22Type* AnyTagged(Zone* zone) {
23  return Type::Intersect(
24      Type::Any(),
25      Type::Union(Type::TaggedPointer(), Type::TaggedSigned(), zone), zone);
26}
27
28
29Type* ExternalPointer(Zone* zone) {
30  return Type::Intersect(Type::Internal(), Type::UntaggedPointer(), zone);
31}
32}  // namespace
33
34
35Type::FunctionType* CallInterfaceDescriptor::BuildDefaultFunctionType(
36    Isolate* isolate, int parameter_count) {
37  Zone* zone = isolate->interface_descriptor_zone();
38  Type::FunctionType* function = Type::FunctionType::New(
39      AnyTagged(zone), Type::Undefined(), parameter_count, zone);
40  while (parameter_count-- != 0) {
41    function->InitParameter(parameter_count, AnyTagged(zone));
42  }
43  return function;
44}
45
46
47void CallInterfaceDescriptorData::InitializePlatformSpecific(
48    int register_parameter_count, Register* registers,
49    PlatformInterfaceDescriptor* platform_descriptor) {
50  platform_specific_descriptor_ = platform_descriptor;
51  register_param_count_ = register_parameter_count;
52
53  // InterfaceDescriptor owns a copy of the registers array.
54  register_params_.Reset(NewArray<Register>(register_parameter_count));
55  for (int i = 0; i < register_parameter_count; i++) {
56    register_params_[i] = registers[i];
57  }
58}
59
60const char* CallInterfaceDescriptor::DebugName(Isolate* isolate) const {
61  CallInterfaceDescriptorData* start = isolate->call_descriptor_data(0);
62  size_t index = data_ - start;
63  DCHECK(index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
64  CallDescriptors::Key key = static_cast<CallDescriptors::Key>(index);
65  switch (key) {
66#define DEF_CASE(NAME)        \
67  case CallDescriptors::NAME: \
68    return #NAME " Descriptor";
69    INTERFACE_DESCRIPTOR_LIST(DEF_CASE)
70#undef DEF_CASE
71    case CallDescriptors::NUMBER_OF_DESCRIPTORS:
72      break;
73  }
74  return "";
75}
76
77
78void AllocateMutableHeapNumberDescriptor::InitializePlatformSpecific(
79    CallInterfaceDescriptorData* data) {
80  data->InitializePlatformSpecific(0, nullptr, nullptr);
81}
82
83
84void VoidDescriptor::InitializePlatformSpecific(
85    CallInterfaceDescriptorData* data) {
86  data->InitializePlatformSpecific(0, nullptr);
87}
88
89
90Type::FunctionType* LoadDescriptor::BuildCallInterfaceDescriptorFunctionType(
91    Isolate* isolate, int paramater_count) {
92  Zone* zone = isolate->interface_descriptor_zone();
93  Type::FunctionType* function =
94      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
95  function->InitParameter(0, AnyTagged(zone));
96  function->InitParameter(1, AnyTagged(zone));
97  function->InitParameter(2, SmiType(zone));
98  return function;
99}
100
101
102void LoadDescriptor::InitializePlatformSpecific(
103    CallInterfaceDescriptorData* data) {
104  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
105  data->InitializePlatformSpecific(arraysize(registers), registers);
106}
107
108
109void StoreDescriptor::InitializePlatformSpecific(
110    CallInterfaceDescriptorData* data) {
111  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister()};
112  data->InitializePlatformSpecific(arraysize(registers), registers);
113}
114
115
116void StoreTransitionDescriptor::InitializePlatformSpecific(
117    CallInterfaceDescriptorData* data) {
118  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
119                          MapRegister()};
120
121  data->InitializePlatformSpecific(arraysize(registers), registers);
122}
123
124
125void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
126    CallInterfaceDescriptorData* data) {
127  if (SlotRegister().is(no_reg)) {
128    Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
129                            MapRegister(), VectorRegister()};
130    data->InitializePlatformSpecific(arraysize(registers), registers);
131  } else {
132    Register registers[] = {ReceiverRegister(), NameRegister(),
133                            ValueRegister(),    MapRegister(),
134                            SlotRegister(),     VectorRegister()};
135    data->InitializePlatformSpecific(arraysize(registers), registers);
136  }
137}
138
139
140Type::FunctionType*
141StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
142    Isolate* isolate, int paramater_count) {
143  Zone* zone = isolate->interface_descriptor_zone();
144  Type::FunctionType* function =
145      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
146  function->InitParameter(0, AnyTagged(zone));  // Receiver
147  function->InitParameter(1, AnyTagged(zone));  // Name
148  function->InitParameter(2, AnyTagged(zone));  // Value
149  function->InitParameter(3, AnyTagged(zone));  // Map
150  return function;
151}
152
153
154Type::FunctionType*
155LoadGlobalViaContextDescriptor::BuildCallInterfaceDescriptorFunctionType(
156    Isolate* isolate, int paramater_count) {
157  Zone* zone = isolate->interface_descriptor_zone();
158  Type::FunctionType* function =
159      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 1, zone);
160  function->InitParameter(0, UntaggedIntegral32(zone));
161  return function;
162}
163
164
165void LoadGlobalViaContextDescriptor::InitializePlatformSpecific(
166    CallInterfaceDescriptorData* data) {
167  Register registers[] = {SlotRegister()};
168  data->InitializePlatformSpecific(arraysize(registers), registers);
169}
170
171
172Type::FunctionType*
173StoreGlobalViaContextDescriptor::BuildCallInterfaceDescriptorFunctionType(
174    Isolate* isolate, int paramater_count) {
175  Zone* zone = isolate->interface_descriptor_zone();
176  Type::FunctionType* function =
177      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
178  function->InitParameter(0, UntaggedIntegral32(zone));
179  function->InitParameter(1, AnyTagged(zone));
180  return function;
181}
182
183
184void StoreGlobalViaContextDescriptor::InitializePlatformSpecific(
185    CallInterfaceDescriptorData* data) {
186  Register registers[] = {SlotRegister(), ValueRegister()};
187  data->InitializePlatformSpecific(arraysize(registers), registers);
188}
189
190
191void InstanceOfDescriptor::InitializePlatformSpecific(
192    CallInterfaceDescriptorData* data) {
193  Register registers[] = {LeftRegister(), RightRegister()};
194  data->InitializePlatformSpecific(arraysize(registers), registers);
195}
196
197
198void StringCompareDescriptor::InitializePlatformSpecific(
199    CallInterfaceDescriptorData* data) {
200  Register registers[] = {LeftRegister(), RightRegister()};
201  data->InitializePlatformSpecific(arraysize(registers), registers);
202}
203
204
205void ToLengthDescriptor::InitializePlatformSpecific(
206    CallInterfaceDescriptorData* data) {
207  Register registers[] = {ReceiverRegister()};
208  data->InitializePlatformSpecific(arraysize(registers), registers);
209}
210
211
212void ToStringDescriptor::InitializePlatformSpecific(
213    CallInterfaceDescriptorData* data) {
214  Register registers[] = {ReceiverRegister()};
215  data->InitializePlatformSpecific(arraysize(registers), registers);
216}
217
218
219void ToObjectDescriptor::InitializePlatformSpecific(
220    CallInterfaceDescriptorData* data) {
221  Register registers[] = {ReceiverRegister()};
222  data->InitializePlatformSpecific(arraysize(registers), registers);
223}
224
225
226void MathPowTaggedDescriptor::InitializePlatformSpecific(
227    CallInterfaceDescriptorData* data) {
228  Register registers[] = {exponent()};
229  data->InitializePlatformSpecific(arraysize(registers), registers);
230}
231
232
233void MathPowIntegerDescriptor::InitializePlatformSpecific(
234    CallInterfaceDescriptorData* data) {
235  Register registers[] = {exponent()};
236  data->InitializePlatformSpecific(arraysize(registers), registers);
237}
238
239
240Type::FunctionType*
241LoadWithVectorDescriptor::BuildCallInterfaceDescriptorFunctionType(
242    Isolate* isolate, int paramater_count) {
243  Zone* zone = isolate->interface_descriptor_zone();
244  Type::FunctionType* function =
245      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
246  function->InitParameter(0, AnyTagged(zone));
247  function->InitParameter(1, AnyTagged(zone));
248  function->InitParameter(2, SmiType(zone));
249  function->InitParameter(3, AnyTagged(zone));
250  return function;
251}
252
253
254void LoadWithVectorDescriptor::InitializePlatformSpecific(
255    CallInterfaceDescriptorData* data) {
256  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
257                          VectorRegister()};
258  data->InitializePlatformSpecific(arraysize(registers), registers);
259}
260
261
262Type::FunctionType*
263VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
264    Isolate* isolate, int paramater_count) {
265  Zone* zone = isolate->interface_descriptor_zone();
266  bool has_slot = !VectorStoreTransitionDescriptor::SlotRegister().is(no_reg);
267  int arg_count = has_slot ? 6 : 5;
268  Type::FunctionType* function = Type::FunctionType::New(
269      AnyTagged(zone), Type::Undefined(), arg_count, zone);
270  int index = 0;
271  function->InitParameter(index++, AnyTagged(zone));  // receiver
272  function->InitParameter(index++, AnyTagged(zone));  // name
273  function->InitParameter(index++, AnyTagged(zone));  // value
274  function->InitParameter(index++, AnyTagged(zone));  // map
275  if (has_slot) {
276    function->InitParameter(index++, SmiType(zone));  // slot
277  }
278  function->InitParameter(index++, AnyTagged(zone));  // vector
279  return function;
280}
281
282
283Type::FunctionType*
284VectorStoreICDescriptor::BuildCallInterfaceDescriptorFunctionType(
285    Isolate* isolate, int paramater_count) {
286  Zone* zone = isolate->interface_descriptor_zone();
287  Type::FunctionType* function =
288      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 5, zone);
289  function->InitParameter(0, AnyTagged(zone));
290  function->InitParameter(1, AnyTagged(zone));
291  function->InitParameter(2, AnyTagged(zone));
292  function->InitParameter(3, SmiType(zone));
293  function->InitParameter(4, AnyTagged(zone));
294  return function;
295}
296
297
298void VectorStoreICDescriptor::InitializePlatformSpecific(
299    CallInterfaceDescriptorData* data) {
300  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
301                          SlotRegister(), VectorRegister()};
302  data->InitializePlatformSpecific(arraysize(registers), registers);
303}
304
305
306Type::FunctionType*
307VectorStoreICTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
308    Isolate* isolate, int paramater_count) {
309  Zone* zone = isolate->interface_descriptor_zone();
310  Type::FunctionType* function =
311      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
312  function->InitParameter(0, AnyTagged(zone));
313  function->InitParameter(1, AnyTagged(zone));
314  function->InitParameter(2, AnyTagged(zone));
315  function->InitParameter(3, SmiType(zone));
316  return function;
317}
318
319
320void VectorStoreICTrampolineDescriptor::InitializePlatformSpecific(
321    CallInterfaceDescriptorData* data) {
322  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
323                          SlotRegister()};
324  data->InitializePlatformSpecific(arraysize(registers), registers);
325}
326
327
328Type::FunctionType*
329ApiGetterDescriptor::BuildCallInterfaceDescriptorFunctionType(
330    Isolate* isolate, int paramater_count) {
331  Zone* zone = isolate->interface_descriptor_zone();
332  Type::FunctionType* function =
333      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 1, zone);
334  function->InitParameter(0, ExternalPointer(zone));
335  return function;
336}
337
338
339void ApiGetterDescriptor::InitializePlatformSpecific(
340    CallInterfaceDescriptorData* data) {
341  Register registers[] = {function_address()};
342  data->InitializePlatformSpecific(arraysize(registers), registers);
343}
344
345
346void ArgumentsAccessReadDescriptor::InitializePlatformSpecific(
347    CallInterfaceDescriptorData* data) {
348  Register registers[] = {index(), parameter_count()};
349  data->InitializePlatformSpecific(arraysize(registers), registers);
350}
351
352
353Type::FunctionType*
354ArgumentsAccessNewDescriptor::BuildCallInterfaceDescriptorFunctionType(
355    Isolate* isolate, int paramater_count) {
356  Zone* zone = isolate->interface_descriptor_zone();
357  Type::FunctionType* function =
358      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
359  function->InitParameter(0, AnyTagged(zone));
360  function->InitParameter(1, SmiType(zone));
361  function->InitParameter(2, ExternalPointer(zone));
362  return function;
363}
364
365
366void ArgumentsAccessNewDescriptor::InitializePlatformSpecific(
367    CallInterfaceDescriptorData* data) {
368  Register registers[] = {function(), parameter_count(), parameter_pointer()};
369  data->InitializePlatformSpecific(arraysize(registers), registers);
370}
371
372
373Type::FunctionType*
374RestParamAccessDescriptor::BuildCallInterfaceDescriptorFunctionType(
375    Isolate* isolate, int paramater_count) {
376  Zone* zone = isolate->interface_descriptor_zone();
377  Type::FunctionType* function =
378      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
379  function->InitParameter(0, SmiType(zone));
380  function->InitParameter(1, ExternalPointer(zone));
381  function->InitParameter(2, SmiType(zone));
382  return function;
383}
384
385
386void RestParamAccessDescriptor::InitializePlatformSpecific(
387    CallInterfaceDescriptorData* data) {
388  Register registers[] = {parameter_count(), parameter_pointer(),
389                          rest_parameter_index()};
390  data->InitializePlatformSpecific(arraysize(registers), registers);
391}
392
393
394void ContextOnlyDescriptor::InitializePlatformSpecific(
395    CallInterfaceDescriptorData* data) {
396  data->InitializePlatformSpecific(0, nullptr);
397}
398
399
400void GrowArrayElementsDescriptor::InitializePlatformSpecific(
401    CallInterfaceDescriptorData* data) {
402  Register registers[] = {ObjectRegister(), KeyRegister()};
403  data->InitializePlatformSpecific(arraysize(registers), registers);
404}
405
406
407Type::FunctionType*
408FastCloneRegExpDescriptor::BuildCallInterfaceDescriptorFunctionType(
409    Isolate* isolate, int paramater_count) {
410  Zone* zone = isolate->interface_descriptor_zone();
411  Type::FunctionType* function =
412      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
413  function->InitParameter(0, AnyTagged(zone));  // closure
414  function->InitParameter(1, SmiType(zone));    // literal_index
415  function->InitParameter(2, AnyTagged(zone));  // pattern
416  function->InitParameter(3, AnyTagged(zone));  // flags
417  return function;
418}
419
420
421Type::FunctionType*
422FastCloneShallowArrayDescriptor::BuildCallInterfaceDescriptorFunctionType(
423    Isolate* isolate, int paramater_count) {
424  Zone* zone = isolate->interface_descriptor_zone();
425  Type::FunctionType* function =
426      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
427  function->InitParameter(0, AnyTagged(zone));
428  function->InitParameter(1, SmiType(zone));
429  function->InitParameter(2, AnyTagged(zone));
430  return function;
431}
432
433
434Type::FunctionType*
435CreateAllocationSiteDescriptor::BuildCallInterfaceDescriptorFunctionType(
436    Isolate* isolate, int paramater_count) {
437  Zone* zone = isolate->interface_descriptor_zone();
438  Type::FunctionType* function =
439      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
440  function->InitParameter(0, AnyTagged(zone));
441  function->InitParameter(1, SmiType(zone));
442  return function;
443}
444
445
446Type::FunctionType*
447CreateWeakCellDescriptor::BuildCallInterfaceDescriptorFunctionType(
448    Isolate* isolate, int paramater_count) {
449  Zone* zone = isolate->interface_descriptor_zone();
450  Type::FunctionType* function =
451      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
452  function->InitParameter(0, AnyTagged(zone));
453  function->InitParameter(1, SmiType(zone));
454  function->InitParameter(2, AnyTagged(zone));
455  return function;
456}
457
458
459Type::FunctionType*
460CallTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
461    Isolate* isolate, int paramater_count) {
462  Zone* zone = isolate->interface_descriptor_zone();
463  Type::FunctionType* function =
464      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
465  function->InitParameter(0, AnyTagged(zone));           // target
466  function->InitParameter(1, UntaggedIntegral32(zone));  // actual #arguments
467  return function;
468}
469
470
471Type::FunctionType*
472ConstructStubDescriptor::BuildCallInterfaceDescriptorFunctionType(
473    Isolate* isolate, int paramater_count) {
474  Zone* zone = isolate->interface_descriptor_zone();
475  Type::FunctionType* function =
476      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
477  function->InitParameter(0, AnyTagged(zone));           // target
478  function->InitParameter(1, AnyTagged(zone));           // new.target
479  function->InitParameter(2, UntaggedIntegral32(zone));  // actual #arguments
480  function->InitParameter(3, AnyTagged(zone));           // opt. allocation site
481  return function;
482}
483
484
485Type::FunctionType*
486ConstructTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
487    Isolate* isolate, int paramater_count) {
488  Zone* zone = isolate->interface_descriptor_zone();
489  Type::FunctionType* function =
490      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
491  function->InitParameter(0, AnyTagged(zone));           // target
492  function->InitParameter(1, AnyTagged(zone));           // new.target
493  function->InitParameter(2, UntaggedIntegral32(zone));  // actual #arguments
494  return function;
495}
496
497
498Type::FunctionType*
499CallFunctionWithFeedbackDescriptor::BuildCallInterfaceDescriptorFunctionType(
500    Isolate* isolate, int paramater_count) {
501  Zone* zone = isolate->interface_descriptor_zone();
502  Type::FunctionType* function =
503      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
504  function->InitParameter(0, Type::Receiver());  // JSFunction
505  function->InitParameter(1, SmiType(zone));
506  return function;
507}
508
509
510Type::FunctionType* CallFunctionWithFeedbackAndVectorDescriptor::
511    BuildCallInterfaceDescriptorFunctionType(Isolate* isolate,
512                                             int paramater_count) {
513  Zone* zone = isolate->interface_descriptor_zone();
514  Type::FunctionType* function =
515      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
516  function->InitParameter(0, Type::Receiver());  // JSFunction
517  function->InitParameter(1, SmiType(zone));
518  function->InitParameter(2, AnyTagged(zone));
519  return function;
520}
521
522
523Type::FunctionType*
524ArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
525    Isolate* isolate, int paramater_count) {
526  Zone* zone = isolate->interface_descriptor_zone();
527  Type::FunctionType* function =
528      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
529  function->InitParameter(0, Type::Receiver());  // JSFunction
530  function->InitParameter(1, AnyTagged(zone));
531  function->InitParameter(2, UntaggedIntegral32(zone));
532  return function;
533}
534
535
536Type::FunctionType*
537InternalArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
538    Isolate* isolate, int paramater_count) {
539  Zone* zone = isolate->interface_descriptor_zone();
540  Type::FunctionType* function =
541      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
542  function->InitParameter(0, Type::Receiver());  // JSFunction
543  function->InitParameter(1, UntaggedIntegral32(zone));
544  return function;
545}
546
547
548Type::FunctionType*
549ArgumentAdaptorDescriptor::BuildCallInterfaceDescriptorFunctionType(
550    Isolate* isolate, int paramater_count) {
551  Zone* zone = isolate->interface_descriptor_zone();
552  Type::FunctionType* function =
553      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
554  function->InitParameter(0, Type::Receiver());          // JSFunction
555  function->InitParameter(1, AnyTagged(zone));           // the new target
556  function->InitParameter(2, UntaggedIntegral32(zone));  // actual #arguments
557  function->InitParameter(3, UntaggedIntegral32(zone));  // expected #arguments
558  return function;
559}
560
561
562Type::FunctionType*
563ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
564    Isolate* isolate, int paramater_count) {
565  Zone* zone = isolate->interface_descriptor_zone();
566  Type::FunctionType* function =
567      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 5, zone);
568  function->InitParameter(0, AnyTagged(zone));           // callee
569  function->InitParameter(1, AnyTagged(zone));           // call_data
570  function->InitParameter(2, AnyTagged(zone));           // holder
571  function->InitParameter(3, ExternalPointer(zone));     // api_function_address
572  function->InitParameter(4, UntaggedIntegral32(zone));  // actual #arguments
573  return function;
574}
575
576
577Type::FunctionType*
578ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
579    Isolate* isolate, int paramater_count) {
580  Zone* zone = isolate->interface_descriptor_zone();
581  Type::FunctionType* function =
582      Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
583  function->InitParameter(0, AnyTagged(zone));        // callee
584  function->InitParameter(1, AnyTagged(zone));        // call_data
585  function->InitParameter(2, AnyTagged(zone));        // holder
586  function->InitParameter(3, ExternalPointer(zone));  // api_function_address
587  return function;
588}
589
590
591}  // namespace internal
592}  // namespace v8
593