1 // 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 #include "src/code-factory.h"
6 
7 #include "src/bootstrapper.h"
8 #include "src/ic/ic.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 
14 // static
LoadIC(Isolate * isolate,TypeofMode typeof_mode,LanguageMode language_mode)15 Callable CodeFactory::LoadIC(Isolate* isolate, TypeofMode typeof_mode,
16                              LanguageMode language_mode) {
17   return Callable(
18       LoadIC::initialize_stub(
19           isolate, LoadICState(typeof_mode, language_mode).GetExtraICState()),
20       LoadDescriptor(isolate));
21 }
22 
23 
24 // static
LoadICInOptimizedCode(Isolate * isolate,TypeofMode typeof_mode,LanguageMode language_mode,InlineCacheState initialization_state)25 Callable CodeFactory::LoadICInOptimizedCode(
26     Isolate* isolate, TypeofMode typeof_mode, LanguageMode language_mode,
27     InlineCacheState initialization_state) {
28   auto code = LoadIC::initialize_stub_in_optimized_code(
29       isolate, LoadICState(typeof_mode, language_mode).GetExtraICState(),
30       initialization_state);
31   return Callable(code, LoadWithVectorDescriptor(isolate));
32 }
33 
34 
35 // static
KeyedLoadIC(Isolate * isolate,LanguageMode language_mode)36 Callable CodeFactory::KeyedLoadIC(Isolate* isolate,
37                                   LanguageMode language_mode) {
38   ExtraICState state = is_strong(language_mode) ? LoadICState::kStrongModeState
39                                                 : kNoExtraICState;
40   return Callable(KeyedLoadIC::initialize_stub(isolate, state),
41                   LoadDescriptor(isolate));
42 }
43 
44 
45 // static
KeyedLoadICInOptimizedCode(Isolate * isolate,LanguageMode language_mode,InlineCacheState initialization_state)46 Callable CodeFactory::KeyedLoadICInOptimizedCode(
47     Isolate* isolate, LanguageMode language_mode,
48     InlineCacheState initialization_state) {
49   ExtraICState state = is_strong(language_mode) ? LoadICState::kStrongModeState
50                                                 : kNoExtraICState;
51   auto code = KeyedLoadIC::initialize_stub_in_optimized_code(
52       isolate, initialization_state, state);
53   if (initialization_state != MEGAMORPHIC) {
54     return Callable(code, LoadWithVectorDescriptor(isolate));
55   }
56   return Callable(code, LoadDescriptor(isolate));
57 }
58 
59 
60 // static
CallIC(Isolate * isolate,int argc,ConvertReceiverMode mode)61 Callable CodeFactory::CallIC(Isolate* isolate, int argc,
62                              ConvertReceiverMode mode) {
63   return Callable(CallIC::initialize_stub(isolate, argc, mode),
64                   CallFunctionWithFeedbackDescriptor(isolate));
65 }
66 
67 
68 // static
CallICInOptimizedCode(Isolate * isolate,int argc,ConvertReceiverMode mode)69 Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc,
70                                             ConvertReceiverMode mode) {
71   return Callable(
72       CallIC::initialize_stub_in_optimized_code(isolate, argc, mode),
73       CallFunctionWithFeedbackAndVectorDescriptor(isolate));
74 }
75 
76 
77 // static
StoreIC(Isolate * isolate,LanguageMode language_mode)78 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
79   return Callable(
80       StoreIC::initialize_stub(isolate, language_mode, UNINITIALIZED),
81       VectorStoreICTrampolineDescriptor(isolate));
82 }
83 
84 
85 // static
StoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode,InlineCacheState initialization_state)86 Callable CodeFactory::StoreICInOptimizedCode(
87     Isolate* isolate, LanguageMode language_mode,
88     InlineCacheState initialization_state) {
89   CallInterfaceDescriptor descriptor = initialization_state != MEGAMORPHIC
90                                            ? VectorStoreICDescriptor(isolate)
91                                            : StoreDescriptor(isolate);
92   return Callable(StoreIC::initialize_stub_in_optimized_code(
93                       isolate, language_mode, initialization_state),
94                   descriptor);
95 }
96 
97 
98 // static
KeyedStoreIC(Isolate * isolate,LanguageMode language_mode)99 Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
100                                    LanguageMode language_mode) {
101   return Callable(
102       KeyedStoreIC::initialize_stub(isolate, language_mode, UNINITIALIZED),
103       VectorStoreICTrampolineDescriptor(isolate));
104 }
105 
106 
107 // static
KeyedStoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode,InlineCacheState initialization_state)108 Callable CodeFactory::KeyedStoreICInOptimizedCode(
109     Isolate* isolate, LanguageMode language_mode,
110     InlineCacheState initialization_state) {
111   CallInterfaceDescriptor descriptor = initialization_state != MEGAMORPHIC
112                                            ? VectorStoreICDescriptor(isolate)
113                                            : StoreDescriptor(isolate);
114   return Callable(KeyedStoreIC::initialize_stub_in_optimized_code(
115                       isolate, language_mode, initialization_state),
116                   descriptor);
117 }
118 
119 
120 // static
CompareIC(Isolate * isolate,Token::Value op,Strength strength)121 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op,
122                                 Strength strength) {
123   Handle<Code> code = CompareIC::GetUninitialized(isolate, op, strength);
124   return Callable(code, CompareDescriptor(isolate));
125 }
126 
127 
128 // static
CompareNilIC(Isolate * isolate,NilValue nil_value)129 Callable CodeFactory::CompareNilIC(Isolate* isolate, NilValue nil_value) {
130   Handle<Code> code = CompareNilICStub::GetUninitialized(isolate, nil_value);
131   return Callable(code, CompareNilDescriptor(isolate));
132 }
133 
134 
135 // static
BinaryOpIC(Isolate * isolate,Token::Value op,Strength strength)136 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
137                                  Strength strength) {
138   BinaryOpICStub stub(isolate, op, strength);
139   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
140 }
141 
142 
143 // static
InstanceOf(Isolate * isolate)144 Callable CodeFactory::InstanceOf(Isolate* isolate) {
145   InstanceOfStub stub(isolate);
146   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
147 }
148 
149 
150 // static
ToBoolean(Isolate * isolate)151 Callable CodeFactory::ToBoolean(Isolate* isolate) {
152   Handle<Code> code = ToBooleanStub::GetUninitialized(isolate);
153   return Callable(code, ToBooleanDescriptor(isolate));
154 }
155 
156 
157 // static
ToNumber(Isolate * isolate)158 Callable CodeFactory::ToNumber(Isolate* isolate) {
159   ToNumberStub stub(isolate);
160   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
161 }
162 
163 
164 // static
ToString(Isolate * isolate)165 Callable CodeFactory::ToString(Isolate* isolate) {
166   ToStringStub stub(isolate);
167   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
168 }
169 
170 
171 // static
ToLength(Isolate * isolate)172 Callable CodeFactory::ToLength(Isolate* isolate) {
173   ToLengthStub stub(isolate);
174   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
175 }
176 
177 
178 // static
ToObject(Isolate * isolate)179 Callable CodeFactory::ToObject(Isolate* isolate) {
180   ToObjectStub stub(isolate);
181   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
182 }
183 
184 
185 // static
NumberToString(Isolate * isolate)186 Callable CodeFactory::NumberToString(Isolate* isolate) {
187   NumberToStringStub stub(isolate);
188   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
189 }
190 
191 
192 // static
RegExpConstructResult(Isolate * isolate)193 Callable CodeFactory::RegExpConstructResult(Isolate* isolate) {
194   RegExpConstructResultStub stub(isolate);
195   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
196 }
197 
198 
199 // static
RegExpExec(Isolate * isolate)200 Callable CodeFactory::RegExpExec(Isolate* isolate) {
201   RegExpExecStub stub(isolate);
202   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
203 }
204 
205 
206 // static
StringAdd(Isolate * isolate,StringAddFlags flags,PretenureFlag pretenure_flag)207 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
208                                 PretenureFlag pretenure_flag) {
209   StringAddStub stub(isolate, flags, pretenure_flag);
210   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
211 }
212 
213 
214 // static
StringCompare(Isolate * isolate)215 Callable CodeFactory::StringCompare(Isolate* isolate) {
216   StringCompareStub stub(isolate);
217   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
218 }
219 
220 
221 // static
SubString(Isolate * isolate)222 Callable CodeFactory::SubString(Isolate* isolate) {
223   SubStringStub stub(isolate);
224   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
225 }
226 
227 
228 // static
Typeof(Isolate * isolate)229 Callable CodeFactory::Typeof(Isolate* isolate) {
230   TypeofStub stub(isolate);
231   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
232 }
233 
234 
235 // static
FastCloneRegExp(Isolate * isolate)236 Callable CodeFactory::FastCloneRegExp(Isolate* isolate) {
237   FastCloneRegExpStub stub(isolate);
238   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
239 }
240 
241 
242 // static
FastCloneShallowArray(Isolate * isolate)243 Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) {
244   // TODO(mstarzinger): Thread through AllocationSiteMode at some point.
245   FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE);
246   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
247 }
248 
249 
250 // static
FastCloneShallowObject(Isolate * isolate,int length)251 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) {
252   FastCloneShallowObjectStub stub(isolate, length);
253   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
254 }
255 
256 
257 // static
FastNewContext(Isolate * isolate,int slot_count)258 Callable CodeFactory::FastNewContext(Isolate* isolate, int slot_count) {
259   FastNewContextStub stub(isolate, slot_count);
260   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
261 }
262 
263 
264 // static
FastNewClosure(Isolate * isolate,LanguageMode language_mode,FunctionKind kind)265 Callable CodeFactory::FastNewClosure(Isolate* isolate,
266                                      LanguageMode language_mode,
267                                      FunctionKind kind) {
268   FastNewClosureStub stub(isolate, language_mode, kind);
269   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
270 }
271 
272 
273 // static
ArgumentsAccess(Isolate * isolate,bool is_unmapped_arguments,bool has_duplicate_parameters)274 Callable CodeFactory::ArgumentsAccess(Isolate* isolate,
275                                       bool is_unmapped_arguments,
276                                       bool has_duplicate_parameters) {
277   ArgumentsAccessStub::Type type = ArgumentsAccessStub::ComputeType(
278       is_unmapped_arguments, has_duplicate_parameters);
279   ArgumentsAccessStub stub(isolate, type);
280   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
281 }
282 
283 
284 // static
RestArgumentsAccess(Isolate * isolate)285 Callable CodeFactory::RestArgumentsAccess(Isolate* isolate) {
286   RestParamAccessStub stub(isolate);
287   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
288 }
289 
290 
291 // static
AllocateHeapNumber(Isolate * isolate)292 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
293   AllocateHeapNumberStub stub(isolate);
294   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
295 }
296 
297 
298 // static
AllocateMutableHeapNumber(Isolate * isolate)299 Callable CodeFactory::AllocateMutableHeapNumber(Isolate* isolate) {
300   AllocateMutableHeapNumberStub stub(isolate);
301   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
302 }
303 
304 
305 // static
AllocateInNewSpace(Isolate * isolate)306 Callable CodeFactory::AllocateInNewSpace(Isolate* isolate) {
307   AllocateInNewSpaceStub stub(isolate);
308   return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
309 }
310 
311 
312 // static
ArgumentAdaptor(Isolate * isolate)313 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
314   return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
315                   ArgumentAdaptorDescriptor(isolate));
316 }
317 
318 
319 // static
Call(Isolate * isolate,ConvertReceiverMode mode)320 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) {
321   return Callable(isolate->builtins()->Call(mode),
322                   CallTrampolineDescriptor(isolate));
323 }
324 
325 
326 // static
CallFunction(Isolate * isolate,ConvertReceiverMode mode)327 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
328   return Callable(isolate->builtins()->CallFunction(mode),
329                   CallTrampolineDescriptor(isolate));
330 }
331 
332 
333 // static
Construct(Isolate * isolate)334 Callable CodeFactory::Construct(Isolate* isolate) {
335   return Callable(isolate->builtins()->Construct(),
336                   ConstructTrampolineDescriptor(isolate));
337 }
338 
339 
340 // static
ConstructFunction(Isolate * isolate)341 Callable CodeFactory::ConstructFunction(Isolate* isolate) {
342   return Callable(isolate->builtins()->ConstructFunction(),
343                   ConstructTrampolineDescriptor(isolate));
344 }
345 
346 
347 // static
InterpreterPushArgsAndCall(Isolate * isolate)348 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate) {
349   return Callable(isolate->builtins()->InterpreterPushArgsAndCall(),
350                   InterpreterPushArgsAndCallDescriptor(isolate));
351 }
352 
353 
354 // static
InterpreterPushArgsAndConstruct(Isolate * isolate)355 Callable CodeFactory::InterpreterPushArgsAndConstruct(Isolate* isolate) {
356   return Callable(isolate->builtins()->InterpreterPushArgsAndConstruct(),
357                   InterpreterPushArgsAndConstructDescriptor(isolate));
358 }
359 
360 
361 // static
InterpreterCEntry(Isolate * isolate,int result_size)362 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
363   // Note: If we ever use fpregs in the interpreter then we will need to
364   // save fpregs too.
365   CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister);
366   return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
367 }
368 
369 }  // namespace internal
370 }  // namespace v8
371