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 namespace {
14
15 // TODO(ishell): make it (const Stub& stub) once CodeStub::GetCode() is const.
16 template <typename Stub>
make_callable(Stub & stub)17 Callable make_callable(Stub& stub) {
18 typedef typename Stub::Descriptor Descriptor;
19 return Callable(stub.GetCode(), Descriptor(stub.isolate()));
20 }
21
22 } // namespace
23
24 // static
LoadIC(Isolate * isolate)25 Callable CodeFactory::LoadIC(Isolate* isolate) {
26 LoadICTrampolineStub stub(isolate);
27 return make_callable(stub);
28 }
29
30 // static
ApiGetter(Isolate * isolate)31 Callable CodeFactory::ApiGetter(Isolate* isolate) {
32 CallApiGetterStub stub(isolate);
33 return make_callable(stub);
34 }
35
36 // static
LoadICInOptimizedCode(Isolate * isolate)37 Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate) {
38 LoadICStub stub(isolate);
39 return make_callable(stub);
40 }
41
42 // static
LoadGlobalIC(Isolate * isolate,TypeofMode typeof_mode)43 Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
44 LoadGlobalICTrampolineStub stub(isolate, LoadGlobalICState(typeof_mode));
45 return make_callable(stub);
46 }
47
48 // static
LoadGlobalICInOptimizedCode(Isolate * isolate,TypeofMode typeof_mode)49 Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
50 TypeofMode typeof_mode) {
51 LoadGlobalICStub stub(isolate, LoadGlobalICState(typeof_mode));
52 return make_callable(stub);
53 }
54
55 // static
KeyedLoadIC(Isolate * isolate)56 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
57 KeyedLoadICTrampolineTFStub stub(isolate);
58 return make_callable(stub);
59 }
60
61 // static
KeyedLoadICInOptimizedCode(Isolate * isolate)62 Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
63 KeyedLoadICTFStub stub(isolate);
64 return make_callable(stub);
65 }
66
67 // static
KeyedLoadIC_Megamorphic(Isolate * isolate)68 Callable CodeFactory::KeyedLoadIC_Megamorphic(Isolate* isolate) {
69 return Callable(isolate->builtins()->KeyedLoadIC_Megamorphic_TF(),
70 LoadWithVectorDescriptor(isolate));
71 }
72
73 // static
CallIC(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)74 Callable CodeFactory::CallIC(Isolate* isolate, ConvertReceiverMode mode,
75 TailCallMode tail_call_mode) {
76 CallICTrampolineStub stub(isolate, CallICState(mode, tail_call_mode));
77 return make_callable(stub);
78 }
79
80 // static
CallICInOptimizedCode(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)81 Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate,
82 ConvertReceiverMode mode,
83 TailCallMode tail_call_mode) {
84 CallICStub stub(isolate, CallICState(mode, tail_call_mode));
85 return make_callable(stub);
86 }
87
88 // static
StoreIC(Isolate * isolate,LanguageMode language_mode)89 Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
90 StoreICTrampolineStub stub(isolate, StoreICState(language_mode));
91 return make_callable(stub);
92 }
93
94 // static
StoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode)95 Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
96 LanguageMode language_mode) {
97 StoreICStub stub(isolate, StoreICState(language_mode));
98 return make_callable(stub);
99 }
100
101 // static
KeyedStoreIC(Isolate * isolate,LanguageMode language_mode)102 Callable CodeFactory::KeyedStoreIC(Isolate* isolate,
103 LanguageMode language_mode) {
104 if (FLAG_tf_store_ic_stub) {
105 KeyedStoreICTrampolineTFStub stub(isolate, StoreICState(language_mode));
106 return make_callable(stub);
107 }
108 KeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode));
109 return make_callable(stub);
110 }
111
112 // static
KeyedStoreICInOptimizedCode(Isolate * isolate,LanguageMode language_mode)113 Callable CodeFactory::KeyedStoreICInOptimizedCode(Isolate* isolate,
114 LanguageMode language_mode) {
115 if (FLAG_tf_store_ic_stub) {
116 KeyedStoreICTFStub stub(isolate, StoreICState(language_mode));
117 return make_callable(stub);
118 }
119 KeyedStoreICStub stub(isolate, StoreICState(language_mode));
120 return make_callable(stub);
121 }
122
123 // static
KeyedStoreIC_Megamorphic(Isolate * isolate,LanguageMode language_mode)124 Callable CodeFactory::KeyedStoreIC_Megamorphic(Isolate* isolate,
125 LanguageMode language_mode) {
126 if (FLAG_tf_store_ic_stub) {
127 return Callable(
128 language_mode == STRICT
129 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict_TF()
130 : isolate->builtins()->KeyedStoreIC_Megamorphic_TF(),
131 StoreWithVectorDescriptor(isolate));
132 }
133 return Callable(language_mode == STRICT
134 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
135 : isolate->builtins()->KeyedStoreIC_Megamorphic(),
136 StoreWithVectorDescriptor(isolate));
137 }
138
139 // static
CompareIC(Isolate * isolate,Token::Value op)140 Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
141 CompareICStub stub(isolate, op);
142 return make_callable(stub);
143 }
144
145 // static
BinaryOpIC(Isolate * isolate,Token::Value op)146 Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
147 BinaryOpICStub stub(isolate, op);
148 return make_callable(stub);
149 }
150
151 // static
GetProperty(Isolate * isolate)152 Callable CodeFactory::GetProperty(Isolate* isolate) {
153 GetPropertyStub stub(isolate);
154 return make_callable(stub);
155 }
156
157 // static
ToBoolean(Isolate * isolate)158 Callable CodeFactory::ToBoolean(Isolate* isolate) {
159 return Callable(isolate->builtins()->ToBoolean(),
160 TypeConversionDescriptor(isolate));
161 }
162
163 // static
ToNumber(Isolate * isolate)164 Callable CodeFactory::ToNumber(Isolate* isolate) {
165 return Callable(isolate->builtins()->ToNumber(),
166 TypeConversionDescriptor(isolate));
167 }
168
169 // static
NonNumberToNumber(Isolate * isolate)170 Callable CodeFactory::NonNumberToNumber(Isolate* isolate) {
171 return Callable(isolate->builtins()->NonNumberToNumber(),
172 TypeConversionDescriptor(isolate));
173 }
174
175 // static
StringToNumber(Isolate * isolate)176 Callable CodeFactory::StringToNumber(Isolate* isolate) {
177 return Callable(isolate->builtins()->StringToNumber(),
178 TypeConversionDescriptor(isolate));
179 }
180
181 // static
ToName(Isolate * isolate)182 Callable CodeFactory::ToName(Isolate* isolate) {
183 return Callable(isolate->builtins()->ToName(),
184 TypeConversionDescriptor(isolate));
185 }
186
187 // static
NonPrimitiveToPrimitive(Isolate * isolate,ToPrimitiveHint hint)188 Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
189 ToPrimitiveHint hint) {
190 return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint),
191 TypeConversionDescriptor(isolate));
192 }
193
194 // static
OrdinaryToPrimitive(Isolate * isolate,OrdinaryToPrimitiveHint hint)195 Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate,
196 OrdinaryToPrimitiveHint hint) {
197 return Callable(isolate->builtins()->OrdinaryToPrimitive(hint),
198 TypeConversionDescriptor(isolate));
199 }
200
201 // static
NumberToString(Isolate * isolate)202 Callable CodeFactory::NumberToString(Isolate* isolate) {
203 NumberToStringStub stub(isolate);
204 return make_callable(stub);
205 }
206
207 // static
RegExpExec(Isolate * isolate)208 Callable CodeFactory::RegExpExec(Isolate* isolate) {
209 RegExpExecStub stub(isolate);
210 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
211 }
212
213 // static
StringFromCharCode(Isolate * isolate)214 Callable CodeFactory::StringFromCharCode(Isolate* isolate) {
215 Handle<Code> code(isolate->builtins()->StringFromCharCode());
216 return Callable(code, BuiltinDescriptor(isolate));
217 }
218
219 #define DECLARE_TFS(Name, Kind, Extra, InterfaceDescriptor) \
220 typedef InterfaceDescriptor##Descriptor Name##Descriptor;
BUILTIN_LIST(IGNORE_BUILTIN,IGNORE_BUILTIN,IGNORE_BUILTIN,DECLARE_TFS,IGNORE_BUILTIN,IGNORE_BUILTIN,IGNORE_BUILTIN)221 BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN, DECLARE_TFS,
222 IGNORE_BUILTIN, IGNORE_BUILTIN, IGNORE_BUILTIN)
223 #undef DECLARE_TFS
224
225 #define TFS_BUILTIN(Name) \
226 Callable CodeFactory::Name(Isolate* isolate) { \
227 Handle<Code> code(isolate->builtins()->Name()); \
228 return Callable(code, Name##Descriptor(isolate)); \
229 }
230
231 TFS_BUILTIN(ToString)
232 TFS_BUILTIN(Add)
233 TFS_BUILTIN(Subtract)
234 TFS_BUILTIN(Multiply)
235 TFS_BUILTIN(Divide)
236 TFS_BUILTIN(Modulus)
237 TFS_BUILTIN(BitwiseAnd)
238 TFS_BUILTIN(BitwiseOr)
239 TFS_BUILTIN(BitwiseXor)
240 TFS_BUILTIN(ShiftLeft)
241 TFS_BUILTIN(ShiftRight)
242 TFS_BUILTIN(ShiftRightLogical)
243 TFS_BUILTIN(LessThan)
244 TFS_BUILTIN(LessThanOrEqual)
245 TFS_BUILTIN(GreaterThan)
246 TFS_BUILTIN(GreaterThanOrEqual)
247 TFS_BUILTIN(Equal)
248 TFS_BUILTIN(NotEqual)
249 TFS_BUILTIN(StrictEqual)
250 TFS_BUILTIN(StrictNotEqual)
251 TFS_BUILTIN(HasProperty)
252 TFS_BUILTIN(ToInteger)
253 TFS_BUILTIN(ToLength)
254 TFS_BUILTIN(ToObject)
255 TFS_BUILTIN(Typeof)
256 TFS_BUILTIN(InstanceOf)
257 TFS_BUILTIN(OrdinaryHasInstance)
258 TFS_BUILTIN(ForInFilter)
259
260 #undef TFS_BUILTIN
261
262 // static
263 Callable CodeFactory::Inc(Isolate* isolate) {
264 IncStub stub(isolate);
265 return make_callable(stub);
266 }
267
268 // static
Dec(Isolate * isolate)269 Callable CodeFactory::Dec(Isolate* isolate) {
270 DecStub stub(isolate);
271 return make_callable(stub);
272 }
273
274 // static
StringAdd(Isolate * isolate,StringAddFlags flags,PretenureFlag pretenure_flag)275 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
276 PretenureFlag pretenure_flag) {
277 StringAddStub stub(isolate, flags, pretenure_flag);
278 return make_callable(stub);
279 }
280
281 // static
StringCompare(Isolate * isolate,Token::Value token)282 Callable CodeFactory::StringCompare(Isolate* isolate, Token::Value token) {
283 switch (token) {
284 case Token::EQ:
285 case Token::EQ_STRICT:
286 return StringEqual(isolate);
287 case Token::NE:
288 case Token::NE_STRICT:
289 return StringNotEqual(isolate);
290 case Token::LT:
291 return StringLessThan(isolate);
292 case Token::GT:
293 return StringGreaterThan(isolate);
294 case Token::LTE:
295 return StringLessThanOrEqual(isolate);
296 case Token::GTE:
297 return StringGreaterThanOrEqual(isolate);
298 default:
299 break;
300 }
301 UNREACHABLE();
302 return StringEqual(isolate);
303 }
304
305 // static
StringEqual(Isolate * isolate)306 Callable CodeFactory::StringEqual(Isolate* isolate) {
307 return Callable(isolate->builtins()->StringEqual(),
308 CompareDescriptor(isolate));
309 }
310
311 // static
StringNotEqual(Isolate * isolate)312 Callable CodeFactory::StringNotEqual(Isolate* isolate) {
313 return Callable(isolate->builtins()->StringNotEqual(),
314 CompareDescriptor(isolate));
315 }
316
317 // static
StringLessThan(Isolate * isolate)318 Callable CodeFactory::StringLessThan(Isolate* isolate) {
319 return Callable(isolate->builtins()->StringLessThan(),
320 CompareDescriptor(isolate));
321 }
322
323 // static
StringLessThanOrEqual(Isolate * isolate)324 Callable CodeFactory::StringLessThanOrEqual(Isolate* isolate) {
325 return Callable(isolate->builtins()->StringLessThanOrEqual(),
326 CompareDescriptor(isolate));
327 }
328
329 // static
StringGreaterThan(Isolate * isolate)330 Callable CodeFactory::StringGreaterThan(Isolate* isolate) {
331 return Callable(isolate->builtins()->StringGreaterThan(),
332 CompareDescriptor(isolate));
333 }
334
335 // static
StringGreaterThanOrEqual(Isolate * isolate)336 Callable CodeFactory::StringGreaterThanOrEqual(Isolate* isolate) {
337 return Callable(isolate->builtins()->StringGreaterThanOrEqual(),
338 CompareDescriptor(isolate));
339 }
340
341 // static
SubString(Isolate * isolate)342 Callable CodeFactory::SubString(Isolate* isolate) {
343 SubStringStub stub(isolate);
344 return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
345 }
346
347 // static
ResumeGenerator(Isolate * isolate)348 Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
349 return Callable(isolate->builtins()->ResumeGeneratorTrampoline(),
350 ResumeGeneratorDescriptor(isolate));
351 }
352
353 // static
FastCloneRegExp(Isolate * isolate)354 Callable CodeFactory::FastCloneRegExp(Isolate* isolate) {
355 FastCloneRegExpStub stub(isolate);
356 return make_callable(stub);
357 }
358
359 // static
FastCloneShallowArray(Isolate * isolate)360 Callable CodeFactory::FastCloneShallowArray(Isolate* isolate) {
361 // TODO(mstarzinger): Thread through AllocationSiteMode at some point.
362 FastCloneShallowArrayStub stub(isolate, DONT_TRACK_ALLOCATION_SITE);
363 return make_callable(stub);
364 }
365
366 // static
FastCloneShallowObject(Isolate * isolate,int length)367 Callable CodeFactory::FastCloneShallowObject(Isolate* isolate, int length) {
368 FastCloneShallowObjectStub stub(isolate, length);
369 return make_callable(stub);
370 }
371
372
373 // static
FastNewFunctionContext(Isolate * isolate)374 Callable CodeFactory::FastNewFunctionContext(Isolate* isolate) {
375 FastNewFunctionContextStub stub(isolate);
376 return make_callable(stub);
377 }
378
379 // static
FastNewClosure(Isolate * isolate)380 Callable CodeFactory::FastNewClosure(Isolate* isolate) {
381 FastNewClosureStub stub(isolate);
382 return make_callable(stub);
383 }
384
385 // static
FastNewObject(Isolate * isolate)386 Callable CodeFactory::FastNewObject(Isolate* isolate) {
387 FastNewObjectStub stub(isolate);
388 return make_callable(stub);
389 }
390
391 // static
FastNewRestParameter(Isolate * isolate,bool skip_stub_frame)392 Callable CodeFactory::FastNewRestParameter(Isolate* isolate,
393 bool skip_stub_frame) {
394 FastNewRestParameterStub stub(isolate, skip_stub_frame);
395 return make_callable(stub);
396 }
397
398 // static
FastNewSloppyArguments(Isolate * isolate,bool skip_stub_frame)399 Callable CodeFactory::FastNewSloppyArguments(Isolate* isolate,
400 bool skip_stub_frame) {
401 FastNewSloppyArgumentsStub stub(isolate, skip_stub_frame);
402 return make_callable(stub);
403 }
404
405 // static
FastNewStrictArguments(Isolate * isolate,bool skip_stub_frame)406 Callable CodeFactory::FastNewStrictArguments(Isolate* isolate,
407 bool skip_stub_frame) {
408 FastNewStrictArgumentsStub stub(isolate, skip_stub_frame);
409 return make_callable(stub);
410 }
411
412 // static
CopyFastSmiOrObjectElements(Isolate * isolate)413 Callable CodeFactory::CopyFastSmiOrObjectElements(Isolate* isolate) {
414 return Callable(isolate->builtins()->CopyFastSmiOrObjectElements(),
415 CopyFastSmiOrObjectElementsDescriptor(isolate));
416 }
417
418 // static
GrowFastDoubleElements(Isolate * isolate)419 Callable CodeFactory::GrowFastDoubleElements(Isolate* isolate) {
420 return Callable(isolate->builtins()->GrowFastDoubleElements(),
421 GrowArrayElementsDescriptor(isolate));
422 }
423
424 // static
GrowFastSmiOrObjectElements(Isolate * isolate)425 Callable CodeFactory::GrowFastSmiOrObjectElements(Isolate* isolate) {
426 return Callable(isolate->builtins()->GrowFastSmiOrObjectElements(),
427 GrowArrayElementsDescriptor(isolate));
428 }
429
430 // static
AllocateHeapNumber(Isolate * isolate)431 Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
432 AllocateHeapNumberStub stub(isolate);
433 return make_callable(stub);
434 }
435
436 #define SIMD128_ALLOC(TYPE, Type, type, lane_count, lane_type) \
437 Callable CodeFactory::Allocate##Type(Isolate* isolate) { \
438 Allocate##Type##Stub stub(isolate); \
439 return make_callable(stub); \
440 }
SIMD128_TYPES(SIMD128_ALLOC)441 SIMD128_TYPES(SIMD128_ALLOC)
442 #undef SIMD128_ALLOC
443
444 // static
445 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
446 return Callable(isolate->builtins()->ArgumentsAdaptorTrampoline(),
447 ArgumentAdaptorDescriptor(isolate));
448 }
449
450 // static
Call(Isolate * isolate,ConvertReceiverMode mode,TailCallMode tail_call_mode)451 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode,
452 TailCallMode tail_call_mode) {
453 return Callable(isolate->builtins()->Call(mode, tail_call_mode),
454 CallTrampolineDescriptor(isolate));
455 }
456
457 // static
CallFunction(Isolate * isolate,ConvertReceiverMode mode)458 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
459 return Callable(isolate->builtins()->CallFunction(mode),
460 CallTrampolineDescriptor(isolate));
461 }
462
463 // static
Construct(Isolate * isolate)464 Callable CodeFactory::Construct(Isolate* isolate) {
465 return Callable(isolate->builtins()->Construct(),
466 ConstructTrampolineDescriptor(isolate));
467 }
468
469 // static
ConstructFunction(Isolate * isolate)470 Callable CodeFactory::ConstructFunction(Isolate* isolate) {
471 return Callable(isolate->builtins()->ConstructFunction(),
472 ConstructTrampolineDescriptor(isolate));
473 }
474
475 // static
InterpreterPushArgsAndCall(Isolate * isolate,TailCallMode tail_call_mode,CallableType function_type)476 Callable CodeFactory::InterpreterPushArgsAndCall(Isolate* isolate,
477 TailCallMode tail_call_mode,
478 CallableType function_type) {
479 return Callable(isolate->builtins()->InterpreterPushArgsAndCall(
480 tail_call_mode, function_type),
481 InterpreterPushArgsAndCallDescriptor(isolate));
482 }
483
484 // static
InterpreterPushArgsAndConstruct(Isolate * isolate,CallableType function_type)485 Callable CodeFactory::InterpreterPushArgsAndConstruct(
486 Isolate* isolate, CallableType function_type) {
487 return Callable(
488 isolate->builtins()->InterpreterPushArgsAndConstruct(function_type),
489 InterpreterPushArgsAndConstructDescriptor(isolate));
490 }
491
492 // static
InterpreterPushArgsAndConstructArray(Isolate * isolate)493 Callable CodeFactory::InterpreterPushArgsAndConstructArray(Isolate* isolate) {
494 return Callable(isolate->builtins()->InterpreterPushArgsAndConstructArray(),
495 InterpreterPushArgsAndConstructArrayDescriptor(isolate));
496 }
497
498 // static
InterpreterCEntry(Isolate * isolate,int result_size)499 Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
500 // Note: If we ever use fpregs in the interpreter then we will need to
501 // save fpregs too.
502 CEntryStub stub(isolate, result_size, kDontSaveFPRegs, kArgvInRegister);
503 return Callable(stub.GetCode(), InterpreterCEntryDescriptor(isolate));
504 }
505
506 // static
InterpreterOnStackReplacement(Isolate * isolate)507 Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
508 return Callable(isolate->builtins()->InterpreterOnStackReplacement(),
509 ContextOnlyDescriptor(isolate));
510 }
511
512 } // namespace internal
513 } // namespace v8
514