V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
interface-descriptors.cc
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 
7 #include "src/macro-assembler.h"
8 
9 namespace v8 {
10 namespace internal {
11 
12 void CallInterfaceDescriptorData::InitializePlatformSpecific(
13  int register_parameter_count, const Register* registers) {
14  DCHECK(!IsInitializedPlatformIndependent());
15 
16  register_param_count_ = register_parameter_count;
17 
18  // InterfaceDescriptor owns a copy of the registers array.
19  register_params_ = NewArray<Register>(register_parameter_count, no_reg);
20  for (int i = 0; i < register_parameter_count; i++) {
21  // The value of the root register must be reserved, thus any uses
22  // within the calling convention are disallowed.
23  DCHECK_NE(registers[i], kRootRegister);
24  register_params_[i] = registers[i];
25  }
26 }
27 
28 void CallInterfaceDescriptorData::InitializePlatformIndependent(
29  Flags flags, int return_count, int parameter_count,
30  const MachineType* machine_types, int machine_types_length) {
31  DCHECK(IsInitializedPlatformSpecific());
32 
33  flags_ = flags;
34  return_count_ = return_count;
35  param_count_ = parameter_count;
36  const int types_length = return_count_ + param_count_;
37 
38  // Machine types are either fully initialized or null.
39  if (machine_types == nullptr) {
40  machine_types_ =
41  NewArray<MachineType>(types_length, MachineType::AnyTagged());
42  } else {
43  DCHECK_EQ(machine_types_length, types_length);
44  machine_types_ = NewArray<MachineType>(types_length);
45  for (int i = 0; i < types_length; i++) machine_types_[i] = machine_types[i];
46  }
47 
48  DCHECK(AllStackParametersAreTagged());
49 }
50 
51 #ifdef DEBUG
52 bool CallInterfaceDescriptorData::AllStackParametersAreTagged() const {
53  DCHECK(IsInitialized());
54  const int types_length = return_count_ + param_count_;
55  const int first_stack_param = return_count_ + register_param_count_;
56  for (int i = first_stack_param; i < types_length; i++) {
57  if (!machine_types_[i].IsTagged()) return false;
58  }
59  return true;
60 }
61 #endif // DEBUG
62 
63 void CallInterfaceDescriptorData::Reset() {
64  delete[] machine_types_;
65  machine_types_ = nullptr;
66  delete[] register_params_;
67  register_params_ = nullptr;
68 }
69 
70 // static
71 CallInterfaceDescriptorData
72  CallDescriptors::call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
73 
74 void CallDescriptors::InitializeOncePerProcess() {
75 #define INTERFACE_DESCRIPTOR(name, ...) \
76  name##Descriptor().Initialize(&call_descriptor_data_[CallDescriptors::name]);
77  INTERFACE_DESCRIPTOR_LIST(INTERFACE_DESCRIPTOR)
78 #undef INTERFACE_DESCRIPTOR
79 
80  DCHECK(ContextOnlyDescriptor{}.HasContextParameter());
81  DCHECK(!NoContextDescriptor{}.HasContextParameter());
82  DCHECK(!AllocateDescriptor{}.HasContextParameter());
83  DCHECK(!AllocateHeapNumberDescriptor{}.HasContextParameter());
84  DCHECK(!AbortDescriptor{}.HasContextParameter());
85 }
86 
87 void CallDescriptors::TearDown() {
88  for (CallInterfaceDescriptorData& data : call_descriptor_data_) {
89  data.Reset();
90  }
91 }
92 
93 void CallInterfaceDescriptor::JSDefaultInitializePlatformSpecific(
94  CallInterfaceDescriptorData* data, int non_js_register_parameter_count) {
95  DCHECK_LE(static_cast<unsigned>(non_js_register_parameter_count), 1);
96 
97  // 3 is for kTarget, kNewTarget and kActualArgumentsCount
98  int register_parameter_count = 3 + non_js_register_parameter_count;
99 
100  DCHECK(!AreAliased(
101  kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
102  kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register));
103 
104  const Register default_js_stub_registers[] = {
105  kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
106  kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register};
107 
108  CHECK_LE(static_cast<size_t>(register_parameter_count),
109  arraysize(default_js_stub_registers));
110  data->InitializePlatformSpecific(register_parameter_count,
111  default_js_stub_registers);
112 }
113 
114 const char* CallInterfaceDescriptor::DebugName() const {
115  CallDescriptors::Key key = CallDescriptors::GetKey(data_);
116  switch (key) {
117 #define DEF_CASE(name, ...) \
118  case CallDescriptors::name: \
119  return #name " Descriptor";
120  INTERFACE_DESCRIPTOR_LIST(DEF_CASE)
121 #undef DEF_CASE
122  case CallDescriptors::NUMBER_OF_DESCRIPTORS:
123  break;
124  }
125  return "";
126 }
127 
128 
129 void VoidDescriptor::InitializePlatformSpecific(
130  CallInterfaceDescriptorData* data) {
131  data->InitializePlatformSpecific(0, nullptr);
132 }
133 
134 void AllocateDescriptor::InitializePlatformSpecific(
135  CallInterfaceDescriptorData* data) {
136  Register registers[] = {kAllocateSizeRegister};
137  data->InitializePlatformSpecific(arraysize(registers), registers);
138 }
139 
140 void CEntry1ArgvOnStackDescriptor::InitializePlatformSpecific(
141  CallInterfaceDescriptorData* data) {
142  Register registers[] = {kRuntimeCallArgCountRegister,
143  kRuntimeCallFunctionRegister};
144  data->InitializePlatformSpecific(arraysize(registers), registers);
145 }
146 
147 namespace {
148 
149 void InterpreterCEntryDescriptor_InitializePlatformSpecific(
150  CallInterfaceDescriptorData* data) {
151  Register registers[] = {kRuntimeCallArgCountRegister,
152  kRuntimeCallArgvRegister,
153  kRuntimeCallFunctionRegister};
154  data->InitializePlatformSpecific(arraysize(registers), registers);
155 }
156 
157 } // namespace
158 
159 void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
160  CallInterfaceDescriptorData* data) {
161  InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
162 }
163 
164 void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
165  CallInterfaceDescriptorData* data) {
166  InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
167 }
168 
169 void FastNewFunctionContextDescriptor::InitializePlatformSpecific(
170  CallInterfaceDescriptorData* data) {
171  Register registers[] = {ScopeInfoRegister(), SlotsRegister()};
172  data->InitializePlatformSpecific(arraysize(registers), registers);
173 }
174 
175 void FastNewObjectDescriptor::InitializePlatformSpecific(
176  CallInterfaceDescriptorData* data) {
177  Register registers[] = {TargetRegister(), NewTargetRegister()};
178  data->InitializePlatformSpecific(arraysize(registers), registers);
179 }
180 
181 const Register FastNewObjectDescriptor::TargetRegister() {
182  return kJSFunctionRegister;
183 }
184 
185 const Register FastNewObjectDescriptor::NewTargetRegister() {
186  return kJavaScriptCallNewTargetRegister;
187 }
188 
189 
190 void LoadDescriptor::InitializePlatformSpecific(
191  CallInterfaceDescriptorData* data) {
192  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
193  data->InitializePlatformSpecific(arraysize(registers), registers);
194 }
195 
196 void LoadGlobalDescriptor::InitializePlatformSpecific(
197  CallInterfaceDescriptorData* data) {
198  Register registers[] = {NameRegister(), SlotRegister()};
199  data->InitializePlatformSpecific(arraysize(registers), registers);
200 }
201 
202 void LoadGlobalWithVectorDescriptor::InitializePlatformSpecific(
203  CallInterfaceDescriptorData* data) {
204  Register registers[] = {NameRegister(), SlotRegister(), VectorRegister()};
205  data->InitializePlatformSpecific(arraysize(registers), registers);
206 }
207 
208 void StoreGlobalDescriptor::InitializePlatformSpecific(
209  CallInterfaceDescriptorData* data) {
210  Register registers[] = {NameRegister(), ValueRegister(), SlotRegister()};
211 
212  int len = arraysize(registers) - kStackArgumentsCount;
213  data->InitializePlatformSpecific(len, registers);
214 }
215 
216 void StoreGlobalWithVectorDescriptor::InitializePlatformSpecific(
217  CallInterfaceDescriptorData* data) {
218  Register registers[] = {NameRegister(), ValueRegister(), SlotRegister(),
219  VectorRegister()};
220  int len = arraysize(registers) - kStackArgumentsCount;
221  data->InitializePlatformSpecific(len, registers);
222 }
223 
224 void StoreDescriptor::InitializePlatformSpecific(
225  CallInterfaceDescriptorData* data) {
226  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
227  SlotRegister()};
228 
229  int len = arraysize(registers) - kStackArgumentsCount;
230  data->InitializePlatformSpecific(len, registers);
231 }
232 
233 void StoreTransitionDescriptor::InitializePlatformSpecific(
234  CallInterfaceDescriptorData* data) {
235  Register registers[] = {
236  ReceiverRegister(), NameRegister(), MapRegister(),
237  ValueRegister(), SlotRegister(), VectorRegister(),
238  };
239  int len = arraysize(registers) - kStackArgumentsCount;
240  data->InitializePlatformSpecific(len, registers);
241 }
242 
243 void StringAtDescriptor::InitializePlatformSpecific(
244  CallInterfaceDescriptorData* data) {
245  DefaultInitializePlatformSpecific(data, kParameterCount);
246 }
247 
248 void StringSubstringDescriptor::InitializePlatformSpecific(
249  CallInterfaceDescriptorData* data) {
250  DefaultInitializePlatformSpecific(data, kParameterCount);
251 }
252 
253 void TypeConversionDescriptor::InitializePlatformSpecific(
254  CallInterfaceDescriptorData* data) {
255  Register registers[] = {ArgumentRegister()};
256  data->InitializePlatformSpecific(arraysize(registers), registers);
257 }
258 
259 void TypeConversionStackParameterDescriptor::InitializePlatformSpecific(
260  CallInterfaceDescriptorData* data) {
261  data->InitializePlatformSpecific(0, nullptr);
262 }
263 
264 void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific(
265  CallInterfaceDescriptorData* data) {
266  data->InitializePlatformSpecific(0, nullptr);
267 }
268 
269 void LoadWithVectorDescriptor::InitializePlatformSpecific(
270  CallInterfaceDescriptorData* data) {
271  Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
272  VectorRegister()};
273  // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
274  // to allow no_reg entries.
275  // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), SlotRegister(),
276  // VectorRegister(), kRootRegister));
277  int len = arraysize(registers) - kStackArgumentsCount;
278  data->InitializePlatformSpecific(len, registers);
279 }
280 
281 void StoreWithVectorDescriptor::InitializePlatformSpecific(
282  CallInterfaceDescriptorData* data) {
283  Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
284  SlotRegister(), VectorRegister()};
285  // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
286  // to allow no_reg entries.
287  // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), kRootRegister));
288  int len = arraysize(registers) - kStackArgumentsCount;
289  data->InitializePlatformSpecific(len, registers);
290 }
291 
292 const Register ApiGetterDescriptor::ReceiverRegister() {
293  return LoadDescriptor::ReceiverRegister();
294 }
295 
296 void ApiGetterDescriptor::InitializePlatformSpecific(
297  CallInterfaceDescriptorData* data) {
298  Register registers[] = {ReceiverRegister(), HolderRegister(),
299  CallbackRegister()};
300  data->InitializePlatformSpecific(arraysize(registers), registers);
301 }
302 
303 void ContextOnlyDescriptor::InitializePlatformSpecific(
304  CallInterfaceDescriptorData* data) {
305  data->InitializePlatformSpecific(0, nullptr);
306 }
307 
308 void NoContextDescriptor::InitializePlatformSpecific(
309  CallInterfaceDescriptorData* data) {
310  data->InitializePlatformSpecific(0, nullptr);
311 }
312 
313 void GrowArrayElementsDescriptor::InitializePlatformSpecific(
314  CallInterfaceDescriptorData* data) {
315  Register registers[] = {ObjectRegister(), KeyRegister()};
316  data->InitializePlatformSpecific(arraysize(registers), registers);
317 }
318 
319 void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
320  CallInterfaceDescriptorData* data) {
321  DefaultInitializePlatformSpecific(data, 3);
322 }
323 
324 void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
325  CallInterfaceDescriptorData* data) {
326  // This descriptor must use the same set of registers as the
327  // ArrayNArgumentsConstructorDescriptor.
328  ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
329 }
330 
331 void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
332  CallInterfaceDescriptorData* data) {
333  // This descriptor must use the same set of registers as the
334  // ArrayNArgumentsConstructorDescriptor.
335  ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
336 }
337 
338 void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
339  CallInterfaceDescriptorData* data) {
340  // Keep the arguments on the same registers as they were in
341  // ArrayConstructorDescriptor to avoid unnecessary register moves.
342  // kFunction, kAllocationSite, kActualArgumentsCount
343  Register registers[] = {kJavaScriptCallTargetRegister,
344  kJavaScriptCallExtraArg1Register,
345  kJavaScriptCallArgCountRegister};
346  data->InitializePlatformSpecific(arraysize(registers), registers);
347 }
348 
349 void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
350  CallInterfaceDescriptorData* data) {
351  DefaultInitializePlatformSpecific(data, kParameterCount);
352 }
353 
354 void WasmThrowDescriptor::InitializePlatformSpecific(
355  CallInterfaceDescriptorData* data) {
356  DefaultInitializePlatformSpecific(data, kParameterCount);
357 }
358 
359 void WasmAtomicWakeDescriptor::InitializePlatformSpecific(
360  CallInterfaceDescriptorData* data) {
361  DefaultInitializePlatformSpecific(data, kParameterCount);
362 }
363 
364 void WasmI32AtomicWaitDescriptor::InitializePlatformSpecific(
365  CallInterfaceDescriptorData* data) {
366  DefaultInitializePlatformSpecific(data, kParameterCount);
367 }
368 
369 void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
370  CallInterfaceDescriptorData* data) {
371  DefaultInitializePlatformSpecific(data, kParameterCount);
372 }
373 
374 } // namespace internal
375 } // namespace v8
Definition: libplatform.h:13