5 #include "src/compiler/js-generic-lowering.h" 7 #include "src/ast/ast.h" 8 #include "src/builtins/builtins-constructor.h" 9 #include "src/code-factory.h" 10 #include "src/code-stubs.h" 11 #include "src/compiler/common-operator.h" 12 #include "src/compiler/js-graph.h" 13 #include "src/compiler/machine-operator.h" 14 #include "src/compiler/node-matchers.h" 15 #include "src/compiler/node-properties.h" 16 #include "src/compiler/operator-properties.h" 17 #include "src/feedback-vector.h" 18 #include "src/objects/scope-info.h" 26 CallDescriptor::Flags FrameStateFlagForCall(Node* node) {
27 return OperatorProperties::HasFrameStateInput(node->op())
28 ? CallDescriptor::kNeedsFrameState
29 : CallDescriptor::kNoFlags;
34 JSGenericLowering::JSGenericLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
36 JSGenericLowering::~JSGenericLowering() =
default;
39 Reduction JSGenericLowering::Reduce(Node* node) {
40 switch (node->opcode()) {
41 #define DECLARE_CASE(x) \ 42 case IrOpcode::k##x: \ 45 JS_OP_LIST(DECLARE_CASE)
54 #define REPLACE_STUB_CALL(Name) \ 55 void JSGenericLowering::LowerJS##Name(Node* node) { \ 56 CallDescriptor::Flags flags = FrameStateFlagForCall(node); \ 57 Callable callable = Builtins::CallableFor(isolate(), Builtins::k##Name); \ 58 ReplaceWithStubCall(node, callable, flags); \ 60 REPLACE_STUB_CALL(Add)
61 REPLACE_STUB_CALL(Subtract)
62 REPLACE_STUB_CALL(Multiply)
63 REPLACE_STUB_CALL(Divide)
64 REPLACE_STUB_CALL(Modulus)
65 REPLACE_STUB_CALL(Exponentiate)
66 REPLACE_STUB_CALL(BitwiseAnd)
67 REPLACE_STUB_CALL(BitwiseOr)
68 REPLACE_STUB_CALL(BitwiseXor)
69 REPLACE_STUB_CALL(ShiftLeft)
70 REPLACE_STUB_CALL(ShiftRight)
71 REPLACE_STUB_CALL(ShiftRightLogical)
72 REPLACE_STUB_CALL(LessThan)
73 REPLACE_STUB_CALL(LessThanOrEqual)
74 REPLACE_STUB_CALL(GreaterThan)
75 REPLACE_STUB_CALL(GreaterThanOrEqual)
76 REPLACE_STUB_CALL(BitwiseNot)
77 REPLACE_STUB_CALL(Decrement)
78 REPLACE_STUB_CALL(Increment)
79 REPLACE_STUB_CALL(Negate)
80 REPLACE_STUB_CALL(HasProperty)
81 REPLACE_STUB_CALL(Equal)
82 REPLACE_STUB_CALL(ToLength)
83 REPLACE_STUB_CALL(ToNumber)
84 REPLACE_STUB_CALL(ToNumberConvertBigInt)
85 REPLACE_STUB_CALL(ToNumeric)
86 REPLACE_STUB_CALL(ToName)
87 REPLACE_STUB_CALL(ToObject)
88 REPLACE_STUB_CALL(ToString)
89 REPLACE_STUB_CALL(ForInEnumerate)
90 REPLACE_STUB_CALL(AsyncFunctionEnter)
91 REPLACE_STUB_CALL(AsyncFunctionReject)
92 REPLACE_STUB_CALL(AsyncFunctionResolve)
93 REPLACE_STUB_CALL(FulfillPromise)
94 REPLACE_STUB_CALL(PerformPromiseThen)
95 REPLACE_STUB_CALL(PromiseResolve)
96 REPLACE_STUB_CALL(RejectPromise)
97 REPLACE_STUB_CALL(ResolvePromise)
98 #undef REPLACE_STUB_CALL 100 void JSGenericLowering::ReplaceWithStubCall(Node* node,
102 CallDescriptor::Flags flags) {
103 ReplaceWithStubCall(node, callable, flags, node->op()->properties());
106 void JSGenericLowering::ReplaceWithStubCall(Node* node,
108 CallDescriptor::Flags flags,
109 Operator::Properties properties) {
110 const CallInterfaceDescriptor& descriptor = callable.descriptor();
111 auto call_descriptor = Linkage::GetStubCallDescriptor(
112 zone(), descriptor, descriptor.GetStackParameterCount(), flags,
114 Node* stub_code = jsgraph()->HeapConstant(callable.code());
115 node->InsertInput(zone(), 0, stub_code);
116 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
120 void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
121 Runtime::FunctionId f,
122 int nargs_override) {
123 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
124 Operator::Properties properties = node->op()->properties();
125 const Runtime::Function* fun = Runtime::FunctionForId(f);
126 int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
127 auto call_descriptor =
128 Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags);
129 Node* ref = jsgraph()->ExternalConstant(ExternalReference::Create(f));
130 Node* arity = jsgraph()->Int32Constant(nargs);
131 node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
132 node->InsertInput(zone(), nargs + 1, ref);
133 node->InsertInput(zone(), nargs + 2, arity);
134 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
137 void JSGenericLowering::LowerJSStrictEqual(Node* node) {
139 NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
140 Callable callable = Builtins::CallableFor(isolate(), Builtins::kStrictEqual);
141 node->RemoveInput(4);
142 ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags,
143 Operator::kEliminatable);
146 void JSGenericLowering::LowerJSLoadProperty(Node* node) {
147 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
148 const PropertyAccess& p = PropertyAccessOf(node->op());
149 Node* frame_state = NodeProperties::GetFrameStateInput(node);
150 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
151 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
152 if (outer_state->opcode() != IrOpcode::kFrameState) {
153 Callable callable = Builtins::CallableFor(
154 isolate(), p.feedback().ic_state() == MEGAMORPHIC
155 ? Builtins::kKeyedLoadICTrampoline_Megamorphic
156 : Builtins::kKeyedLoadICTrampoline);
157 ReplaceWithStubCall(node, callable, flags);
159 Callable callable = Builtins::CallableFor(
160 isolate(), p.feedback().ic_state() == MEGAMORPHIC
161 ? Builtins::kKeyedLoadIC_Megamorphic
162 : Builtins::kKeyedLoadIC);
163 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
164 node->InsertInput(zone(), 3, vector);
165 ReplaceWithStubCall(node, callable, flags);
169 void JSGenericLowering::LowerJSLoadNamed(Node* node) {
170 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
171 NamedAccess
const& p = NamedAccessOf(node->op());
172 Node* frame_state = NodeProperties::GetFrameStateInput(node);
173 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
174 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
175 if (!p.feedback().IsValid()) {
177 Builtins::CallableFor(isolate(), Builtins::kGetProperty);
178 ReplaceWithStubCall(node, callable, flags);
181 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
182 if (outer_state->opcode() != IrOpcode::kFrameState) {
183 Callable callable = Builtins::CallableFor(
184 isolate(), p.feedback().ic_state() == MEGAMORPHIC
185 ? Builtins::kLoadICTrampoline_Megamorphic
186 : Builtins::kLoadICTrampoline);
187 ReplaceWithStubCall(node, callable, flags);
190 Builtins::CallableFor(isolate(), p.feedback().ic_state() == MEGAMORPHIC
191 ? Builtins::kLoadIC_Megamorphic
192 : Builtins::kLoadIC);
193 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
194 node->InsertInput(zone(), 3, vector);
195 ReplaceWithStubCall(node, callable, flags);
199 void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
200 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
201 const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
202 Node* frame_state = NodeProperties::GetFrameStateInput(node);
203 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
204 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.name()));
205 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
206 if (outer_state->opcode() != IrOpcode::kFrameState) {
207 Callable callable = CodeFactory::LoadGlobalIC(isolate(), p.typeof_mode());
208 ReplaceWithStubCall(node, callable, flags);
211 CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode());
212 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
213 node->InsertInput(zone(), 2, vector);
214 ReplaceWithStubCall(node, callable, flags);
218 void JSGenericLowering::LowerJSStoreProperty(Node* node) {
219 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
220 PropertyAccess
const& p = PropertyAccessOf(node->op());
221 Node* frame_state = NodeProperties::GetFrameStateInput(node);
222 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
223 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
224 if (outer_state->opcode() != IrOpcode::kFrameState) {
226 Builtins::CallableFor(isolate(), Builtins::kKeyedStoreICTrampoline);
227 ReplaceWithStubCall(node, callable, flags);
230 Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC);
231 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
232 node->InsertInput(zone(), 4, vector);
233 ReplaceWithStubCall(node, callable, flags);
237 void JSGenericLowering::LowerJSStoreNamed(Node* node) {
238 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
239 NamedAccess
const& p = NamedAccessOf(node->op());
240 Node* frame_state = NodeProperties::GetFrameStateInput(node);
241 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
242 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
243 if (!p.feedback().IsValid()) {
245 zone(), 3, jsgraph()->SmiConstant(static_cast<int>(p.language_mode())));
246 ReplaceWithRuntimeCall(node, Runtime::kSetNamedProperty);
249 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
250 if (outer_state->opcode() != IrOpcode::kFrameState) {
252 Builtins::CallableFor(isolate(), Builtins::kStoreICTrampoline);
253 ReplaceWithStubCall(node, callable, flags);
255 Callable callable = Builtins::CallableFor(isolate(), Builtins::kStoreIC);
256 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
257 node->InsertInput(zone(), 4, vector);
258 ReplaceWithStubCall(node, callable, flags);
262 void JSGenericLowering::LowerJSStoreNamedOwn(Node* node) {
263 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
264 StoreNamedOwnParameters
const& p = StoreNamedOwnParametersOf(node->op());
265 Node* frame_state = NodeProperties::GetFrameStateInput(node);
266 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
267 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
268 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
269 if (outer_state->opcode() != IrOpcode::kFrameState) {
270 Callable callable = CodeFactory::StoreOwnIC(isolate());
271 ReplaceWithStubCall(node, callable, flags);
273 Callable callable = CodeFactory::StoreOwnICInOptimizedCode(isolate());
274 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
275 node->InsertInput(zone(), 4, vector);
276 ReplaceWithStubCall(node, callable, flags);
280 void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
281 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
282 const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
283 Node* frame_state = NodeProperties::GetFrameStateInput(node);
284 Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
285 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.name()));
286 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
287 if (outer_state->opcode() != IrOpcode::kFrameState) {
289 Builtins::CallableFor(isolate(), Builtins::kStoreGlobalICTrampoline);
290 ReplaceWithStubCall(node, callable, flags);
293 Builtins::CallableFor(isolate(), Builtins::kStoreGlobalIC);
294 Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
295 node->InsertInput(zone(), 3, vector);
296 ReplaceWithStubCall(node, callable, flags);
300 void JSGenericLowering::LowerJSStoreDataPropertyInLiteral(Node* node) {
301 FeedbackParameter
const& p = FeedbackParameterOf(node->op());
302 node->InsertInputs(zone(), 4, 2);
303 node->ReplaceInput(4, jsgraph()->HeapConstant(p.feedback().vector()));
304 node->ReplaceInput(5, jsgraph()->SmiConstant(p.feedback().index()));
305 ReplaceWithRuntimeCall(node, Runtime::kDefineDataPropertyInLiteral);
308 void JSGenericLowering::LowerJSStoreInArrayLiteral(Node* node) {
310 Builtins::CallableFor(isolate(), Builtins::kStoreInArrayLiteralIC);
311 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
312 FeedbackParameter
const& p = FeedbackParameterOf(node->op());
313 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
314 node->InsertInput(zone(), 4, jsgraph()->HeapConstant(p.feedback().vector()));
315 ReplaceWithStubCall(node, callable, flags);
318 void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
319 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
321 Builtins::CallableFor(isolate(), Builtins::kDeleteProperty);
322 ReplaceWithStubCall(node, callable, flags);
325 void JSGenericLowering::LowerJSGetSuperConstructor(Node* node) {
326 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
328 Builtins::CallableFor(isolate(), Builtins::kGetSuperConstructor);
329 ReplaceWithStubCall(node, callable, flags);
332 void JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) {
333 ReplaceWithRuntimeCall(node, Runtime::kHasInPrototypeChain);
336 void JSGenericLowering::LowerJSInstanceOf(Node* node) {
337 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
338 Callable callable = Builtins::CallableFor(isolate(), Builtins::kInstanceOf);
339 ReplaceWithStubCall(node, callable, flags);
342 void JSGenericLowering::LowerJSOrdinaryHasInstance(Node* node) {
343 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
345 Builtins::CallableFor(isolate(), Builtins::kOrdinaryHasInstance);
346 ReplaceWithStubCall(node, callable, flags);
349 void JSGenericLowering::LowerJSLoadContext(Node* node) {
354 void JSGenericLowering::LowerJSStoreContext(Node* node) {
359 void JSGenericLowering::LowerJSCreate(Node* node) {
360 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
362 Builtins::CallableFor(isolate(), Builtins::kFastNewObject);
363 ReplaceWithStubCall(node, callable, flags);
367 void JSGenericLowering::LowerJSCreateArguments(Node* node) {
368 CreateArgumentsType
const type = CreateArgumentsTypeOf(node->op());
370 case CreateArgumentsType::kMappedArguments:
371 ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments_Generic);
373 case CreateArgumentsType::kUnmappedArguments:
374 ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments);
376 case CreateArgumentsType::kRestParameter:
377 ReplaceWithRuntimeCall(node, Runtime::kNewRestParameter);
383 void JSGenericLowering::LowerJSCreateArray(Node* node) {
384 CreateArrayParameters
const& p = CreateArrayParametersOf(node->op());
385 int const arity =
static_cast<int>(p.arity());
386 auto call_descriptor = Linkage::GetStubCallDescriptor(
387 zone(), ArrayConstructorDescriptor{}, arity + 1,
388 CallDescriptor::kNeedsFrameState, node->op()->properties());
389 Node* stub_code = jsgraph()->ArrayConstructorStubConstant();
390 Node* stub_arity = jsgraph()->Int32Constant(arity);
391 MaybeHandle<AllocationSite>
const maybe_site = p.site();
392 Handle<AllocationSite> site;
393 Node* type_info = maybe_site.ToHandle(&site) ? jsgraph()->HeapConstant(site)
394 : jsgraph()->UndefinedConstant();
395 Node* receiver = jsgraph()->UndefinedConstant();
396 node->InsertInput(zone(), 0, stub_code);
397 node->InsertInput(zone(), 3, stub_arity);
398 node->InsertInput(zone(), 4, type_info);
399 node->InsertInput(zone(), 5, receiver);
400 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
403 void JSGenericLowering::LowerJSCreateArrayIterator(Node* node) {
407 void JSGenericLowering::LowerJSCreateAsyncFunctionObject(Node* node) {
411 void JSGenericLowering::LowerJSCreateCollectionIterator(Node* node) {
415 void JSGenericLowering::LowerJSCreateBoundFunction(Node* node) {
419 void JSGenericLowering::LowerJSObjectIsArray(Node* node) {
423 void JSGenericLowering::LowerJSCreateObject(Node* node) {
424 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
425 Callable callable = Builtins::CallableFor(
426 isolate(), Builtins::kCreateObjectWithoutProperties);
427 ReplaceWithStubCall(node, callable, flags);
430 void JSGenericLowering::LowerJSParseInt(Node* node) {
431 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
432 Callable callable = Builtins::CallableFor(isolate(), Builtins::kParseInt);
433 ReplaceWithStubCall(node, callable, flags);
436 void JSGenericLowering::LowerJSRegExpTest(Node* node) {
437 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
439 Builtins::CallableFor(isolate(), Builtins::kRegExpPrototypeTestFast);
440 ReplaceWithStubCall(node, callable, flags);
443 void JSGenericLowering::LowerJSCreateClosure(Node* node) {
444 CreateClosureParameters
const& p = CreateClosureParametersOf(node->op());
445 Handle<SharedFunctionInfo>
const shared_info = p.shared_info();
446 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(shared_info));
447 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.feedback_cell()));
448 node->RemoveInput(4);
451 if (p.pretenure() == NOT_TENURED) {
453 Builtins::CallableFor(isolate(), Builtins::kFastNewClosure);
454 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
455 ReplaceWithStubCall(node, callable, flags);
457 ReplaceWithRuntimeCall(node, Runtime::kNewClosure_Tenured);
462 void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
463 const CreateFunctionContextParameters& parameters =
464 CreateFunctionContextParametersOf(node->op());
465 Handle<ScopeInfo> scope_info = parameters.scope_info();
466 int slot_count = parameters.slot_count();
467 ScopeType scope_type = parameters.scope_type();
468 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
470 if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) {
472 CodeFactory::FastNewFunctionContext(isolate(), scope_type);
473 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
474 node->InsertInput(zone(), 1, jsgraph()->Int32Constant(slot_count));
475 ReplaceWithStubCall(node, callable, flags);
477 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
478 ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext);
482 void JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) {
483 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
485 Builtins::CallableFor(isolate(), Builtins::kCreateGeneratorObject);
486 node->RemoveInput(4);
487 ReplaceWithStubCall(node, callable, flags);
490 void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
494 void JSGenericLowering::LowerJSCreateStringIterator(Node* node) {
498 void JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) {
502 void JSGenericLowering::LowerJSCreatePromise(Node* node) {
506 void JSGenericLowering::LowerJSCreateTypedArray(Node* node) {
507 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
509 Builtins::CallableFor(isolate(), Builtins::kCreateTypedArray);
510 ReplaceWithStubCall(node, callable, flags);
513 void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
514 CreateLiteralParameters
const& p = CreateLiteralParametersOf(node->op());
515 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
516 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
517 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
518 node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
522 if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
523 p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
525 Builtins::CallableFor(isolate(), Builtins::kCreateShallowArrayLiteral);
526 ReplaceWithStubCall(node, callable, flags);
528 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
529 ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
533 void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
534 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
535 FeedbackParameter
const& p = FeedbackParameterOf(node->op());
536 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
537 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
538 node->RemoveInput(4);
540 Builtins::CallableFor(isolate(), Builtins::kCreateEmptyArrayLiteral);
541 ReplaceWithStubCall(node, callable, flags);
544 void JSGenericLowering::LowerJSCreateArrayFromIterable(Node* node) {
545 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
546 Callable callable = Builtins::CallableFor(
547 isolate(), Builtins::kIterableToListWithSymbolLookup);
548 ReplaceWithStubCall(node, callable, flags);
551 void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
552 CreateLiteralParameters
const& p = CreateLiteralParametersOf(node->op());
553 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
554 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
555 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
556 node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
557 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
561 if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
563 ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
565 Builtins::CallableFor(isolate(), Builtins::kCreateShallowObjectLiteral);
566 ReplaceWithStubCall(node, callable, flags);
568 ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
572 void JSGenericLowering::LowerJSCloneObject(Node* node) {
573 CloneObjectParameters
const& p = CloneObjectParametersOf(node->op());
574 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
576 Builtins::CallableFor(isolate(), Builtins::kCloneObjectIC);
577 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.flags()));
578 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
579 node->InsertInput(zone(), 3, jsgraph()->HeapConstant(p.feedback().vector()));
580 ReplaceWithStubCall(node, callable, flags);
583 void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
587 void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
588 CreateLiteralParameters
const& p = CreateLiteralParametersOf(node->op());
589 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
591 Builtins::CallableFor(isolate(), Builtins::kCreateRegExpLiteral);
592 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
593 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
594 node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
595 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
596 ReplaceWithStubCall(node, callable, flags);
600 void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
604 void JSGenericLowering::LowerJSCreateWithContext(Node* node) {
608 void JSGenericLowering::LowerJSCreateBlockContext(Node* node) {
609 Handle<ScopeInfo> scope_info = ScopeInfoOf(node->op());
610 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
611 ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext);
614 void JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) {
615 ConstructForwardVarargsParameters p =
616 ConstructForwardVarargsParametersOf(node->op());
617 int const arg_count =
static_cast<int>(p.arity() - 2);
618 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
619 Callable callable = CodeFactory::ConstructForwardVarargs(isolate());
620 auto call_descriptor = Linkage::GetStubCallDescriptor(
621 zone(), callable.descriptor(), arg_count + 1, flags);
622 Node* stub_code = jsgraph()->HeapConstant(callable.code());
623 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
624 Node* start_index = jsgraph()->Uint32Constant(p.start_index());
625 Node* new_target = node->InputAt(arg_count + 1);
626 Node* receiver = jsgraph()->UndefinedConstant();
627 node->RemoveInput(arg_count + 1);
628 node->InsertInput(zone(), 0, stub_code);
629 node->InsertInput(zone(), 2, new_target);
630 node->InsertInput(zone(), 3, stub_arity);
631 node->InsertInput(zone(), 4, start_index);
632 node->InsertInput(zone(), 5, receiver);
633 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
636 void JSGenericLowering::LowerJSConstruct(Node* node) {
637 ConstructParameters
const& p = ConstructParametersOf(node->op());
638 int const arg_count =
static_cast<int>(p.arity() - 2);
639 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
640 Callable callable = CodeFactory::Construct(isolate());
641 auto call_descriptor = Linkage::GetStubCallDescriptor(
642 zone(), callable.descriptor(), arg_count + 1, flags);
643 Node* stub_code = jsgraph()->HeapConstant(callable.code());
644 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
645 Node* new_target = node->InputAt(arg_count + 1);
646 Node* receiver = jsgraph()->UndefinedConstant();
647 node->RemoveInput(arg_count + 1);
648 node->InsertInput(zone(), 0, stub_code);
649 node->InsertInput(zone(), 2, new_target);
650 node->InsertInput(zone(), 3, stub_arity);
651 node->InsertInput(zone(), 4, receiver);
652 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
655 void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) {
657 Builtins::CallableFor(isolate(), Builtins::kConstructWithArrayLike);
658 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
659 auto call_descriptor =
660 Linkage::GetStubCallDescriptor(zone(), callable.descriptor(), 1, flags);
661 Node* stub_code = jsgraph()->HeapConstant(callable.code());
662 Node* receiver = jsgraph()->UndefinedConstant();
663 Node* arguments_list = node->InputAt(1);
664 Node* new_target = node->InputAt(2);
665 node->InsertInput(zone(), 0, stub_code);
666 node->ReplaceInput(2, new_target);
667 node->ReplaceInput(3, arguments_list);
668 node->InsertInput(zone(), 4, receiver);
669 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
672 void JSGenericLowering::LowerJSConstructWithSpread(Node* node) {
673 ConstructParameters
const& p = ConstructParametersOf(node->op());
674 int const arg_count =
static_cast<int>(p.arity() - 2);
675 int const spread_index = arg_count;
676 int const new_target_index = arg_count + 1;
677 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
678 Callable callable = CodeFactory::ConstructWithSpread(isolate());
679 auto call_descriptor = Linkage::GetStubCallDescriptor(
680 zone(), callable.descriptor(), arg_count, flags);
681 Node* stub_code = jsgraph()->HeapConstant(callable.code());
682 Node* stack_arg_count = jsgraph()->Int32Constant(arg_count - 1);
683 Node* new_target = node->InputAt(new_target_index);
684 Node* spread = node->InputAt(spread_index);
685 Node* receiver = jsgraph()->UndefinedConstant();
686 DCHECK(new_target_index > spread_index);
687 node->RemoveInput(new_target_index);
688 node->RemoveInput(spread_index);
690 node->InsertInput(zone(), 0, stub_code);
691 node->InsertInput(zone(), 2, new_target);
692 node->InsertInput(zone(), 3, stack_arg_count);
693 node->InsertInput(zone(), 4, spread);
694 node->InsertInput(zone(), 5, receiver);
695 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
698 void JSGenericLowering::LowerJSCallForwardVarargs(Node* node) {
699 CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op());
700 int const arg_count =
static_cast<int>(p.arity() - 2);
701 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
702 Callable callable = CodeFactory::CallForwardVarargs(isolate());
703 auto call_descriptor = Linkage::GetStubCallDescriptor(
704 zone(), callable.descriptor(), arg_count + 1, flags);
705 Node* stub_code = jsgraph()->HeapConstant(callable.code());
706 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
707 Node* start_index = jsgraph()->Uint32Constant(p.start_index());
708 node->InsertInput(zone(), 0, stub_code);
709 node->InsertInput(zone(), 2, stub_arity);
710 node->InsertInput(zone(), 3, start_index);
711 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
714 void JSGenericLowering::LowerJSCall(Node* node) {
715 CallParameters
const& p = CallParametersOf(node->op());
716 int const arg_count =
static_cast<int>(p.arity() - 2);
717 ConvertReceiverMode
const mode = p.convert_mode();
718 Callable callable = CodeFactory::Call(isolate(), mode);
719 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
720 auto call_descriptor = Linkage::GetStubCallDescriptor(
721 zone(), callable.descriptor(), arg_count + 1, flags);
722 Node* stub_code = jsgraph()->HeapConstant(callable.code());
723 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
724 node->InsertInput(zone(), 0, stub_code);
725 node->InsertInput(zone(), 2, stub_arity);
726 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
729 void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) {
730 Callable callable = CodeFactory::CallWithArrayLike(isolate());
731 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
732 auto call_descriptor =
733 Linkage::GetStubCallDescriptor(zone(), callable.descriptor(), 1, flags);
734 Node* stub_code = jsgraph()->HeapConstant(callable.code());
735 Node* receiver = node->InputAt(1);
736 Node* arguments_list = node->InputAt(2);
737 node->InsertInput(zone(), 0, stub_code);
738 node->ReplaceInput(3, receiver);
739 node->ReplaceInput(2, arguments_list);
740 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
743 void JSGenericLowering::LowerJSCallWithSpread(Node* node) {
744 CallParameters
const& p = CallParametersOf(node->op());
745 int const arg_count =
static_cast<int>(p.arity() - 2);
746 int const spread_index =
static_cast<int>(p.arity() + 1);
747 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
748 Callable callable = CodeFactory::CallWithSpread(isolate());
749 auto call_descriptor = Linkage::GetStubCallDescriptor(
750 zone(), callable.descriptor(), arg_count, flags);
751 Node* stub_code = jsgraph()->HeapConstant(callable.code());
753 Node* stack_arg_count = jsgraph()->Int32Constant(arg_count - 1);
754 node->InsertInput(zone(), 0, stub_code);
755 node->InsertInput(zone(), 2, stack_arg_count);
756 node->InsertInput(zone(), 3, node->InputAt(spread_index));
757 node->RemoveInput(spread_index + 1);
758 NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
761 void JSGenericLowering::LowerJSCallRuntime(Node* node) {
762 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
763 ReplaceWithRuntimeCall(node, p.id(),
static_cast<int>(p.arity()));
766 void JSGenericLowering::LowerJSForInNext(Node* node) {
770 void JSGenericLowering::LowerJSForInPrepare(Node* node) {
774 void JSGenericLowering::LowerJSLoadMessage(Node* node) {
779 void JSGenericLowering::LowerJSStoreMessage(Node* node) {
783 void JSGenericLowering::LowerJSLoadModule(Node* node) {
787 void JSGenericLowering::LowerJSStoreModule(Node* node) {
791 void JSGenericLowering::LowerJSGeneratorStore(Node* node) {
795 void JSGenericLowering::LowerJSGeneratorRestoreContinuation(Node* node) {
799 void JSGenericLowering::LowerJSGeneratorRestoreContext(Node* node) {
803 void JSGenericLowering::LowerJSGeneratorRestoreInputOrDebugPos(Node* node) {
807 void JSGenericLowering::LowerJSGeneratorRestoreRegister(Node* node) {
811 void JSGenericLowering::LowerJSStackCheck(Node* node) {
812 Node* effect = NodeProperties::GetEffectInput(node);
813 Node* control = NodeProperties::GetControlInput(node);
815 Node* limit = effect = graph()->NewNode(
816 machine()->Load(MachineType::Pointer()),
817 jsgraph()->ExternalConstant(
818 ExternalReference::address_of_stack_limit(isolate())),
819 jsgraph()->IntPtrConstant(0), effect, control);
820 Node* pointer = graph()->NewNode(machine()->LoadStackPointer());
822 Node* check = graph()->NewNode(machine()->UintLessThan(), limit, pointer);
824 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
826 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
827 Node* etrue = effect;
829 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
830 NodeProperties::ReplaceControlInput(node, if_false);
831 NodeProperties::ReplaceEffectInput(node, effect);
832 Node* efalse = if_false = node;
834 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
835 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
838 NodeProperties::ReplaceUses(node, node, ephi, merge, merge);
839 NodeProperties::ReplaceControlInput(merge, if_false, 1);
840 NodeProperties::ReplaceEffectInput(ephi, efalse, 1);
845 for (Edge edge : merge->use_edges()) {
846 if (!NodeProperties::IsControlEdge(edge))
continue;
847 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
848 NodeProperties::ReplaceUses(edge.from(),
nullptr,
nullptr, merge);
849 NodeProperties::ReplaceControlInput(merge, edge.from(), 1);
852 if (edge.from()->opcode() == IrOpcode::kIfException) {
853 NodeProperties::ReplaceEffectInput(edge.from(), node);
859 ReplaceWithRuntimeCall(node, Runtime::kStackGuard);
862 void JSGenericLowering::LowerJSDebugger(Node* node) {
863 CallDescriptor::Flags flags = FrameStateFlagForCall(node);
864 Callable callable = CodeFactory::HandleDebuggerStatement(isolate());
865 ReplaceWithStubCall(node, callable, flags);
868 Zone* JSGenericLowering::zone()
const {
return graph()->zone(); }
871 Isolate* JSGenericLowering::isolate()
const {
return jsgraph()->isolate(); }
874 Graph* JSGenericLowering::graph()
const {
return jsgraph()->graph(); }
877 CommonOperatorBuilder* JSGenericLowering::common()
const {
878 return jsgraph()->common();
882 MachineOperatorBuilder* JSGenericLowering::machine()
const {
883 return jsgraph()->machine();