5 #include "src/code-factory.h" 7 #include "src/bootstrapper.h" 8 #include "src/builtins/builtins-descriptors.h" 10 #include "src/objects-inl.h" 18 template <
typename Stub>
19 Callable make_callable(Stub& stub) {
20 typedef typename Stub::Descriptor Descriptor;
21 return Callable(stub.GetCode(), Descriptor{});
27 Handle<Code> CodeFactory::RuntimeCEntry(Isolate* isolate,
int result_size) {
28 return CodeFactory::CEntry(isolate, result_size);
31 #define CENTRY_CODE(RS, SD, AM, BE) \ 32 BUILTIN_CODE(isolate, CEntry_##RS##_##SD##_##AM##_##BE) 35 Handle<Code> CodeFactory::CEntry(Isolate* isolate,
int result_size,
36 SaveFPRegsMode save_doubles,
37 ArgvMode argv_mode,
bool builtin_exit_frame) {
39 const int rs = result_size;
40 const SaveFPRegsMode sd = save_doubles;
41 const ArgvMode am = argv_mode;
42 const bool be = builtin_exit_frame;
44 if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvOnStack && !be) {
45 return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvOnStack, NoBuiltinExit);
46 }
else if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvOnStack && be) {
47 return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvOnStack, BuiltinExit);
48 }
else if (rs == 1 && sd == kDontSaveFPRegs && am == kArgvInRegister && !be) {
49 return CENTRY_CODE(Return1, DontSaveFPRegs, ArgvInRegister, NoBuiltinExit);
50 }
else if (rs == 1 && sd == kSaveFPRegs && am == kArgvOnStack && !be) {
51 return CENTRY_CODE(Return1, SaveFPRegs, ArgvOnStack, NoBuiltinExit);
52 }
else if (rs == 1 && sd == kSaveFPRegs && am == kArgvOnStack && be) {
53 return CENTRY_CODE(Return1, SaveFPRegs, ArgvOnStack, BuiltinExit);
54 }
else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvOnStack && !be) {
55 return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvOnStack, NoBuiltinExit);
56 }
else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvOnStack && be) {
57 return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvOnStack, BuiltinExit);
58 }
else if (rs == 2 && sd == kDontSaveFPRegs && am == kArgvInRegister && !be) {
59 return CENTRY_CODE(Return2, DontSaveFPRegs, ArgvInRegister, NoBuiltinExit);
60 }
else if (rs == 2 && sd == kSaveFPRegs && am == kArgvOnStack && !be) {
61 return CENTRY_CODE(Return2, SaveFPRegs, ArgvOnStack, NoBuiltinExit);
62 }
else if (rs == 2 && sd == kSaveFPRegs && am == kArgvOnStack && be) {
63 return CENTRY_CODE(Return2, SaveFPRegs, ArgvOnStack, BuiltinExit);
72 Callable CodeFactory::ApiGetter(Isolate* isolate) {
73 return Callable(BUILTIN_CODE(isolate, CallApiGetter), ApiGetterDescriptor{});
77 Callable CodeFactory::CallApiCallback(Isolate* isolate,
int argc) {
80 return Callable(BUILTIN_CODE(isolate, CallApiCallback_Argc0),
81 ApiCallbackDescriptor{});
83 return Callable(BUILTIN_CODE(isolate, CallApiCallback_Argc1),
84 ApiCallbackDescriptor{});
86 CallApiCallbackStub stub(isolate, argc);
87 return make_callable(stub);
94 Callable CodeFactory::LoadGlobalIC(Isolate* isolate, TypeofMode typeof_mode) {
96 typeof_mode == NOT_INSIDE_TYPEOF
97 ? BUILTIN_CODE(isolate, LoadGlobalICTrampoline)
98 : BUILTIN_CODE(isolate, LoadGlobalICInsideTypeofTrampoline),
99 LoadGlobalDescriptor{});
103 Callable CodeFactory::LoadGlobalICInOptimizedCode(Isolate* isolate,
104 TypeofMode typeof_mode) {
105 return Callable(typeof_mode == NOT_INSIDE_TYPEOF
106 ? BUILTIN_CODE(isolate, LoadGlobalIC)
107 : BUILTIN_CODE(isolate, LoadGlobalICInsideTypeof),
108 LoadGlobalWithVectorDescriptor{});
111 Callable CodeFactory::StoreOwnIC(Isolate* isolate) {
114 return Callable(BUILTIN_CODE(isolate, StoreICTrampoline), StoreDescriptor{});
117 Callable CodeFactory::StoreOwnICInOptimizedCode(Isolate* isolate) {
120 return Callable(BUILTIN_CODE(isolate, StoreIC), StoreWithVectorDescriptor{});
123 Callable CodeFactory::KeyedStoreIC_SloppyArguments(Isolate* isolate,
124 KeyedAccessStoreMode mode) {
125 Builtins::Name builtin_index;
128 builtin_index = Builtins::kKeyedStoreIC_SloppyArguments_Standard;
130 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
132 Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW;
134 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
136 Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB;
138 case STORE_NO_TRANSITION_HANDLE_COW:
140 Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW;
145 return isolate->builtins()->CallableFor(isolate, builtin_index);
148 Callable CodeFactory::KeyedStoreIC_Slow(Isolate* isolate,
149 KeyedAccessStoreMode mode) {
150 Builtins::Name builtin_index;
153 builtin_index = Builtins::kKeyedStoreIC_Slow_Standard;
155 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
156 builtin_index = Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW;
158 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
159 builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB;
161 case STORE_NO_TRANSITION_HANDLE_COW:
162 builtin_index = Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW;
167 return isolate->builtins()->CallableFor(isolate, builtin_index);
170 Callable CodeFactory::StoreInArrayLiteralIC_Slow(Isolate* isolate,
171 KeyedAccessStoreMode mode) {
172 Builtins::Name builtin_index;
175 builtin_index = Builtins::kStoreInArrayLiteralIC_Slow_Standard;
177 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
179 Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW;
181 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
183 Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB;
185 case STORE_NO_TRANSITION_HANDLE_COW:
187 Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW;
192 return isolate->builtins()->CallableFor(isolate, builtin_index);
195 Callable CodeFactory::ElementsTransitionAndStore(Isolate* isolate,
196 KeyedAccessStoreMode mode) {
197 Builtins::Name builtin_index;
200 builtin_index = Builtins::kElementsTransitionAndStore_Standard;
202 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
204 Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW;
206 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
208 Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB;
210 case STORE_NO_TRANSITION_HANDLE_COW:
212 Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW;
217 return isolate->builtins()->CallableFor(isolate, builtin_index);
220 Callable CodeFactory::StoreFastElementIC(Isolate* isolate,
221 KeyedAccessStoreMode mode) {
222 Builtins::Name builtin_index;
225 builtin_index = Builtins::kStoreFastElementIC_Standard;
227 case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
228 builtin_index = Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW;
230 case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
231 builtin_index = Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB;
233 case STORE_NO_TRANSITION_HANDLE_COW:
234 builtin_index = Builtins::kStoreFastElementIC_NoTransitionHandleCOW;
239 return isolate->builtins()->CallableFor(isolate, builtin_index);
243 Callable CodeFactory::BinaryOperation(Isolate* isolate, Operation op) {
245 case Operation::kShiftRight:
246 return Builtins::CallableFor(isolate, Builtins::kShiftRight);
247 case Operation::kShiftLeft:
248 return Builtins::CallableFor(isolate, Builtins::kShiftLeft);
249 case Operation::kShiftRightLogical:
250 return Builtins::CallableFor(isolate, Builtins::kShiftRightLogical);
251 case Operation::kAdd:
252 return Builtins::CallableFor(isolate, Builtins::kAdd);
253 case Operation::kSubtract:
254 return Builtins::CallableFor(isolate, Builtins::kSubtract);
255 case Operation::kMultiply:
256 return Builtins::CallableFor(isolate, Builtins::kMultiply);
257 case Operation::kDivide:
258 return Builtins::CallableFor(isolate, Builtins::kDivide);
259 case Operation::kModulus:
260 return Builtins::CallableFor(isolate, Builtins::kModulus);
261 case Operation::kBitwiseOr:
262 return Builtins::CallableFor(isolate, Builtins::kBitwiseOr);
263 case Operation::kBitwiseAnd:
264 return Builtins::CallableFor(isolate, Builtins::kBitwiseAnd);
265 case Operation::kBitwiseXor:
266 return Builtins::CallableFor(isolate, Builtins::kBitwiseXor);
274 Callable CodeFactory::NonPrimitiveToPrimitive(Isolate* isolate,
275 ToPrimitiveHint hint) {
276 return Callable(isolate->builtins()->NonPrimitiveToPrimitive(hint),
277 TypeConversionDescriptor{});
281 Callable CodeFactory::OrdinaryToPrimitive(Isolate* isolate,
282 OrdinaryToPrimitiveHint hint) {
283 return Callable(isolate->builtins()->OrdinaryToPrimitive(hint),
284 TypeConversionDescriptor{});
288 Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags) {
290 case STRING_ADD_CHECK_NONE:
291 return Builtins::CallableFor(isolate, Builtins::kStringAdd_CheckNone);
292 case STRING_ADD_CONVERT_LEFT:
293 return Builtins::CallableFor(isolate, Builtins::kStringAdd_ConvertLeft);
294 case STRING_ADD_CONVERT_RIGHT:
295 return Builtins::CallableFor(isolate, Builtins::kStringAdd_ConvertRight);
301 Callable CodeFactory::ResumeGenerator(Isolate* isolate) {
302 return Callable(BUILTIN_CODE(isolate, ResumeGeneratorTrampoline),
303 ResumeGeneratorDescriptor{});
307 Callable CodeFactory::FrameDropperTrampoline(Isolate* isolate) {
308 return Callable(BUILTIN_CODE(isolate, FrameDropperTrampoline),
309 FrameDropperTrampolineDescriptor{});
313 Callable CodeFactory::HandleDebuggerStatement(Isolate* isolate) {
314 return Callable(BUILTIN_CODE(isolate, HandleDebuggerStatement),
315 ContextOnlyDescriptor{});
319 Callable CodeFactory::FastNewFunctionContext(Isolate* isolate,
320 ScopeType scope_type) {
321 return Callable(isolate->builtins()->NewFunctionContext(scope_type),
322 FastNewFunctionContextDescriptor{});
326 Callable CodeFactory::ArgumentAdaptor(Isolate* isolate) {
327 return Callable(BUILTIN_CODE(isolate, ArgumentsAdaptorTrampoline),
328 ArgumentsAdaptorDescriptor{});
332 Callable CodeFactory::Call(Isolate* isolate, ConvertReceiverMode mode) {
333 return Callable(isolate->builtins()->Call(mode), CallTrampolineDescriptor{});
337 Callable CodeFactory::CallWithArrayLike(Isolate* isolate) {
338 return Callable(BUILTIN_CODE(isolate, CallWithArrayLike),
339 CallWithArrayLikeDescriptor{});
343 Callable CodeFactory::CallWithSpread(Isolate* isolate) {
344 return Callable(BUILTIN_CODE(isolate, CallWithSpread),
345 CallWithSpreadDescriptor{});
349 Callable CodeFactory::CallFunction(Isolate* isolate, ConvertReceiverMode mode) {
350 return Callable(isolate->builtins()->CallFunction(mode),
351 CallTrampolineDescriptor{});
355 Callable CodeFactory::CallVarargs(Isolate* isolate) {
356 return Callable(BUILTIN_CODE(isolate, CallVarargs), CallVarargsDescriptor{});
360 Callable CodeFactory::CallForwardVarargs(Isolate* isolate) {
361 return Callable(BUILTIN_CODE(isolate, CallForwardVarargs),
362 CallForwardVarargsDescriptor{});
366 Callable CodeFactory::CallFunctionForwardVarargs(Isolate* isolate) {
367 return Callable(BUILTIN_CODE(isolate, CallFunctionForwardVarargs),
368 CallForwardVarargsDescriptor{});
372 Callable CodeFactory::Construct(Isolate* isolate) {
373 return Callable(BUILTIN_CODE(isolate, Construct), JSTrampolineDescriptor{});
377 Callable CodeFactory::ConstructWithSpread(Isolate* isolate) {
378 return Callable(BUILTIN_CODE(isolate, ConstructWithSpread),
379 ConstructWithSpreadDescriptor{});
383 Callable CodeFactory::ConstructFunction(Isolate* isolate) {
384 return Callable(BUILTIN_CODE(isolate, ConstructFunction),
385 JSTrampolineDescriptor{});
389 Callable CodeFactory::ConstructVarargs(Isolate* isolate) {
390 return Callable(BUILTIN_CODE(isolate, ConstructVarargs),
391 ConstructVarargsDescriptor{});
395 Callable CodeFactory::ConstructForwardVarargs(Isolate* isolate) {
396 return Callable(BUILTIN_CODE(isolate, ConstructForwardVarargs),
397 ConstructForwardVarargsDescriptor{});
401 Callable CodeFactory::ConstructFunctionForwardVarargs(Isolate* isolate) {
402 return Callable(BUILTIN_CODE(isolate, ConstructFunctionForwardVarargs),
403 ConstructForwardVarargsDescriptor{});
407 Callable CodeFactory::InterpreterPushArgsThenCall(
408 Isolate* isolate, ConvertReceiverMode receiver_mode,
409 InterpreterPushArgsMode mode) {
411 isolate->builtins()->InterpreterPushArgsThenCall(receiver_mode, mode),
412 InterpreterPushArgsThenCallDescriptor{});
416 Callable CodeFactory::InterpreterPushArgsThenConstruct(
417 Isolate* isolate, InterpreterPushArgsMode mode) {
418 return Callable(isolate->builtins()->InterpreterPushArgsThenConstruct(mode),
419 InterpreterPushArgsThenConstructDescriptor{});
423 Callable CodeFactory::InterpreterCEntry(Isolate* isolate,
int result_size) {
426 Handle<Code> code = CodeFactory::CEntry(isolate, result_size, kDontSaveFPRegs,
428 if (result_size == 1) {
429 return Callable(code, InterpreterCEntry1Descriptor{});
431 DCHECK_EQ(result_size, 2);
432 return Callable(code, InterpreterCEntry2Descriptor{});
437 Callable CodeFactory::InterpreterOnStackReplacement(Isolate* isolate) {
438 return Callable(BUILTIN_CODE(isolate, InterpreterOnStackReplacement),
439 ContextOnlyDescriptor{});
443 Callable CodeFactory::ArrayNoArgumentConstructor(
444 Isolate* isolate, ElementsKind kind,
445 AllocationSiteOverrideMode override_mode) {
446 #define CASE(kind_caps, kind_camel, mode_camel) \ 449 BUILTIN_CODE(isolate, \ 450 ArrayNoArgumentConstructor_##kind_camel##_##mode_camel), \ 451 ArrayNoArgumentConstructorDescriptor{}) 452 if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
453 DCHECK(IsSmiElementsKind(kind));
455 CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
456 CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
461 DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
462 !AllocationSite::ShouldTrack(kind));
464 CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
465 CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
466 CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
467 CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
468 CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
469 CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
478 Callable CodeFactory::ArraySingleArgumentConstructor(
479 Isolate* isolate, ElementsKind kind,
480 AllocationSiteOverrideMode override_mode) {
481 #define CASE(kind_caps, kind_camel, mode_camel) \ 486 ArraySingleArgumentConstructor_##kind_camel##_##mode_camel), \ 487 ArraySingleArgumentConstructorDescriptor{}) 488 if (override_mode == DONT_OVERRIDE && AllocationSite::ShouldTrack(kind)) {
489 DCHECK(IsSmiElementsKind(kind));
491 CASE(PACKED_SMI_ELEMENTS, PackedSmi, DontOverride);
492 CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DontOverride);
497 DCHECK(override_mode == DISABLE_ALLOCATION_SITES ||
498 !AllocationSite::ShouldTrack(kind));
500 CASE(PACKED_SMI_ELEMENTS, PackedSmi, DisableAllocationSites);
501 CASE(HOLEY_SMI_ELEMENTS, HoleySmi, DisableAllocationSites);
502 CASE(PACKED_ELEMENTS, Packed, DisableAllocationSites);
503 CASE(HOLEY_ELEMENTS, Holey, DisableAllocationSites);
504 CASE(PACKED_DOUBLE_ELEMENTS, PackedDouble, DisableAllocationSites);
505 CASE(HOLEY_DOUBLE_ELEMENTS, HoleyDouble, DisableAllocationSites);
514 Callable CodeFactory::InternalArrayNoArgumentConstructor(Isolate* isolate,
517 case PACKED_ELEMENTS:
519 BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Packed),
520 ArrayNoArgumentConstructorDescriptor{});
523 BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Holey),
524 ArrayNoArgumentConstructorDescriptor{});
531 Callable CodeFactory::InternalArraySingleArgumentConstructor(
532 Isolate* isolate, ElementsKind kind) {
534 case PACKED_ELEMENTS:
536 BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Packed),
537 ArraySingleArgumentConstructorDescriptor{});
540 BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Holey),
541 ArraySingleArgumentConstructorDescriptor{});