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