Line data Source code
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/compiler/js-generic-lowering.h"
6 :
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 :
18 : namespace v8 {
19 : namespace internal {
20 : namespace compiler {
21 :
22 : namespace {
23 :
24 3230176 : CallDescriptor::Flags FrameStateFlagForCall(Node* node) {
25 3230176 : return OperatorProperties::HasFrameStateInput(node->op())
26 : ? CallDescriptor::kNeedsFrameState
27 3230181 : : CallDescriptor::kNoFlags;
28 : }
29 :
30 : } // namespace
31 :
32 886720 : JSGenericLowering::JSGenericLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
33 :
34 886714 : JSGenericLowering::~JSGenericLowering() {}
35 :
36 :
37 43099527 : Reduction JSGenericLowering::Reduce(Node* node) {
38 43099527 : switch (node->opcode()) {
39 : #define DECLARE_CASE(x) \
40 : case IrOpcode::k##x: \
41 : Lower##x(node); \
42 : break;
43 11860 : JS_OP_LIST(DECLARE_CASE)
44 : #undef DECLARE_CASE
45 : default:
46 : // Nothing to see.
47 : return NoChange();
48 : }
49 : return Changed(node);
50 : }
51 :
52 : #define REPLACE_STUB_CALL(Name) \
53 : void JSGenericLowering::LowerJS##Name(Node* node) { \
54 : CallDescriptor::Flags flags = FrameStateFlagForCall(node); \
55 : Callable callable = Builtins::CallableFor(isolate(), Builtins::k##Name); \
56 : ReplaceWithStubCall(node, callable, flags); \
57 : }
58 126308 : REPLACE_STUB_CALL(Add)
59 49108 : REPLACE_STUB_CALL(Subtract)
60 25724 : REPLACE_STUB_CALL(Multiply)
61 36824 : REPLACE_STUB_CALL(Divide)
62 1756 : REPLACE_STUB_CALL(Modulus)
63 23048 : REPLACE_STUB_CALL(BitwiseAnd)
64 25452 : REPLACE_STUB_CALL(BitwiseOr)
65 580 : REPLACE_STUB_CALL(BitwiseXor)
66 472 : REPLACE_STUB_CALL(ShiftLeft)
67 3580 : REPLACE_STUB_CALL(ShiftRight)
68 3196 : REPLACE_STUB_CALL(ShiftRightLogical)
69 77764 : REPLACE_STUB_CALL(LessThan)
70 4624 : REPLACE_STUB_CALL(LessThanOrEqual)
71 24980 : REPLACE_STUB_CALL(GreaterThan)
72 8808 : REPLACE_STUB_CALL(GreaterThanOrEqual)
73 15732 : REPLACE_STUB_CALL(HasProperty)
74 32972 : REPLACE_STUB_CALL(Equal)
75 700 : REPLACE_STUB_CALL(ToInteger)
76 3360 : REPLACE_STUB_CALL(ToLength)
77 29068 : REPLACE_STUB_CALL(ToNumber)
78 3692 : REPLACE_STUB_CALL(ToName)
79 0 : REPLACE_STUB_CALL(ToObject)
80 11444 : REPLACE_STUB_CALL(ToString)
81 6308 : REPLACE_STUB_CALL(ForInEnumerate)
82 : #undef REPLACE_STUB_CALL
83 :
84 1784644 : void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
85 : CallDescriptor::Flags flags) {
86 1784644 : ReplaceWithStubCall(node, callable, flags, node->op()->properties());
87 1784644 : }
88 :
89 1869944 : void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
90 : CallDescriptor::Flags flags,
91 : Operator::Properties properties,
92 1869945 : int result_size) {
93 : const CallInterfaceDescriptor& descriptor = callable.descriptor();
94 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
95 : isolate(), zone(), descriptor, descriptor.GetStackParameterCount(), flags,
96 3739888 : properties, MachineType::AnyTagged(), result_size);
97 1869945 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
98 1869946 : node->InsertInput(zone(), 0, stub_code);
99 1869946 : NodeProperties::ChangeOp(node, common()->Call(desc));
100 1869945 : }
101 :
102 :
103 1983484 : void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
104 : Runtime::FunctionId f,
105 2975235 : int nargs_override) {
106 991744 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
107 991744 : Operator::Properties properties = node->op()->properties();
108 991744 : const Runtime::Function* fun = Runtime::FunctionForId(f);
109 991741 : int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
110 : CallDescriptor* desc =
111 991741 : Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags);
112 1983490 : Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
113 991745 : Node* arity = jsgraph()->Int32Constant(nargs);
114 2975232 : node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
115 1983488 : node->InsertInput(zone(), nargs + 1, ref);
116 1983490 : node->InsertInput(zone(), nargs + 2, arity);
117 991745 : NodeProperties::ChangeOp(node, common()->Call(desc));
118 991745 : }
119 :
120 85301 : void JSGenericLowering::LowerJSStrictEqual(Node* node) {
121 : // The === operator doesn't need the current context.
122 85301 : NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
123 85301 : Callable callable = Builtins::CallableFor(isolate(), Builtins::kStrictEqual);
124 85301 : node->RemoveInput(4); // control
125 : ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags,
126 85301 : Operator::kEliminatable);
127 85301 : }
128 :
129 157470 : void JSGenericLowering::LowerJSLoadProperty(Node* node) {
130 52016 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
131 52016 : const PropertyAccess& p = PropertyAccessOf(node->op());
132 52016 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
133 52016 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
134 104032 : node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
135 52016 : if (outer_state->opcode() != IrOpcode::kFrameState) {
136 : Callable callable =
137 50594 : Builtins::CallableFor(isolate(), Builtins::kKeyedLoadICTrampoline);
138 50594 : ReplaceWithStubCall(node, callable, flags);
139 : } else {
140 : Callable callable =
141 1422 : Builtins::CallableFor(isolate(), Builtins::kKeyedLoadIC);
142 1422 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
143 1422 : node->InsertInput(zone(), 3, vector);
144 1422 : ReplaceWithStubCall(node, callable, flags);
145 : }
146 52016 : }
147 :
148 1978346 : void JSGenericLowering::LowerJSLoadNamed(Node* node) {
149 493973 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
150 493973 : NamedAccess const& p = NamedAccessOf(node->op());
151 493973 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
152 493973 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
153 987945 : node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
154 987946 : node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
155 493973 : if (outer_state->opcode() != IrOpcode::kFrameState) {
156 : Callable callable =
157 491519 : Builtins::CallableFor(isolate(), Builtins::kLoadICTrampoline);
158 491519 : ReplaceWithStubCall(node, callable, flags);
159 : } else {
160 2454 : Callable callable = Builtins::CallableFor(isolate(), Builtins::kLoadIC);
161 2454 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
162 2454 : node->InsertInput(zone(), 3, vector);
163 : ReplaceWithStubCall(node, callable, flags);
164 : }
165 493973 : }
166 :
167 :
168 394336 : void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
169 98568 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
170 197136 : const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
171 98568 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
172 98568 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
173 197136 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.name()));
174 197136 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
175 98568 : if (outer_state->opcode() != IrOpcode::kFrameState) {
176 98504 : Callable callable = CodeFactory::LoadGlobalIC(isolate(), p.typeof_mode());
177 98504 : ReplaceWithStubCall(node, callable, flags);
178 : } else {
179 : Callable callable =
180 64 : CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode());
181 64 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
182 64 : node->InsertInput(zone(), 2, vector);
183 64 : ReplaceWithStubCall(node, callable, flags);
184 : }
185 98568 : }
186 :
187 168630 : void JSGenericLowering::LowerJSStoreProperty(Node* node) {
188 56180 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
189 56180 : PropertyAccess const& p = PropertyAccessOf(node->op());
190 56180 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
191 56180 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
192 112360 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
193 56180 : if (outer_state->opcode() != IrOpcode::kFrameState) {
194 : Callable callable =
195 56090 : Builtins::CallableFor(isolate(), Builtins::kKeyedStoreICTrampoline);
196 56090 : ReplaceWithStubCall(node, callable, flags);
197 : } else {
198 : Callable callable =
199 90 : Builtins::CallableFor(isolate(), Builtins::kKeyedStoreIC);
200 90 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
201 90 : node->InsertInput(zone(), 4, vector);
202 90 : ReplaceWithStubCall(node, callable, flags);
203 : }
204 56180 : }
205 :
206 987283 : void JSGenericLowering::LowerJSStoreNamed(Node* node) {
207 246808 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
208 246808 : NamedAccess const& p = NamedAccessOf(node->op());
209 246808 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
210 246808 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
211 493616 : node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
212 493616 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
213 246808 : if (outer_state->opcode() != IrOpcode::kFrameState) {
214 : Callable callable =
215 246757 : Builtins::CallableFor(isolate(), Builtins::kStoreICTrampoline);
216 246757 : ReplaceWithStubCall(node, callable, flags);
217 : } else {
218 51 : Callable callable = Builtins::CallableFor(isolate(), Builtins::kStoreIC);
219 51 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
220 51 : node->InsertInput(zone(), 4, vector);
221 51 : ReplaceWithStubCall(node, callable, flags);
222 : }
223 246808 : }
224 :
225 177069 : void JSGenericLowering::LowerJSStoreNamedOwn(Node* node) {
226 44252 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
227 44252 : StoreNamedOwnParameters const& p = StoreNamedOwnParametersOf(node->op());
228 44252 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
229 44252 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
230 88504 : node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
231 88504 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
232 44252 : if (outer_state->opcode() != IrOpcode::kFrameState) {
233 44191 : Callable callable = CodeFactory::StoreOwnIC(isolate());
234 44191 : ReplaceWithStubCall(node, callable, flags);
235 : } else {
236 61 : Callable callable = CodeFactory::StoreOwnICInOptimizedCode(isolate());
237 61 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
238 61 : node->InsertInput(zone(), 4, vector);
239 61 : ReplaceWithStubCall(node, callable, flags);
240 : }
241 44252 : }
242 :
243 900746 : void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
244 150123 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
245 300246 : const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
246 150123 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
247 150123 : Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
248 150123 : Node* context = NodeProperties::GetContextInput(node);
249 150123 : Node* effect = NodeProperties::GetEffectInput(node);
250 150123 : Node* control = NodeProperties::GetControlInput(node);
251 : // Load global object from the context.
252 : Node* native_context = effect =
253 : graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
254 : jsgraph()->IntPtrConstant(
255 : Context::SlotOffset(Context::NATIVE_CONTEXT_INDEX)),
256 300246 : effect, control);
257 : Node* global = effect = graph()->NewNode(
258 : machine()->Load(MachineType::AnyTagged()), native_context,
259 : jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
260 300246 : effect, control);
261 150123 : NodeProperties::ReplaceEffectInput(node, effect);
262 150123 : node->InsertInput(zone(), 0, global);
263 300246 : node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
264 300246 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
265 150123 : if (outer_state->opcode() != IrOpcode::kFrameState) {
266 : Callable callable =
267 150115 : CodeFactory::StoreGlobalIC(isolate(), p.language_mode());
268 150115 : ReplaceWithStubCall(node, callable, flags);
269 : } else {
270 : Callable callable =
271 8 : CodeFactory::StoreGlobalICInOptimizedCode(isolate(), p.language_mode());
272 8 : Node* vector = jsgraph()->HeapConstant(p.feedback().vector());
273 8 : node->InsertInput(zone(), 4, vector);
274 8 : ReplaceWithStubCall(node, callable, flags);
275 : }
276 150123 : }
277 :
278 165108 : void JSGenericLowering::LowerJSStoreDataPropertyInLiteral(Node* node) {
279 55036 : FeedbackParameter const& p = FeedbackParameterOf(node->op());
280 55036 : node->InsertInputs(zone(), 4, 2);
281 55036 : node->ReplaceInput(4, jsgraph()->HeapConstant(p.feedback().vector()));
282 110072 : node->ReplaceInput(5, jsgraph()->SmiConstant(p.feedback().index()));
283 55036 : ReplaceWithRuntimeCall(node, Runtime::kDefineDataPropertyInLiteral);
284 55036 : }
285 :
286 1842 : void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
287 1842 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
288 : Callable callable =
289 1842 : Builtins::CallableFor(isolate(), Builtins::kDeleteProperty);
290 1842 : ReplaceWithStubCall(node, callable, flags);
291 1842 : }
292 :
293 56 : void JSGenericLowering::LowerJSGetSuperConstructor(Node* node) {
294 56 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
295 : Callable callable =
296 56 : Builtins::CallableFor(isolate(), Builtins::kGetSuperConstructor);
297 56 : ReplaceWithStubCall(node, callable, flags);
298 56 : }
299 :
300 0 : void JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) {
301 0 : ReplaceWithRuntimeCall(node, Runtime::kHasInPrototypeChain);
302 0 : }
303 :
304 2040 : void JSGenericLowering::LowerJSInstanceOf(Node* node) {
305 2040 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
306 2040 : Callable callable = Builtins::CallableFor(isolate(), Builtins::kInstanceOf);
307 2040 : ReplaceWithStubCall(node, callable, flags);
308 2040 : }
309 :
310 51 : void JSGenericLowering::LowerJSOrdinaryHasInstance(Node* node) {
311 51 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
312 : Callable callable =
313 51 : Builtins::CallableFor(isolate(), Builtins::kOrdinaryHasInstance);
314 51 : ReplaceWithStubCall(node, callable, flags);
315 51 : }
316 :
317 0 : void JSGenericLowering::LowerJSLoadContext(Node* node) {
318 0 : UNREACHABLE(); // Eliminated in typed lowering.
319 : }
320 :
321 :
322 0 : void JSGenericLowering::LowerJSStoreContext(Node* node) {
323 0 : UNREACHABLE(); // Eliminated in typed lowering.
324 : }
325 :
326 :
327 2073 : void JSGenericLowering::LowerJSCreate(Node* node) {
328 2073 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
329 : Callable callable =
330 2073 : Builtins::CallableFor(isolate(), Builtins::kFastNewObject);
331 2073 : ReplaceWithStubCall(node, callable, flags);
332 2073 : }
333 :
334 :
335 6 : void JSGenericLowering::LowerJSCreateArguments(Node* node) {
336 6 : CreateArgumentsType const type = CreateArgumentsTypeOf(node->op());
337 6 : switch (type) {
338 : case CreateArgumentsType::kMappedArguments:
339 6 : ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments_Generic);
340 6 : break;
341 : case CreateArgumentsType::kUnmappedArguments:
342 0 : ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments);
343 0 : break;
344 : case CreateArgumentsType::kRestParameter:
345 0 : ReplaceWithRuntimeCall(node, Runtime::kNewRestParameter);
346 0 : break;
347 : }
348 6 : }
349 :
350 :
351 132 : void JSGenericLowering::LowerJSCreateArray(Node* node) {
352 22 : CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
353 22 : int const arity = static_cast<int>(p.arity());
354 : Handle<AllocationSite> const site = p.site();
355 22 : ArrayConstructorDescriptor descriptor(isolate());
356 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
357 : isolate(), zone(), descriptor, arity + 1,
358 : CallDescriptor::kNeedsFrameState, node->op()->properties(),
359 44 : MachineType::AnyTagged());
360 22 : Node* stub_code = jsgraph()->ArrayConstructorStubConstant();
361 22 : Node* stub_arity = jsgraph()->Int32Constant(arity);
362 : Node* type_info = site.is_null() ? jsgraph()->UndefinedConstant()
363 44 : : jsgraph()->HeapConstant(site);
364 22 : Node* receiver = jsgraph()->UndefinedConstant();
365 22 : node->InsertInput(zone(), 0, stub_code);
366 22 : node->InsertInput(zone(), 3, stub_arity);
367 22 : node->InsertInput(zone(), 4, type_info);
368 22 : node->InsertInput(zone(), 5, receiver);
369 22 : NodeProperties::ChangeOp(node, common()->Call(desc));
370 22 : }
371 :
372 0 : void JSGenericLowering::LowerJSCreateBoundFunction(Node* node) {
373 0 : UNREACHABLE(); // Eliminated in typed lowering.
374 : }
375 :
376 2334609 : void JSGenericLowering::LowerJSCreateClosure(Node* node) {
377 1336511 : CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
378 583653 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
379 : Handle<SharedFunctionInfo> const shared_info = p.shared_info();
380 1167306 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(shared_info));
381 583653 : node->RemoveInput(3); // control
382 :
383 : // Use the FastNewClosure builtin only for functions allocated in new space.
384 583653 : if (p.pretenure() == NOT_TENURED) {
385 : Callable callable =
386 414446 : Builtins::CallableFor(isolate(), Builtins::kFastNewClosure);
387 : node->InsertInput(zone(), 1,
388 828891 : jsgraph()->HeapConstant(p.feedback().vector()));
389 828891 : node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
390 414446 : ReplaceWithStubCall(node, callable, flags);
391 : } else {
392 : node->InsertInput(zone(), 1,
393 338414 : jsgraph()->HeapConstant(p.feedback().vector()));
394 338414 : node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
395 : ReplaceWithRuntimeCall(node, (p.pretenure() == TENURED)
396 : ? Runtime::kNewClosure_Tenured
397 169207 : : Runtime::kNewClosure);
398 : }
399 583653 : }
400 :
401 :
402 10982 : void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
403 5491 : const CreateFunctionContextParameters& parameters =
404 5491 : CreateFunctionContextParametersOf(node->op());
405 : int slot_count = parameters.slot_count();
406 : ScopeType scope_type = parameters.scope_type();
407 5491 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
408 :
409 5491 : if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) {
410 : Callable callable =
411 10982 : CodeFactory::FastNewFunctionContext(isolate(), scope_type);
412 10982 : node->InsertInput(zone(), 1, jsgraph()->Int32Constant(slot_count));
413 5491 : ReplaceWithStubCall(node, callable, flags);
414 : } else {
415 0 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(scope_type));
416 0 : ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext);
417 : }
418 5491 : }
419 :
420 26 : void JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) {
421 26 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
422 : Callable callable =
423 26 : Builtins::CallableFor(isolate(), Builtins::kCreateGeneratorObject);
424 26 : node->RemoveInput(4); // control
425 26 : ReplaceWithStubCall(node, callable, flags);
426 26 : }
427 :
428 0 : void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
429 0 : UNREACHABLE(); // Eliminated in typed lowering.
430 : }
431 :
432 0 : void JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) {
433 0 : UNREACHABLE(); // Eliminated in typed lowering.
434 : }
435 :
436 72269 : void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
437 52735 : CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
438 17855 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
439 35710 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
440 35710 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
441 35710 : node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
442 :
443 : // Use the CreateShallowArrayLiteratlr builtin only for shallow boilerplates
444 : // without properties up to the number of elements that the stubs can handle.
445 34880 : if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
446 : p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) {
447 : Callable callable =
448 17006 : Builtins::CallableFor(isolate(), Builtins::kCreateShallowArrayLiteral);
449 17006 : ReplaceWithStubCall(node, callable, flags);
450 : } else {
451 849 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
452 849 : ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
453 : }
454 17855 : }
455 :
456 89784 : void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
457 22446 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
458 22446 : FeedbackParameter const& p = FeedbackParameterOf(node->op());
459 44892 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
460 44892 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
461 22446 : node->RemoveInput(4); // control
462 : Callable callable =
463 22446 : Builtins::CallableFor(isolate(), Builtins::kCreateEmptyArrayLiteral);
464 22446 : ReplaceWithStubCall(node, callable, flags);
465 22446 : }
466 :
467 202365 : void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
468 159119 : CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
469 40473 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
470 80946 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
471 80946 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
472 80946 : node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
473 40473 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
474 :
475 : // Use the CreateShallowObjectLiteratal builtin only for shallow boilerplates
476 : // without elements up to the number of properties that the stubs can handle.
477 78173 : if ((p.flags() & AggregateLiteral::kIsShallow) != 0 &&
478 : p.length() <=
479 : ConstructorBuiltins::kMaximumClonedShallowObjectProperties) {
480 : Callable callable =
481 37690 : Builtins::CallableFor(isolate(), Builtins::kCreateShallowObjectLiteral);
482 37690 : ReplaceWithStubCall(node, callable, flags);
483 : } else {
484 2783 : ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
485 : }
486 40473 : }
487 :
488 0 : void JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) {
489 0 : UNREACHABLE(); // Eliminated in typed lowering.
490 : }
491 :
492 50500 : void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
493 20200 : CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
494 10100 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
495 : Callable callable =
496 10100 : Builtins::CallableFor(isolate(), Builtins::kCreateRegExpLiteral);
497 20200 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.feedback().vector()));
498 20200 : node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index()));
499 20200 : node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
500 10100 : node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
501 10100 : ReplaceWithStubCall(node, callable, flags);
502 10100 : }
503 :
504 :
505 0 : void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
506 0 : UNREACHABLE(); // Eliminated in typed lowering.
507 : }
508 :
509 0 : void JSGenericLowering::LowerJSCreateWithContext(Node* node) {
510 0 : UNREACHABLE(); // Eliminated in typed lowering.
511 : }
512 :
513 0 : void JSGenericLowering::LowerJSCreateBlockContext(Node* node) {
514 0 : Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
515 0 : node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
516 0 : ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext);
517 0 : }
518 :
519 :
520 0 : void JSGenericLowering::LowerJSCreateScriptContext(Node* node) {
521 0 : Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
522 0 : node->InsertInput(zone(), 1, jsgraph()->HeapConstant(scope_info));
523 0 : ReplaceWithRuntimeCall(node, Runtime::kNewScriptContext);
524 0 : }
525 :
526 105 : void JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) {
527 : ConstructForwardVarargsParameters p =
528 21 : ConstructForwardVarargsParametersOf(node->op());
529 21 : int const arg_count = static_cast<int>(p.arity() - 2);
530 21 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
531 21 : Callable callable = CodeFactory::ConstructForwardVarargs(isolate());
532 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
533 63 : isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
534 21 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
535 21 : Node* stub_arity = jsgraph()->Int32Constant(arg_count);
536 : Node* start_index = jsgraph()->Uint32Constant(p.start_index());
537 : Node* new_target = node->InputAt(arg_count + 1);
538 21 : Node* receiver = jsgraph()->UndefinedConstant();
539 21 : node->RemoveInput(arg_count + 1); // Drop new target.
540 21 : node->InsertInput(zone(), 0, stub_code);
541 21 : node->InsertInput(zone(), 2, new_target);
542 21 : node->InsertInput(zone(), 3, stub_arity);
543 21 : node->InsertInput(zone(), 4, start_index);
544 21 : node->InsertInput(zone(), 5, receiver);
545 21 : NodeProperties::ChangeOp(node, common()->Call(desc));
546 21 : }
547 :
548 42080 : void JSGenericLowering::LowerJSConstruct(Node* node) {
549 10520 : ConstructParameters const& p = ConstructParametersOf(node->op());
550 10520 : int const arg_count = static_cast<int>(p.arity() - 2);
551 10520 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
552 10520 : Callable callable = CodeFactory::Construct(isolate());
553 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
554 31560 : isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
555 10520 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
556 10520 : Node* stub_arity = jsgraph()->Int32Constant(arg_count);
557 : Node* new_target = node->InputAt(arg_count + 1);
558 10520 : Node* receiver = jsgraph()->UndefinedConstant();
559 10520 : node->RemoveInput(arg_count + 1); // Drop new target.
560 10520 : node->InsertInput(zone(), 0, stub_code);
561 10520 : node->InsertInput(zone(), 2, new_target);
562 10520 : node->InsertInput(zone(), 3, stub_arity);
563 10520 : node->InsertInput(zone(), 4, receiver);
564 10520 : NodeProperties::ChangeOp(node, common()->Call(desc));
565 10520 : }
566 :
567 162 : void JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) {
568 : Callable callable =
569 54 : Builtins::CallableFor(isolate(), Builtins::kConstructWithArrayLike);
570 54 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
571 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
572 108 : isolate(), zone(), callable.descriptor(), 1, flags);
573 54 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
574 54 : Node* receiver = jsgraph()->UndefinedConstant();
575 : Node* arguments_list = node->InputAt(1);
576 : Node* new_target = node->InputAt(2);
577 54 : node->InsertInput(zone(), 0, stub_code);
578 54 : node->ReplaceInput(2, new_target);
579 54 : node->ReplaceInput(3, arguments_list);
580 54 : node->InsertInput(zone(), 4, receiver);
581 54 : NodeProperties::ChangeOp(node, common()->Call(desc));
582 54 : }
583 :
584 188 : void JSGenericLowering::LowerJSConstructWithSpread(Node* node) {
585 47 : ConstructParameters const& p = ConstructParametersOf(node->op());
586 47 : int const arg_count = static_cast<int>(p.arity() - 2);
587 : int const spread_index = arg_count;
588 47 : int const new_target_index = arg_count + 1;
589 47 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
590 47 : Callable callable = CodeFactory::ConstructWithSpread(isolate());
591 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
592 94 : isolate(), zone(), callable.descriptor(), arg_count, flags);
593 47 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
594 94 : Node* stack_arg_count = jsgraph()->Int32Constant(arg_count - 1);
595 : Node* new_target = node->InputAt(new_target_index);
596 : Node* spread = node->InputAt(spread_index);
597 47 : Node* receiver = jsgraph()->UndefinedConstant();
598 : DCHECK(new_target_index > spread_index);
599 47 : node->RemoveInput(new_target_index); // Drop new target.
600 47 : node->RemoveInput(spread_index);
601 :
602 47 : node->InsertInput(zone(), 0, stub_code);
603 47 : node->InsertInput(zone(), 2, new_target);
604 47 : node->InsertInput(zone(), 3, stack_arg_count);
605 47 : node->InsertInput(zone(), 4, spread);
606 47 : node->InsertInput(zone(), 5, receiver);
607 47 : NodeProperties::ChangeOp(node, common()->Call(desc));
608 47 : }
609 :
610 296 : void JSGenericLowering::LowerJSCallForwardVarargs(Node* node) {
611 74 : CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op());
612 74 : int const arg_count = static_cast<int>(p.arity() - 2);
613 74 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
614 74 : Callable callable = CodeFactory::CallForwardVarargs(isolate());
615 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
616 222 : isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
617 74 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
618 74 : Node* stub_arity = jsgraph()->Int32Constant(arg_count);
619 : Node* start_index = jsgraph()->Uint32Constant(p.start_index());
620 74 : node->InsertInput(zone(), 0, stub_code);
621 74 : node->InsertInput(zone(), 2, stub_arity);
622 74 : node->InsertInput(zone(), 3, start_index);
623 74 : NodeProperties::ChangeOp(node, common()->Call(desc));
624 74 : }
625 :
626 807312 : void JSGenericLowering::LowerJSCall(Node* node) {
627 269104 : CallParameters const& p = CallParametersOf(node->op());
628 269104 : int const arg_count = static_cast<int>(p.arity() - 2);
629 : ConvertReceiverMode const mode = p.convert_mode();
630 269104 : Callable callable = CodeFactory::Call(isolate(), mode);
631 269104 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
632 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
633 807312 : isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
634 269104 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
635 269104 : Node* stub_arity = jsgraph()->Int32Constant(arg_count);
636 269104 : node->InsertInput(zone(), 0, stub_code);
637 269104 : node->InsertInput(zone(), 2, stub_arity);
638 269104 : NodeProperties::ChangeOp(node, common()->Call(desc));
639 269104 : }
640 :
641 598 : void JSGenericLowering::LowerJSCallWithArrayLike(Node* node) {
642 299 : Callable callable = CodeFactory::CallWithArrayLike(isolate());
643 299 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
644 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
645 598 : isolate(), zone(), callable.descriptor(), 1, flags);
646 299 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
647 : Node* receiver = node->InputAt(1);
648 : Node* arguments_list = node->InputAt(2);
649 299 : node->InsertInput(zone(), 0, stub_code);
650 299 : node->ReplaceInput(3, receiver);
651 299 : node->ReplaceInput(2, arguments_list);
652 299 : NodeProperties::ChangeOp(node, common()->Call(desc));
653 299 : }
654 :
655 2502 : void JSGenericLowering::LowerJSCallWithSpread(Node* node) {
656 834 : CallParameters const& p = CallParametersOf(node->op());
657 834 : int const arg_count = static_cast<int>(p.arity() - 2);
658 834 : int const spread_index = static_cast<int>(p.arity() + 1);
659 834 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
660 834 : Callable callable = CodeFactory::CallWithSpread(isolate());
661 : CallDescriptor* desc = Linkage::GetStubCallDescriptor(
662 1668 : isolate(), zone(), callable.descriptor(), arg_count, flags);
663 834 : Node* stub_code = jsgraph()->HeapConstant(callable.code());
664 : // We pass the spread in a register, not on the stack.
665 1668 : Node* stack_arg_count = jsgraph()->Int32Constant(arg_count - 1);
666 834 : node->InsertInput(zone(), 0, stub_code);
667 834 : node->InsertInput(zone(), 2, stack_arg_count);
668 834 : node->InsertInput(zone(), 3, node->InputAt(spread_index));
669 834 : node->RemoveInput(spread_index + 1);
670 834 : NodeProperties::ChangeOp(node, common()->Call(desc));
671 834 : }
672 :
673 251431 : void JSGenericLowering::LowerJSCallRuntime(Node* node) {
674 502862 : const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
675 502862 : ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
676 251431 : }
677 :
678 0 : void JSGenericLowering::LowerJSConvertReceiver(Node* node) {
679 0 : ReplaceWithRuntimeCall(node, Runtime::kConvertReceiver);
680 0 : }
681 :
682 0 : void JSGenericLowering::LowerJSForInNext(Node* node) {
683 0 : UNREACHABLE(); // Eliminated in typed lowering.
684 : }
685 :
686 0 : void JSGenericLowering::LowerJSForInPrepare(Node* node) {
687 0 : UNREACHABLE(); // Eliminated in typed lowering.
688 : }
689 :
690 0 : void JSGenericLowering::LowerJSLoadMessage(Node* node) {
691 0 : UNREACHABLE(); // Eliminated in typed lowering.
692 : }
693 :
694 :
695 0 : void JSGenericLowering::LowerJSStoreMessage(Node* node) {
696 0 : UNREACHABLE(); // Eliminated in typed lowering.
697 : }
698 :
699 0 : void JSGenericLowering::LowerJSLoadModule(Node* node) {
700 0 : UNREACHABLE(); // Eliminated in typed lowering.
701 : }
702 :
703 0 : void JSGenericLowering::LowerJSStoreModule(Node* node) {
704 0 : UNREACHABLE(); // Eliminated in typed lowering.
705 : }
706 :
707 0 : void JSGenericLowering::LowerJSGeneratorStore(Node* node) {
708 0 : UNREACHABLE(); // Eliminated in typed lowering.
709 : }
710 :
711 0 : void JSGenericLowering::LowerJSGeneratorRestoreContinuation(Node* node) {
712 0 : UNREACHABLE(); // Eliminated in typed lowering.
713 : }
714 :
715 0 : void JSGenericLowering::LowerJSGeneratorRestoreRegister(Node* node) {
716 0 : UNREACHABLE(); // Eliminated in typed lowering.
717 : }
718 :
719 1537294 : void JSGenericLowering::LowerJSStackCheck(Node* node) {
720 512431 : Node* effect = NodeProperties::GetEffectInput(node);
721 512433 : Node* control = NodeProperties::GetControlInput(node);
722 :
723 : Node* limit = effect = graph()->NewNode(
724 : machine()->Load(MachineType::Pointer()),
725 : jsgraph()->ExternalConstant(
726 : ExternalReference::address_of_stack_limit(isolate())),
727 2049730 : jsgraph()->IntPtrConstant(0), effect, control);
728 512433 : Node* pointer = graph()->NewNode(machine()->LoadStackPointer());
729 :
730 512434 : Node* check = graph()->NewNode(machine()->UintLessThan(), limit, pointer);
731 : Node* branch =
732 512434 : graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
733 :
734 512434 : Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
735 : Node* etrue = effect;
736 :
737 512434 : Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
738 512433 : NodeProperties::ReplaceControlInput(node, if_false);
739 512432 : NodeProperties::ReplaceEffectInput(node, effect);
740 : Node* efalse = if_false = node;
741 :
742 512431 : Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
743 512434 : Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
744 :
745 : // Wire the new diamond into the graph, {node} can still throw.
746 512434 : NodeProperties::ReplaceUses(node, node, ephi, merge, merge);
747 512432 : NodeProperties::ReplaceControlInput(merge, if_false, 1);
748 512434 : NodeProperties::ReplaceEffectInput(ephi, efalse, 1);
749 :
750 : // This iteration cuts out potential {IfSuccess} or {IfException} projection
751 : // uses of the original node and places them inside the diamond, so that we
752 : // can change the original {node} into the slow-path runtime call.
753 3602069 : for (Edge edge : merge->use_edges()) {
754 1544818 : if (!NodeProperties::IsControlEdge(edge)) continue;
755 4634463 : if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
756 7094 : NodeProperties::ReplaceUses(edge.from(), nullptr, nullptr, merge);
757 14188 : NodeProperties::ReplaceControlInput(merge, edge.from(), 1);
758 7094 : edge.UpdateTo(node);
759 : }
760 4634457 : if (edge.from()->opcode() == IrOpcode::kIfException) {
761 7094 : NodeProperties::ReplaceEffectInput(edge.from(), node);
762 7094 : edge.UpdateTo(node);
763 : }
764 : }
765 :
766 : // Turn the stack check into a runtime call.
767 512433 : ReplaceWithRuntimeCall(node, Runtime::kStackGuard);
768 512433 : }
769 :
770 583 : void JSGenericLowering::LowerJSDebugger(Node* node) {
771 583 : CallDescriptor::Flags flags = FrameStateFlagForCall(node);
772 583 : Callable callable = CodeFactory::HandleDebuggerStatement(isolate());
773 583 : ReplaceWithStubCall(node, callable, flags);
774 583 : }
775 :
776 13014685 : Zone* JSGenericLowering::zone() const { return graph()->zone(); }
777 :
778 :
779 5806018 : Isolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); }
780 :
781 :
782 17414380 : Graph* JSGenericLowering::graph() const { return jsgraph()->graph(); }
783 :
784 :
785 5704833 : CommonOperatorBuilder* JSGenericLowering::common() const {
786 5704833 : return jsgraph()->common();
787 : }
788 :
789 :
790 1837546 : MachineOperatorBuilder* JSGenericLowering::machine() const {
791 1837546 : return jsgraph()->machine();
792 : }
793 :
794 : } // namespace compiler
795 : } // namespace internal
796 : } // namespace v8
|