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-operator.h"
6
7 #include <limits>
8
9 #include "src/base/lazy-instance.h"
10 #include "src/compiler/js-graph.h"
11 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/operator.h"
13 #include "src/handles/handles-inl.h"
14 #include "src/objects/objects-inl.h"
15 #include "src/objects/template-objects.h"
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
21 namespace {
22
23 // Returns properties for the given binary op.
BinopProperties(Operator::Opcode opcode)24 constexpr Operator::Properties BinopProperties(Operator::Opcode opcode) {
25 CONSTEXPR_DCHECK(JSOperator::IsBinaryWithFeedback(opcode));
26 return opcode == IrOpcode::kJSStrictEqual ? Operator::kPure
27 : Operator::kNoProperties;
28 }
29
30 } // namespace
31
32 namespace js_node_wrapper_utils {
33
UndefinedConstant(JSGraph * jsgraph)34 TNode<Oddball> UndefinedConstant(JSGraph* jsgraph) {
35 return TNode<Oddball>::UncheckedCast(jsgraph->UndefinedConstant());
36 }
37
38 } // namespace js_node_wrapper_utils
39
GetFeedbackCellRefChecked(JSHeapBroker * broker) const40 FeedbackCellRef JSCreateClosureNode::GetFeedbackCellRefChecked(
41 JSHeapBroker* broker) const {
42 HeapObjectMatcher m(feedback_cell());
43 CHECK(m.HasResolvedValue());
44 return FeedbackCellRef(broker, m.ResolvedValue());
45 }
46
operator <<(std::ostream & os,CallFrequency const & f)47 std::ostream& operator<<(std::ostream& os, CallFrequency const& f) {
48 if (f.IsUnknown()) return os << "unknown";
49 return os << f.value();
50 }
51
operator <<(std::ostream & os,ConstructForwardVarargsParameters const & p)52 std::ostream& operator<<(std::ostream& os,
53 ConstructForwardVarargsParameters const& p) {
54 return os << p.arity() << ", " << p.start_index();
55 }
56
ConstructForwardVarargsParametersOf(Operator const * op)57 ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf(
58 Operator const* op) {
59 DCHECK_EQ(IrOpcode::kJSConstructForwardVarargs, op->opcode());
60 return OpParameter<ConstructForwardVarargsParameters>(op);
61 }
62
operator ==(ConstructParameters const & lhs,ConstructParameters const & rhs)63 bool operator==(ConstructParameters const& lhs,
64 ConstructParameters const& rhs) {
65 return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() &&
66 lhs.feedback() == rhs.feedback();
67 }
68
operator !=(ConstructParameters const & lhs,ConstructParameters const & rhs)69 bool operator!=(ConstructParameters const& lhs,
70 ConstructParameters const& rhs) {
71 return !(lhs == rhs);
72 }
73
hash_value(ConstructParameters const & p)74 size_t hash_value(ConstructParameters const& p) {
75 return base::hash_combine(p.arity(), p.frequency(),
76 FeedbackSource::Hash()(p.feedback()));
77 }
78
operator <<(std::ostream & os,ConstructParameters const & p)79 std::ostream& operator<<(std::ostream& os, ConstructParameters const& p) {
80 return os << p.arity() << ", " << p.frequency();
81 }
82
ConstructParametersOf(Operator const * op)83 ConstructParameters const& ConstructParametersOf(Operator const* op) {
84 DCHECK(op->opcode() == IrOpcode::kJSConstruct ||
85 op->opcode() == IrOpcode::kJSConstructWithArrayLike ||
86 op->opcode() == IrOpcode::kJSConstructWithSpread);
87 return OpParameter<ConstructParameters>(op);
88 }
89
operator <<(std::ostream & os,CallParameters const & p)90 std::ostream& operator<<(std::ostream& os, CallParameters const& p) {
91 return os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode()
92 << ", " << p.speculation_mode() << ", " << p.feedback_relation();
93 }
94
CallParametersOf(const Operator * op)95 const CallParameters& CallParametersOf(const Operator* op) {
96 DCHECK(op->opcode() == IrOpcode::kJSCall ||
97 op->opcode() == IrOpcode::kJSCallWithArrayLike ||
98 op->opcode() == IrOpcode::kJSCallWithSpread);
99 return OpParameter<CallParameters>(op);
100 }
101
operator <<(std::ostream & os,CallForwardVarargsParameters const & p)102 std::ostream& operator<<(std::ostream& os,
103 CallForwardVarargsParameters const& p) {
104 return os << p.arity() << ", " << p.start_index();
105 }
106
CallForwardVarargsParametersOf(Operator const * op)107 CallForwardVarargsParameters const& CallForwardVarargsParametersOf(
108 Operator const* op) {
109 DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, op->opcode());
110 return OpParameter<CallForwardVarargsParameters>(op);
111 }
112
113
operator ==(CallRuntimeParameters const & lhs,CallRuntimeParameters const & rhs)114 bool operator==(CallRuntimeParameters const& lhs,
115 CallRuntimeParameters const& rhs) {
116 return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
117 }
118
119
operator !=(CallRuntimeParameters const & lhs,CallRuntimeParameters const & rhs)120 bool operator!=(CallRuntimeParameters const& lhs,
121 CallRuntimeParameters const& rhs) {
122 return !(lhs == rhs);
123 }
124
125
hash_value(CallRuntimeParameters const & p)126 size_t hash_value(CallRuntimeParameters const& p) {
127 return base::hash_combine(p.id(), p.arity());
128 }
129
130
operator <<(std::ostream & os,CallRuntimeParameters const & p)131 std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
132 return os << p.id() << ", " << p.arity();
133 }
134
135
CallRuntimeParametersOf(const Operator * op)136 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
137 DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
138 return OpParameter<CallRuntimeParameters>(op);
139 }
140
141
ContextAccess(size_t depth,size_t index,bool immutable)142 ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
143 : immutable_(immutable),
144 depth_(static_cast<uint16_t>(depth)),
145 index_(static_cast<uint32_t>(index)) {
146 DCHECK(depth <= std::numeric_limits<uint16_t>::max());
147 DCHECK(index <= std::numeric_limits<uint32_t>::max());
148 }
149
150
operator ==(ContextAccess const & lhs,ContextAccess const & rhs)151 bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
152 return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
153 lhs.immutable() == rhs.immutable();
154 }
155
156
operator !=(ContextAccess const & lhs,ContextAccess const & rhs)157 bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
158 return !(lhs == rhs);
159 }
160
161
hash_value(ContextAccess const & access)162 size_t hash_value(ContextAccess const& access) {
163 return base::hash_combine(access.depth(), access.index(), access.immutable());
164 }
165
166
operator <<(std::ostream & os,ContextAccess const & access)167 std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
168 return os << access.depth() << ", " << access.index() << ", "
169 << access.immutable();
170 }
171
172
ContextAccessOf(Operator const * op)173 ContextAccess const& ContextAccessOf(Operator const* op) {
174 DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
175 op->opcode() == IrOpcode::kJSStoreContext);
176 return OpParameter<ContextAccess>(op);
177 }
178
CreateFunctionContextParameters(Handle<ScopeInfo> scope_info,int slot_count,ScopeType scope_type)179 CreateFunctionContextParameters::CreateFunctionContextParameters(
180 Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type)
181 : scope_info_(scope_info),
182 slot_count_(slot_count),
183 scope_type_(scope_type) {}
184
operator ==(CreateFunctionContextParameters const & lhs,CreateFunctionContextParameters const & rhs)185 bool operator==(CreateFunctionContextParameters const& lhs,
186 CreateFunctionContextParameters const& rhs) {
187 return lhs.scope_info().location() == rhs.scope_info().location() &&
188 lhs.slot_count() == rhs.slot_count() &&
189 lhs.scope_type() == rhs.scope_type();
190 }
191
operator !=(CreateFunctionContextParameters const & lhs,CreateFunctionContextParameters const & rhs)192 bool operator!=(CreateFunctionContextParameters const& lhs,
193 CreateFunctionContextParameters const& rhs) {
194 return !(lhs == rhs);
195 }
196
hash_value(CreateFunctionContextParameters const & parameters)197 size_t hash_value(CreateFunctionContextParameters const& parameters) {
198 return base::hash_combine(parameters.scope_info().location(),
199 parameters.slot_count(),
200 static_cast<int>(parameters.scope_type()));
201 }
202
operator <<(std::ostream & os,CreateFunctionContextParameters const & parameters)203 std::ostream& operator<<(std::ostream& os,
204 CreateFunctionContextParameters const& parameters) {
205 return os << parameters.slot_count() << ", " << parameters.scope_type();
206 }
207
CreateFunctionContextParametersOf(Operator const * op)208 CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
209 Operator const* op) {
210 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, op->opcode());
211 return OpParameter<CreateFunctionContextParameters>(op);
212 }
213
operator ==(StoreNamedOwnParameters const & lhs,StoreNamedOwnParameters const & rhs)214 bool operator==(StoreNamedOwnParameters const& lhs,
215 StoreNamedOwnParameters const& rhs) {
216 return lhs.name().location() == rhs.name().location() &&
217 lhs.feedback() == rhs.feedback();
218 }
219
operator !=(StoreNamedOwnParameters const & lhs,StoreNamedOwnParameters const & rhs)220 bool operator!=(StoreNamedOwnParameters const& lhs,
221 StoreNamedOwnParameters const& rhs) {
222 return !(lhs == rhs);
223 }
224
hash_value(StoreNamedOwnParameters const & p)225 size_t hash_value(StoreNamedOwnParameters const& p) {
226 return base::hash_combine(p.name().location(),
227 FeedbackSource::Hash()(p.feedback()));
228 }
229
operator <<(std::ostream & os,StoreNamedOwnParameters const & p)230 std::ostream& operator<<(std::ostream& os, StoreNamedOwnParameters const& p) {
231 return os << Brief(*p.name());
232 }
233
StoreNamedOwnParametersOf(const Operator * op)234 StoreNamedOwnParameters const& StoreNamedOwnParametersOf(const Operator* op) {
235 DCHECK_EQ(IrOpcode::kJSStoreNamedOwn, op->opcode());
236 return OpParameter<StoreNamedOwnParameters>(op);
237 }
238
operator ==(FeedbackParameter const & lhs,FeedbackParameter const & rhs)239 bool operator==(FeedbackParameter const& lhs, FeedbackParameter const& rhs) {
240 return lhs.feedback() == rhs.feedback();
241 }
242
operator !=(FeedbackParameter const & lhs,FeedbackParameter const & rhs)243 bool operator!=(FeedbackParameter const& lhs, FeedbackParameter const& rhs) {
244 return !(lhs == rhs);
245 }
246
hash_value(FeedbackParameter const & p)247 size_t hash_value(FeedbackParameter const& p) {
248 return FeedbackSource::Hash()(p.feedback());
249 }
250
operator <<(std::ostream & os,FeedbackParameter const & p)251 std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
252 return os << p.feedback();
253 }
254
FeedbackParameterOf(const Operator * op)255 FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
256 DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()) ||
257 JSOperator::IsBinaryWithFeedback(op->opcode()) ||
258 op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
259 op->opcode() == IrOpcode::kJSInstanceOf ||
260 op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral ||
261 op->opcode() == IrOpcode::kJSStoreInArrayLiteral);
262 return OpParameter<FeedbackParameter>(op);
263 }
264
operator ==(NamedAccess const & lhs,NamedAccess const & rhs)265 bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
266 return lhs.name().location() == rhs.name().location() &&
267 lhs.language_mode() == rhs.language_mode() &&
268 lhs.feedback() == rhs.feedback();
269 }
270
271
operator !=(NamedAccess const & lhs,NamedAccess const & rhs)272 bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
273 return !(lhs == rhs);
274 }
275
276
hash_value(NamedAccess const & p)277 size_t hash_value(NamedAccess const& p) {
278 return base::hash_combine(p.name().location(), p.language_mode(),
279 FeedbackSource::Hash()(p.feedback()));
280 }
281
282
operator <<(std::ostream & os,NamedAccess const & p)283 std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
284 return os << Brief(*p.name()) << ", " << p.language_mode();
285 }
286
287
NamedAccessOf(const Operator * op)288 NamedAccess const& NamedAccessOf(const Operator* op) {
289 DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
290 op->opcode() == IrOpcode::kJSLoadNamedFromSuper ||
291 op->opcode() == IrOpcode::kJSStoreNamed);
292 return OpParameter<NamedAccess>(op);
293 }
294
295
operator <<(std::ostream & os,PropertyAccess const & p)296 std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
297 return os << p.language_mode() << ", " << p.feedback();
298 }
299
300
operator ==(PropertyAccess const & lhs,PropertyAccess const & rhs)301 bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
302 return lhs.language_mode() == rhs.language_mode() &&
303 lhs.feedback() == rhs.feedback();
304 }
305
306
operator !=(PropertyAccess const & lhs,PropertyAccess const & rhs)307 bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
308 return !(lhs == rhs);
309 }
310
311
PropertyAccessOf(const Operator * op)312 PropertyAccess const& PropertyAccessOf(const Operator* op) {
313 DCHECK(op->opcode() == IrOpcode::kJSHasProperty ||
314 op->opcode() == IrOpcode::kJSLoadProperty ||
315 op->opcode() == IrOpcode::kJSStoreProperty);
316 return OpParameter<PropertyAccess>(op);
317 }
318
319
hash_value(PropertyAccess const & p)320 size_t hash_value(PropertyAccess const& p) {
321 return base::hash_combine(p.language_mode(),
322 FeedbackSource::Hash()(p.feedback()));
323 }
324
325
operator ==(LoadGlobalParameters const & lhs,LoadGlobalParameters const & rhs)326 bool operator==(LoadGlobalParameters const& lhs,
327 LoadGlobalParameters const& rhs) {
328 return lhs.name().location() == rhs.name().location() &&
329 lhs.feedback() == rhs.feedback() &&
330 lhs.typeof_mode() == rhs.typeof_mode();
331 }
332
333
operator !=(LoadGlobalParameters const & lhs,LoadGlobalParameters const & rhs)334 bool operator!=(LoadGlobalParameters const& lhs,
335 LoadGlobalParameters const& rhs) {
336 return !(lhs == rhs);
337 }
338
339
hash_value(LoadGlobalParameters const & p)340 size_t hash_value(LoadGlobalParameters const& p) {
341 return base::hash_combine(p.name().location(), p.typeof_mode());
342 }
343
344
operator <<(std::ostream & os,LoadGlobalParameters const & p)345 std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
346 return os << Brief(*p.name()) << ", " << p.typeof_mode();
347 }
348
349
LoadGlobalParametersOf(const Operator * op)350 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
351 DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
352 return OpParameter<LoadGlobalParameters>(op);
353 }
354
355
operator ==(StoreGlobalParameters const & lhs,StoreGlobalParameters const & rhs)356 bool operator==(StoreGlobalParameters const& lhs,
357 StoreGlobalParameters const& rhs) {
358 return lhs.language_mode() == rhs.language_mode() &&
359 lhs.name().location() == rhs.name().location() &&
360 lhs.feedback() == rhs.feedback();
361 }
362
363
operator !=(StoreGlobalParameters const & lhs,StoreGlobalParameters const & rhs)364 bool operator!=(StoreGlobalParameters const& lhs,
365 StoreGlobalParameters const& rhs) {
366 return !(lhs == rhs);
367 }
368
369
hash_value(StoreGlobalParameters const & p)370 size_t hash_value(StoreGlobalParameters const& p) {
371 return base::hash_combine(p.language_mode(), p.name().location(),
372 FeedbackSource::Hash()(p.feedback()));
373 }
374
375
operator <<(std::ostream & os,StoreGlobalParameters const & p)376 std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
377 return os << p.language_mode() << ", " << Brief(*p.name());
378 }
379
380
StoreGlobalParametersOf(const Operator * op)381 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
382 DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
383 return OpParameter<StoreGlobalParameters>(op);
384 }
385
386
CreateArgumentsTypeOf(const Operator * op)387 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) {
388 DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
389 return OpParameter<CreateArgumentsType>(op);
390 }
391
392
operator ==(CreateArrayParameters const & lhs,CreateArrayParameters const & rhs)393 bool operator==(CreateArrayParameters const& lhs,
394 CreateArrayParameters const& rhs) {
395 return lhs.arity() == rhs.arity() &&
396 lhs.site().address() == rhs.site().address();
397 }
398
399
operator !=(CreateArrayParameters const & lhs,CreateArrayParameters const & rhs)400 bool operator!=(CreateArrayParameters const& lhs,
401 CreateArrayParameters const& rhs) {
402 return !(lhs == rhs);
403 }
404
405
hash_value(CreateArrayParameters const & p)406 size_t hash_value(CreateArrayParameters const& p) {
407 return base::hash_combine(p.arity(), p.site().address());
408 }
409
410
operator <<(std::ostream & os,CreateArrayParameters const & p)411 std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
412 os << p.arity();
413 Handle<AllocationSite> site;
414 if (p.site().ToHandle(&site)) os << ", " << Brief(*site);
415 return os;
416 }
417
CreateArrayParametersOf(const Operator * op)418 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
419 DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
420 return OpParameter<CreateArrayParameters>(op);
421 }
422
operator ==(CreateArrayIteratorParameters const & lhs,CreateArrayIteratorParameters const & rhs)423 bool operator==(CreateArrayIteratorParameters const& lhs,
424 CreateArrayIteratorParameters const& rhs) {
425 return lhs.kind() == rhs.kind();
426 }
427
operator !=(CreateArrayIteratorParameters const & lhs,CreateArrayIteratorParameters const & rhs)428 bool operator!=(CreateArrayIteratorParameters const& lhs,
429 CreateArrayIteratorParameters const& rhs) {
430 return !(lhs == rhs);
431 }
432
hash_value(CreateArrayIteratorParameters const & p)433 size_t hash_value(CreateArrayIteratorParameters const& p) {
434 return static_cast<size_t>(p.kind());
435 }
436
operator <<(std::ostream & os,CreateArrayIteratorParameters const & p)437 std::ostream& operator<<(std::ostream& os,
438 CreateArrayIteratorParameters const& p) {
439 return os << p.kind();
440 }
441
CreateArrayIteratorParametersOf(const Operator * op)442 const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf(
443 const Operator* op) {
444 DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, op->opcode());
445 return OpParameter<CreateArrayIteratorParameters>(op);
446 }
447
operator ==(CreateCollectionIteratorParameters const & lhs,CreateCollectionIteratorParameters const & rhs)448 bool operator==(CreateCollectionIteratorParameters const& lhs,
449 CreateCollectionIteratorParameters const& rhs) {
450 return lhs.collection_kind() == rhs.collection_kind() &&
451 lhs.iteration_kind() == rhs.iteration_kind();
452 }
453
operator !=(CreateCollectionIteratorParameters const & lhs,CreateCollectionIteratorParameters const & rhs)454 bool operator!=(CreateCollectionIteratorParameters const& lhs,
455 CreateCollectionIteratorParameters const& rhs) {
456 return !(lhs == rhs);
457 }
458
hash_value(CreateCollectionIteratorParameters const & p)459 size_t hash_value(CreateCollectionIteratorParameters const& p) {
460 return base::hash_combine(static_cast<size_t>(p.collection_kind()),
461 static_cast<size_t>(p.iteration_kind()));
462 }
463
operator <<(std::ostream & os,CreateCollectionIteratorParameters const & p)464 std::ostream& operator<<(std::ostream& os,
465 CreateCollectionIteratorParameters const& p) {
466 return os << p.collection_kind() << ", " << p.iteration_kind();
467 }
468
CreateCollectionIteratorParametersOf(const Operator * op)469 const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf(
470 const Operator* op) {
471 DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, op->opcode());
472 return OpParameter<CreateCollectionIteratorParameters>(op);
473 }
474
operator ==(CreateBoundFunctionParameters const & lhs,CreateBoundFunctionParameters const & rhs)475 bool operator==(CreateBoundFunctionParameters const& lhs,
476 CreateBoundFunctionParameters const& rhs) {
477 return lhs.arity() == rhs.arity() &&
478 lhs.map().location() == rhs.map().location();
479 }
480
operator !=(CreateBoundFunctionParameters const & lhs,CreateBoundFunctionParameters const & rhs)481 bool operator!=(CreateBoundFunctionParameters const& lhs,
482 CreateBoundFunctionParameters const& rhs) {
483 return !(lhs == rhs);
484 }
485
hash_value(CreateBoundFunctionParameters const & p)486 size_t hash_value(CreateBoundFunctionParameters const& p) {
487 return base::hash_combine(p.arity(), p.map().location());
488 }
489
operator <<(std::ostream & os,CreateBoundFunctionParameters const & p)490 std::ostream& operator<<(std::ostream& os,
491 CreateBoundFunctionParameters const& p) {
492 os << p.arity();
493 if (!p.map().is_null()) os << ", " << Brief(*p.map());
494 return os;
495 }
496
CreateBoundFunctionParametersOf(const Operator * op)497 const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
498 const Operator* op) {
499 DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, op->opcode());
500 return OpParameter<CreateBoundFunctionParameters>(op);
501 }
502
operator ==(GetTemplateObjectParameters const & lhs,GetTemplateObjectParameters const & rhs)503 bool operator==(GetTemplateObjectParameters const& lhs,
504 GetTemplateObjectParameters const& rhs) {
505 return lhs.description().location() == rhs.description().location() &&
506 lhs.shared().location() == rhs.shared().location() &&
507 lhs.feedback() == rhs.feedback();
508 }
509
operator !=(GetTemplateObjectParameters const & lhs,GetTemplateObjectParameters const & rhs)510 bool operator!=(GetTemplateObjectParameters const& lhs,
511 GetTemplateObjectParameters const& rhs) {
512 return !(lhs == rhs);
513 }
514
hash_value(GetTemplateObjectParameters const & p)515 size_t hash_value(GetTemplateObjectParameters const& p) {
516 return base::hash_combine(p.description().location(), p.shared().location(),
517 FeedbackSource::Hash()(p.feedback()));
518 }
519
operator <<(std::ostream & os,GetTemplateObjectParameters const & p)520 std::ostream& operator<<(std::ostream& os,
521 GetTemplateObjectParameters const& p) {
522 return os << Brief(*p.description()) << ", " << Brief(*p.shared());
523 }
524
GetTemplateObjectParametersOf(const Operator * op)525 const GetTemplateObjectParameters& GetTemplateObjectParametersOf(
526 const Operator* op) {
527 DCHECK(op->opcode() == IrOpcode::kJSGetTemplateObject);
528 return OpParameter<GetTemplateObjectParameters>(op);
529 }
530
operator ==(CreateClosureParameters const & lhs,CreateClosureParameters const & rhs)531 bool operator==(CreateClosureParameters const& lhs,
532 CreateClosureParameters const& rhs) {
533 return lhs.allocation() == rhs.allocation() &&
534 lhs.code().location() == rhs.code().location() &&
535 lhs.shared_info().location() == rhs.shared_info().location();
536 }
537
538
operator !=(CreateClosureParameters const & lhs,CreateClosureParameters const & rhs)539 bool operator!=(CreateClosureParameters const& lhs,
540 CreateClosureParameters const& rhs) {
541 return !(lhs == rhs);
542 }
543
544
hash_value(CreateClosureParameters const & p)545 size_t hash_value(CreateClosureParameters const& p) {
546 return base::hash_combine(p.allocation(), p.shared_info().location());
547 }
548
549
operator <<(std::ostream & os,CreateClosureParameters const & p)550 std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
551 return os << p.allocation() << ", " << Brief(*p.shared_info()) << ", "
552 << Brief(*p.code());
553 }
554
555
CreateClosureParametersOf(const Operator * op)556 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
557 DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
558 return OpParameter<CreateClosureParameters>(op);
559 }
560
561
operator ==(CreateLiteralParameters const & lhs,CreateLiteralParameters const & rhs)562 bool operator==(CreateLiteralParameters const& lhs,
563 CreateLiteralParameters const& rhs) {
564 return lhs.constant().location() == rhs.constant().location() &&
565 lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() &&
566 lhs.flags() == rhs.flags();
567 }
568
569
operator !=(CreateLiteralParameters const & lhs,CreateLiteralParameters const & rhs)570 bool operator!=(CreateLiteralParameters const& lhs,
571 CreateLiteralParameters const& rhs) {
572 return !(lhs == rhs);
573 }
574
575
hash_value(CreateLiteralParameters const & p)576 size_t hash_value(CreateLiteralParameters const& p) {
577 return base::hash_combine(p.constant().location(),
578 FeedbackSource::Hash()(p.feedback()), p.length(),
579 p.flags());
580 }
581
582
operator <<(std::ostream & os,CreateLiteralParameters const & p)583 std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
584 return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags();
585 }
586
587
CreateLiteralParametersOf(const Operator * op)588 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
589 DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
590 op->opcode() == IrOpcode::kJSCreateLiteralObject ||
591 op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
592 return OpParameter<CreateLiteralParameters>(op);
593 }
594
operator ==(CloneObjectParameters const & lhs,CloneObjectParameters const & rhs)595 bool operator==(CloneObjectParameters const& lhs,
596 CloneObjectParameters const& rhs) {
597 return lhs.feedback() == rhs.feedback() && lhs.flags() == rhs.flags();
598 }
599
operator !=(CloneObjectParameters const & lhs,CloneObjectParameters const & rhs)600 bool operator!=(CloneObjectParameters const& lhs,
601 CloneObjectParameters const& rhs) {
602 return !(lhs == rhs);
603 }
604
hash_value(CloneObjectParameters const & p)605 size_t hash_value(CloneObjectParameters const& p) {
606 return base::hash_combine(FeedbackSource::Hash()(p.feedback()), p.flags());
607 }
608
operator <<(std::ostream & os,CloneObjectParameters const & p)609 std::ostream& operator<<(std::ostream& os, CloneObjectParameters const& p) {
610 return os << p.flags();
611 }
612
CloneObjectParametersOf(const Operator * op)613 const CloneObjectParameters& CloneObjectParametersOf(const Operator* op) {
614 DCHECK(op->opcode() == IrOpcode::kJSCloneObject);
615 return OpParameter<CloneObjectParameters>(op);
616 }
617
operator <<(std::ostream & os,GetIteratorParameters const & p)618 std::ostream& operator<<(std::ostream& os, GetIteratorParameters const& p) {
619 return os << p.loadFeedback() << ", " << p.callFeedback();
620 }
621
operator ==(GetIteratorParameters const & lhs,GetIteratorParameters const & rhs)622 bool operator==(GetIteratorParameters const& lhs,
623 GetIteratorParameters const& rhs) {
624 return lhs.loadFeedback() == rhs.loadFeedback() &&
625 lhs.callFeedback() == rhs.callFeedback();
626 }
627
operator !=(GetIteratorParameters const & lhs,GetIteratorParameters const & rhs)628 bool operator!=(GetIteratorParameters const& lhs,
629 GetIteratorParameters const& rhs) {
630 return !(lhs == rhs);
631 }
632
GetIteratorParametersOf(const Operator * op)633 GetIteratorParameters const& GetIteratorParametersOf(const Operator* op) {
634 DCHECK(op->opcode() == IrOpcode::kJSGetIterator);
635 return OpParameter<GetIteratorParameters>(op);
636 }
637
hash_value(GetIteratorParameters const & p)638 size_t hash_value(GetIteratorParameters const& p) {
639 return base::hash_combine(FeedbackSource::Hash()(p.loadFeedback()),
640 FeedbackSource::Hash()(p.callFeedback()));
641 }
642
hash_value(ForInMode const & mode)643 size_t hash_value(ForInMode const& mode) { return static_cast<uint8_t>(mode); }
644
operator <<(std::ostream & os,ForInMode const & mode)645 std::ostream& operator<<(std::ostream& os, ForInMode const& mode) {
646 switch (mode) {
647 case ForInMode::kUseEnumCacheKeysAndIndices:
648 return os << "UseEnumCacheKeysAndIndices";
649 case ForInMode::kUseEnumCacheKeys:
650 return os << "UseEnumCacheKeys";
651 case ForInMode::kGeneric:
652 return os << "Generic";
653 }
654 UNREACHABLE();
655 }
656
operator ==(ForInParameters const & lhs,ForInParameters const & rhs)657 bool operator==(ForInParameters const& lhs, ForInParameters const& rhs) {
658 return lhs.feedback() == rhs.feedback() && lhs.mode() == rhs.mode();
659 }
660
operator !=(ForInParameters const & lhs,ForInParameters const & rhs)661 bool operator!=(ForInParameters const& lhs, ForInParameters const& rhs) {
662 return !(lhs == rhs);
663 }
664
hash_value(ForInParameters const & p)665 size_t hash_value(ForInParameters const& p) {
666 return base::hash_combine(FeedbackSource::Hash()(p.feedback()), p.mode());
667 }
668
operator <<(std::ostream & os,ForInParameters const & p)669 std::ostream& operator<<(std::ostream& os, ForInParameters const& p) {
670 return os << p.feedback() << ", " << p.mode();
671 }
672
ForInParametersOf(const Operator * op)673 ForInParameters const& ForInParametersOf(const Operator* op) {
674 DCHECK(op->opcode() == IrOpcode::kJSForInNext ||
675 op->opcode() == IrOpcode::kJSForInPrepare);
676 return OpParameter<ForInParameters>(op);
677 }
678
679 #define CACHED_OP_LIST(V) \
680 V(ToLength, Operator::kNoProperties, 1, 1) \
681 V(ToName, Operator::kNoProperties, 1, 1) \
682 V(ToNumber, Operator::kNoProperties, 1, 1) \
683 V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1) \
684 V(ToNumeric, Operator::kNoProperties, 1, 1) \
685 V(ToObject, Operator::kFoldable, 1, 1) \
686 V(ToString, Operator::kNoProperties, 1, 1) \
687 V(Create, Operator::kNoProperties, 2, 1) \
688 V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \
689 V(CreateStringIterator, Operator::kEliminatable, 1, 1) \
690 V(CreateKeyValueArray, Operator::kEliminatable, 2, 1) \
691 V(CreatePromise, Operator::kEliminatable, 0, 1) \
692 V(CreateTypedArray, Operator::kNoProperties, 5, 1) \
693 V(CreateObject, Operator::kNoProperties, 1, 1) \
694 V(ObjectIsArray, Operator::kNoProperties, 1, 1) \
695 V(HasInPrototypeChain, Operator::kNoProperties, 2, 1) \
696 V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1) \
697 V(ForInEnumerate, Operator::kNoProperties, 1, 1) \
698 V(AsyncFunctionEnter, Operator::kNoProperties, 2, 1) \
699 V(AsyncFunctionReject, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \
700 V(AsyncFunctionResolve, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \
701 V(LoadMessage, Operator::kNoThrow | Operator::kNoWrite, 0, 1) \
702 V(StoreMessage, Operator::kNoRead | Operator::kNoThrow, 1, 0) \
703 V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
704 V(GeneratorRestoreContext, Operator::kNoThrow, 1, 1) \
705 V(GeneratorRestoreInputOrDebugPos, Operator::kNoThrow, 1, 1) \
706 V(Debugger, Operator::kNoProperties, 0, 0) \
707 V(FulfillPromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \
708 V(PerformPromiseThen, Operator::kNoDeopt | Operator::kNoThrow, 4, 1) \
709 V(PromiseResolve, Operator::kNoProperties, 2, 1) \
710 V(RejectPromise, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \
711 V(ResolvePromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \
712 V(GetSuperConstructor, Operator::kNoWrite | Operator::kNoThrow, 1, 1) \
713 V(ParseInt, Operator::kNoProperties, 2, 1) \
714 V(RegExpTest, Operator::kNoProperties, 2, 1)
715
716 struct JSOperatorGlobalCache final {
717 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \
718 struct Name##Operator final : public Operator { \
719 Name##Operator() \
720 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \
721 value_input_count, Operator::ZeroIfPure(properties), \
722 Operator::ZeroIfEliminatable(properties), \
723 value_output_count, Operator::ZeroIfPure(properties), \
724 Operator::ZeroIfNoThrow(properties)) {} \
725 }; \
726 Name##Operator k##Name##Operator;
727 CACHED_OP_LIST(CACHED_OP)
728 #undef CACHED_OP
729 };
730
731 namespace {
732 DEFINE_LAZY_LEAKY_OBJECT_GETTER(JSOperatorGlobalCache, GetJSOperatorGlobalCache)
733 } // namespace
734
JSOperatorBuilder(Zone * zone)735 JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
736 : cache_(*GetJSOperatorGlobalCache()), zone_(zone) {}
737
738 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \
739 const Operator* JSOperatorBuilder::Name() { \
740 return &cache_.k##Name##Operator; \
741 }
742 CACHED_OP_LIST(CACHED_OP)
743 #undef CACHED_OP
744
745 #define UNARY_OP(JSName, Name) \
746 const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \
747 FeedbackParameter parameters(feedback); \
748 return zone()->New<Operator1<FeedbackParameter>>( \
749 IrOpcode::k##JSName, Operator::kNoProperties, #JSName, 2, 1, 1, 1, 1, \
750 2, parameters); \
751 }
JS_UNOP_WITH_FEEDBACK(UNARY_OP)752 JS_UNOP_WITH_FEEDBACK(UNARY_OP)
753 #undef UNARY_OP
754
755 #define BINARY_OP(JSName, Name) \
756 const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \
757 static constexpr auto kProperties = BinopProperties(IrOpcode::k##JSName); \
758 FeedbackParameter parameters(feedback); \
759 return zone()->New<Operator1<FeedbackParameter>>( \
760 IrOpcode::k##JSName, kProperties, #JSName, 3, 1, 1, 1, 1, \
761 Operator::ZeroIfNoThrow(kProperties), parameters); \
762 }
763 JS_BINOP_WITH_FEEDBACK(BINARY_OP)
764 #undef BINARY_OP
765
766 const Operator* JSOperatorBuilder::StoreDataPropertyInLiteral(
767 const FeedbackSource& feedback) {
768 static constexpr int kObject = 1;
769 static constexpr int kName = 1;
770 static constexpr int kValue = 1;
771 static constexpr int kFlags = 1;
772 static constexpr int kFeedbackVector = 1;
773 static constexpr int kArity =
774 kObject + kName + kValue + kFlags + kFeedbackVector;
775 FeedbackParameter parameters(feedback);
776 return zone()->New<Operator1<FeedbackParameter>>( // --
777 IrOpcode::kJSStoreDataPropertyInLiteral,
778 Operator::kNoThrow, // opcode
779 "JSStoreDataPropertyInLiteral", // name
780 kArity, 1, 1, 0, 1, 1, // counts
781 parameters); // parameter
782 }
783
StoreInArrayLiteral(const FeedbackSource & feedback)784 const Operator* JSOperatorBuilder::StoreInArrayLiteral(
785 const FeedbackSource& feedback) {
786 static constexpr int kArray = 1;
787 static constexpr int kIndex = 1;
788 static constexpr int kValue = 1;
789 static constexpr int kFeedbackVector = 1;
790 static constexpr int kArity = kArray + kIndex + kValue + kFeedbackVector;
791 FeedbackParameter parameters(feedback);
792 return zone()->New<Operator1<FeedbackParameter>>( // --
793 IrOpcode::kJSStoreInArrayLiteral,
794 Operator::kNoThrow, // opcode
795 "JSStoreInArrayLiteral", // name
796 kArity, 1, 1, 0, 1, 1, // counts
797 parameters); // parameter
798 }
799
CallForwardVarargs(size_t arity,uint32_t start_index)800 const Operator* JSOperatorBuilder::CallForwardVarargs(size_t arity,
801 uint32_t start_index) {
802 CallForwardVarargsParameters parameters(arity, start_index);
803 return zone()->New<Operator1<CallForwardVarargsParameters>>( // --
804 IrOpcode::kJSCallForwardVarargs, Operator::kNoProperties, // opcode
805 "JSCallForwardVarargs", // name
806 parameters.arity(), 1, 1, 1, 1, 2, // counts
807 parameters); // parameter
808 }
809
Call(size_t arity,CallFrequency const & frequency,FeedbackSource const & feedback,ConvertReceiverMode convert_mode,SpeculationMode speculation_mode,CallFeedbackRelation feedback_relation)810 const Operator* JSOperatorBuilder::Call(
811 size_t arity, CallFrequency const& frequency,
812 FeedbackSource const& feedback, ConvertReceiverMode convert_mode,
813 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation) {
814 CallParameters parameters(arity, frequency, feedback, convert_mode,
815 speculation_mode, feedback_relation);
816 return zone()->New<Operator1<CallParameters>>( // --
817 IrOpcode::kJSCall, Operator::kNoProperties, // opcode
818 "JSCall", // name
819 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs
820 parameters); // parameter
821 }
822
CallWithArrayLike(const CallFrequency & frequency,const FeedbackSource & feedback,SpeculationMode speculation_mode,CallFeedbackRelation feedback_relation)823 const Operator* JSOperatorBuilder::CallWithArrayLike(
824 const CallFrequency& frequency, const FeedbackSource& feedback,
825 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation) {
826 static constexpr int kTheArrayLikeObject = 1;
827 CallParameters parameters(
828 JSCallWithArrayLikeNode::ArityForArgc(kTheArrayLikeObject), frequency,
829 feedback, ConvertReceiverMode::kAny, speculation_mode, feedback_relation);
830 return zone()->New<Operator1<CallParameters>>( // --
831 IrOpcode::kJSCallWithArrayLike, Operator::kNoProperties, // opcode
832 "JSCallWithArrayLike", // name
833 parameters.arity(), 1, 1, 1, 1, 2, // counts
834 parameters); // parameter
835 }
836
CallWithSpread(uint32_t arity,CallFrequency const & frequency,FeedbackSource const & feedback,SpeculationMode speculation_mode,CallFeedbackRelation feedback_relation)837 const Operator* JSOperatorBuilder::CallWithSpread(
838 uint32_t arity, CallFrequency const& frequency,
839 FeedbackSource const& feedback, SpeculationMode speculation_mode,
840 CallFeedbackRelation feedback_relation) {
841 DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
842 feedback.IsValid());
843 CallParameters parameters(arity, frequency, feedback,
844 ConvertReceiverMode::kAny, speculation_mode,
845 feedback_relation);
846 return zone()->New<Operator1<CallParameters>>( // --
847 IrOpcode::kJSCallWithSpread, Operator::kNoProperties, // opcode
848 "JSCallWithSpread", // name
849 parameters.arity(), 1, 1, 1, 1, 2, // counts
850 parameters); // parameter
851 }
852
CallRuntime(Runtime::FunctionId id)853 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) {
854 const Runtime::Function* f = Runtime::FunctionForId(id);
855 return CallRuntime(f, f->nargs);
856 }
857
858
CallRuntime(Runtime::FunctionId id,size_t arity)859 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
860 size_t arity) {
861 const Runtime::Function* f = Runtime::FunctionForId(id);
862 return CallRuntime(f, arity);
863 }
864
865
CallRuntime(const Runtime::Function * f,size_t arity)866 const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f,
867 size_t arity) {
868 CallRuntimeParameters parameters(f->function_id, arity);
869 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
870 return zone()->New<Operator1<CallRuntimeParameters>>( // --
871 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode
872 "JSCallRuntime", // name
873 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs
874 parameters); // parameter
875 }
876
ConstructForwardVarargs(size_t arity,uint32_t start_index)877 const Operator* JSOperatorBuilder::ConstructForwardVarargs(
878 size_t arity, uint32_t start_index) {
879 ConstructForwardVarargsParameters parameters(arity, start_index);
880 return zone()->New<Operator1<ConstructForwardVarargsParameters>>( // --
881 IrOpcode::kJSConstructForwardVarargs, Operator::kNoProperties, // opcode
882 "JSConstructForwardVarargs", // name
883 parameters.arity(), 1, 1, 1, 1, 2, // counts
884 parameters); // parameter
885 }
886
887 // Note: frequency is taken by reference to work around a GCC bug
888 // on AIX (v8:8193).
Construct(uint32_t arity,CallFrequency const & frequency,FeedbackSource const & feedback)889 const Operator* JSOperatorBuilder::Construct(uint32_t arity,
890 CallFrequency const& frequency,
891 FeedbackSource const& feedback) {
892 ConstructParameters parameters(arity, frequency, feedback);
893 return zone()->New<Operator1<ConstructParameters>>( // --
894 IrOpcode::kJSConstruct, Operator::kNoProperties, // opcode
895 "JSConstruct", // name
896 parameters.arity(), 1, 1, 1, 1, 2, // counts
897 parameters); // parameter
898 }
899
ConstructWithArrayLike(CallFrequency const & frequency,FeedbackSource const & feedback)900 const Operator* JSOperatorBuilder::ConstructWithArrayLike(
901 CallFrequency const& frequency, FeedbackSource const& feedback) {
902 static constexpr int kTheArrayLikeObject = 1;
903 ConstructParameters parameters(
904 JSConstructWithArrayLikeNode::ArityForArgc(kTheArrayLikeObject),
905 frequency, feedback);
906 return zone()->New<Operator1<ConstructParameters>>( // --
907 IrOpcode::kJSConstructWithArrayLike, // opcode
908 Operator::kNoProperties, // properties
909 "JSConstructWithArrayLike", // name
910 parameters.arity(), 1, 1, 1, 1, 2, // counts
911 parameters); // parameter
912 }
913
ConstructWithSpread(uint32_t arity,CallFrequency const & frequency,FeedbackSource const & feedback)914 const Operator* JSOperatorBuilder::ConstructWithSpread(
915 uint32_t arity, CallFrequency const& frequency,
916 FeedbackSource const& feedback) {
917 ConstructParameters parameters(arity, frequency, feedback);
918 return zone()->New<Operator1<ConstructParameters>>( // --
919 IrOpcode::kJSConstructWithSpread, Operator::kNoProperties, // opcode
920 "JSConstructWithSpread", // name
921 parameters.arity(), 1, 1, 1, 1, 2, // counts
922 parameters); // parameter
923 }
924
LoadNamed(Handle<Name> name,const FeedbackSource & feedback)925 const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name,
926 const FeedbackSource& feedback) {
927 static constexpr int kObject = 1;
928 static constexpr int kFeedbackVector = 1;
929 static constexpr int kArity = kObject + kFeedbackVector;
930 NamedAccess access(LanguageMode::kSloppy, name, feedback);
931 return zone()->New<Operator1<NamedAccess>>( // --
932 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
933 "JSLoadNamed", // name
934 kArity, 1, 1, 1, 1, 2, // counts
935 access); // parameter
936 }
937
LoadNamedFromSuper(Handle<Name> name,const FeedbackSource & feedback)938 const Operator* JSOperatorBuilder::LoadNamedFromSuper(
939 Handle<Name> name, const FeedbackSource& feedback) {
940 static constexpr int kReceiver = 1;
941 static constexpr int kHomeObject = 1;
942 static constexpr int kFeedbackVector = 1;
943 static constexpr int kArity = kReceiver + kHomeObject + kFeedbackVector;
944 NamedAccess access(LanguageMode::kSloppy, name, feedback);
945 return zone()->New<Operator1<NamedAccess>>( // --
946 IrOpcode::kJSLoadNamedFromSuper, Operator::kNoProperties, // opcode
947 "JSLoadNamedFromSuper", // name
948 kArity, 1, 1, 1, 1, 2, // counts
949 access); // parameter
950 }
951
LoadProperty(FeedbackSource const & feedback)952 const Operator* JSOperatorBuilder::LoadProperty(
953 FeedbackSource const& feedback) {
954 PropertyAccess access(LanguageMode::kSloppy, feedback);
955 return zone()->New<Operator1<PropertyAccess>>( // --
956 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
957 "JSLoadProperty", // name
958 3, 1, 1, 1, 1, 2, // counts
959 access); // parameter
960 }
961
GetIterator(FeedbackSource const & load_feedback,FeedbackSource const & call_feedback)962 const Operator* JSOperatorBuilder::GetIterator(
963 FeedbackSource const& load_feedback, FeedbackSource const& call_feedback) {
964 GetIteratorParameters access(load_feedback, call_feedback);
965 return zone()->New<Operator1<GetIteratorParameters>>( // --
966 IrOpcode::kJSGetIterator, Operator::kNoProperties, // opcode
967 "JSGetIterator", // name
968 2, 1, 1, 1, 1, 2, // counts
969 access); // parameter
970 }
971
HasProperty(FeedbackSource const & feedback)972 const Operator* JSOperatorBuilder::HasProperty(FeedbackSource const& feedback) {
973 PropertyAccess access(LanguageMode::kSloppy, feedback);
974 return zone()->New<Operator1<PropertyAccess>>( // --
975 IrOpcode::kJSHasProperty, Operator::kNoProperties, // opcode
976 "JSHasProperty", // name
977 3, 1, 1, 1, 1, 2, // counts
978 access); // parameter
979 }
980
ForInNext(ForInMode mode,const FeedbackSource & feedback)981 const Operator* JSOperatorBuilder::ForInNext(ForInMode mode,
982 const FeedbackSource& feedback) {
983 return zone()->New<Operator1<ForInParameters>>( // --
984 IrOpcode::kJSForInNext, Operator::kNoProperties, // opcode
985 "JSForInNext", // name
986 5, 1, 1, 1, 1, 2, // counts
987 ForInParameters{feedback, mode}); // parameter
988 }
989
ForInPrepare(ForInMode mode,const FeedbackSource & feedback)990 const Operator* JSOperatorBuilder::ForInPrepare(
991 ForInMode mode, const FeedbackSource& feedback) {
992 return zone()->New<Operator1<ForInParameters>>( // --
993 IrOpcode::kJSForInPrepare, // opcode
994 Operator::kNoWrite | Operator::kNoThrow, // flags
995 "JSForInPrepare", // name
996 2, 1, 1, 3, 1, 1, // counts
997 ForInParameters{feedback, mode}); // parameter
998 }
999
GeneratorStore(int register_count)1000 const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
1001 return zone()->New<Operator1<int>>( // --
1002 IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode
1003 "JSGeneratorStore", // name
1004 3 + register_count, 1, 1, 0, 1, 0, // counts
1005 register_count); // parameter
1006 }
1007
RegisterCountOf(Operator const * op)1008 int RegisterCountOf(Operator const* op) {
1009 DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, op->opcode());
1010 return OpParameter<int>(op);
1011 }
1012
GeneratorStoreValueCountOf(const Operator * op)1013 int GeneratorStoreValueCountOf(const Operator* op) {
1014 DCHECK_EQ(IrOpcode::kJSGeneratorStore, op->opcode());
1015 return OpParameter<int>(op);
1016 }
1017
GeneratorRestoreRegister(int index)1018 const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) {
1019 return zone()->New<Operator1<int>>( // --
1020 IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow, // opcode
1021 "JSGeneratorRestoreRegister", // name
1022 1, 1, 1, 1, 1, 0, // counts
1023 index); // parameter
1024 }
1025
RestoreRegisterIndexOf(const Operator * op)1026 int RestoreRegisterIndexOf(const Operator* op) {
1027 DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, op->opcode());
1028 return OpParameter<int>(op);
1029 }
1030
StoreNamed(LanguageMode language_mode,Handle<Name> name,FeedbackSource const & feedback)1031 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
1032 Handle<Name> name,
1033 FeedbackSource const& feedback) {
1034 static constexpr int kObject = 1;
1035 static constexpr int kValue = 1;
1036 static constexpr int kFeedbackVector = 1;
1037 static constexpr int kArity = kObject + kValue + kFeedbackVector;
1038 NamedAccess access(language_mode, name, feedback);
1039 return zone()->New<Operator1<NamedAccess>>( // --
1040 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
1041 "JSStoreNamed", // name
1042 kArity, 1, 1, 0, 1, 2, // counts
1043 access); // parameter
1044 }
1045
StoreProperty(LanguageMode language_mode,FeedbackSource const & feedback)1046 const Operator* JSOperatorBuilder::StoreProperty(
1047 LanguageMode language_mode, FeedbackSource const& feedback) {
1048 PropertyAccess access(language_mode, feedback);
1049 return zone()->New<Operator1<PropertyAccess>>( // --
1050 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode
1051 "JSStoreProperty", // name
1052 4, 1, 1, 0, 1, 2, // counts
1053 access); // parameter
1054 }
1055
StoreNamedOwn(Handle<Name> name,FeedbackSource const & feedback)1056 const Operator* JSOperatorBuilder::StoreNamedOwn(
1057 Handle<Name> name, FeedbackSource const& feedback) {
1058 static constexpr int kObject = 1;
1059 static constexpr int kValue = 1;
1060 static constexpr int kFeedbackVector = 1;
1061 static constexpr int kArity = kObject + kValue + kFeedbackVector;
1062 StoreNamedOwnParameters parameters(name, feedback);
1063 return zone()->New<Operator1<StoreNamedOwnParameters>>( // --
1064 IrOpcode::kJSStoreNamedOwn, Operator::kNoProperties, // opcode
1065 "JSStoreNamedOwn", // name
1066 kArity, 1, 1, 0, 1, 2, // counts
1067 parameters); // parameter
1068 }
1069
DeleteProperty()1070 const Operator* JSOperatorBuilder::DeleteProperty() {
1071 return zone()->New<Operator>( // --
1072 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode
1073 "JSDeleteProperty", // name
1074 3, 1, 1, 1, 1, 2); // counts
1075 }
1076
CreateGeneratorObject()1077 const Operator* JSOperatorBuilder::CreateGeneratorObject() {
1078 return zone()->New<Operator>( // --
1079 IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable, // opcode
1080 "JSCreateGeneratorObject", // name
1081 2, 1, 1, 1, 1, 0); // counts
1082 }
1083
LoadGlobal(const Handle<Name> & name,const FeedbackSource & feedback,TypeofMode typeof_mode)1084 const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
1085 const FeedbackSource& feedback,
1086 TypeofMode typeof_mode) {
1087 static constexpr int kFeedbackVector = 1;
1088 static constexpr int kArity = kFeedbackVector;
1089 LoadGlobalParameters parameters(name, feedback, typeof_mode);
1090 return zone()->New<Operator1<LoadGlobalParameters>>( // --
1091 IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode
1092 "JSLoadGlobal", // name
1093 kArity, 1, 1, 1, 1, 2, // counts
1094 parameters); // parameter
1095 }
1096
StoreGlobal(LanguageMode language_mode,const Handle<Name> & name,const FeedbackSource & feedback)1097 const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
1098 const Handle<Name>& name,
1099 const FeedbackSource& feedback) {
1100 static constexpr int kValue = 1;
1101 static constexpr int kFeedbackVector = 1;
1102 static constexpr int kArity = kValue + kFeedbackVector;
1103 StoreGlobalParameters parameters(language_mode, feedback, name);
1104 return zone()->New<Operator1<StoreGlobalParameters>>( // --
1105 IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode
1106 "JSStoreGlobal", // name
1107 kArity, 1, 1, 0, 1, 2, // counts
1108 parameters); // parameter
1109 }
1110
HasContextExtension(size_t depth)1111 const Operator* JSOperatorBuilder::HasContextExtension(size_t depth) {
1112 return zone()->New<Operator1<size_t>>( // --
1113 IrOpcode::kJSHasContextExtension, // opcode
1114 Operator::kNoWrite | Operator::kNoThrow, // flags
1115 "JSHasContextExtension", // name
1116 0, 1, 0, 1, 1, 0, // counts
1117 depth); // parameter
1118 }
1119
LoadContext(size_t depth,size_t index,bool immutable)1120 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
1121 bool immutable) {
1122 ContextAccess access(depth, index, immutable);
1123 return zone()->New<Operator1<ContextAccess>>( // --
1124 IrOpcode::kJSLoadContext, // opcode
1125 Operator::kNoWrite | Operator::kNoThrow, // flags
1126 "JSLoadContext", // name
1127 0, 1, 0, 1, 1, 0, // counts
1128 access); // parameter
1129 }
1130
1131
StoreContext(size_t depth,size_t index)1132 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
1133 ContextAccess access(depth, index, false);
1134 return zone()->New<Operator1<ContextAccess>>( // --
1135 IrOpcode::kJSStoreContext, // opcode
1136 Operator::kNoRead | Operator::kNoThrow, // flags
1137 "JSStoreContext", // name
1138 1, 1, 1, 0, 1, 0, // counts
1139 access); // parameter
1140 }
1141
LoadModule(int32_t cell_index)1142 const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) {
1143 return zone()->New<Operator1<int32_t>>( // --
1144 IrOpcode::kJSLoadModule, // opcode
1145 Operator::kNoWrite | Operator::kNoThrow, // flags
1146 "JSLoadModule", // name
1147 1, 1, 1, 1, 1, 0, // counts
1148 cell_index); // parameter
1149 }
1150
GetImportMeta()1151 const Operator* JSOperatorBuilder::GetImportMeta() {
1152 return zone()->New<Operator>( // --
1153 IrOpcode::kJSGetImportMeta, // opcode
1154 Operator::kNoProperties, // flags
1155 "JSGetImportMeta", // name
1156 0, 1, 1, 1, 1, 2); // counts
1157 }
1158
StoreModule(int32_t cell_index)1159 const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) {
1160 return zone()->New<Operator1<int32_t>>( // --
1161 IrOpcode::kJSStoreModule, // opcode
1162 Operator::kNoRead | Operator::kNoThrow, // flags
1163 "JSStoreModule", // name
1164 2, 1, 1, 0, 1, 0, // counts
1165 cell_index); // parameter
1166 }
1167
CreateArguments(CreateArgumentsType type)1168 const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
1169 return zone()->New<Operator1<CreateArgumentsType>>( // --
1170 IrOpcode::kJSCreateArguments, Operator::kEliminatable, // opcode
1171 "JSCreateArguments", // name
1172 1, 1, 0, 1, 1, 0, // counts
1173 type); // parameter
1174 }
1175
CreateArray(size_t arity,MaybeHandle<AllocationSite> site)1176 const Operator* JSOperatorBuilder::CreateArray(
1177 size_t arity, MaybeHandle<AllocationSite> site) {
1178 // constructor, new_target, arg1, ..., argN
1179 int const value_input_count = static_cast<int>(arity) + 2;
1180 CreateArrayParameters parameters(arity, site);
1181 return zone()->New<Operator1<CreateArrayParameters>>( // --
1182 IrOpcode::kJSCreateArray, Operator::kNoProperties, // opcode
1183 "JSCreateArray", // name
1184 value_input_count, 1, 1, 1, 1, 2, // counts
1185 parameters); // parameter
1186 }
1187
CreateArrayIterator(IterationKind kind)1188 const Operator* JSOperatorBuilder::CreateArrayIterator(IterationKind kind) {
1189 CreateArrayIteratorParameters parameters(kind);
1190 return zone()->New<Operator1<CreateArrayIteratorParameters>>( // --
1191 IrOpcode::kJSCreateArrayIterator, Operator::kEliminatable, // opcode
1192 "JSCreateArrayIterator", // name
1193 1, 1, 1, 1, 1, 0, // counts
1194 parameters); // parameter
1195 }
1196
CreateAsyncFunctionObject(int register_count)1197 const Operator* JSOperatorBuilder::CreateAsyncFunctionObject(
1198 int register_count) {
1199 return zone()->New<Operator1<int>>( // --
1200 IrOpcode::kJSCreateAsyncFunctionObject, // opcode
1201 Operator::kEliminatable, // flags
1202 "JSCreateAsyncFunctionObject", // name
1203 3, 1, 1, 1, 1, 0, // counts
1204 register_count); // parameter
1205 }
1206
CreateCollectionIterator(CollectionKind collection_kind,IterationKind iteration_kind)1207 const Operator* JSOperatorBuilder::CreateCollectionIterator(
1208 CollectionKind collection_kind, IterationKind iteration_kind) {
1209 CreateCollectionIteratorParameters parameters(collection_kind,
1210 iteration_kind);
1211 return zone()->New<Operator1<CreateCollectionIteratorParameters>>(
1212 IrOpcode::kJSCreateCollectionIterator, Operator::kEliminatable,
1213 "JSCreateCollectionIterator", 1, 1, 1, 1, 1, 0, parameters);
1214 }
1215
CreateBoundFunction(size_t arity,Handle<Map> map)1216 const Operator* JSOperatorBuilder::CreateBoundFunction(size_t arity,
1217 Handle<Map> map) {
1218 // bound_target_function, bound_this, arg1, ..., argN
1219 int const value_input_count = static_cast<int>(arity) + 2;
1220 CreateBoundFunctionParameters parameters(arity, map);
1221 return zone()->New<Operator1<CreateBoundFunctionParameters>>( // --
1222 IrOpcode::kJSCreateBoundFunction, Operator::kEliminatable, // opcode
1223 "JSCreateBoundFunction", // name
1224 value_input_count, 1, 1, 1, 1, 0, // counts
1225 parameters); // parameter
1226 }
1227
CreateClosure(Handle<SharedFunctionInfo> shared_info,Handle<Code> code,AllocationType allocation)1228 const Operator* JSOperatorBuilder::CreateClosure(
1229 Handle<SharedFunctionInfo> shared_info, Handle<Code> code,
1230 AllocationType allocation) {
1231 static constexpr int kFeedbackCell = 1;
1232 static constexpr int kArity = kFeedbackCell;
1233 CreateClosureParameters parameters(shared_info, code, allocation);
1234 return zone()->New<Operator1<CreateClosureParameters>>( // --
1235 IrOpcode::kJSCreateClosure, Operator::kEliminatable, // opcode
1236 "JSCreateClosure", // name
1237 kArity, 1, 1, 1, 1, 0, // counts
1238 parameters); // parameter
1239 }
1240
CreateLiteralArray(Handle<ArrayBoilerplateDescription> description,FeedbackSource const & feedback,int literal_flags,int number_of_elements)1241 const Operator* JSOperatorBuilder::CreateLiteralArray(
1242 Handle<ArrayBoilerplateDescription> description,
1243 FeedbackSource const& feedback, int literal_flags, int number_of_elements) {
1244 CreateLiteralParameters parameters(description, feedback, number_of_elements,
1245 literal_flags);
1246 return zone()->New<Operator1<CreateLiteralParameters>>( // --
1247 IrOpcode::kJSCreateLiteralArray, // opcode
1248 Operator::kNoProperties, // properties
1249 "JSCreateLiteralArray", // name
1250 1, 1, 1, 1, 1, 2, // counts
1251 parameters); // parameter
1252 }
1253
CreateEmptyLiteralArray(FeedbackSource const & feedback)1254 const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
1255 FeedbackSource const& feedback) {
1256 static constexpr int kFeedbackVector = 1;
1257 static constexpr int kArity = kFeedbackVector;
1258 FeedbackParameter parameters(feedback);
1259 return zone()->New<Operator1<FeedbackParameter>>( // --
1260 IrOpcode::kJSCreateEmptyLiteralArray, // opcode
1261 Operator::kEliminatable, // properties
1262 "JSCreateEmptyLiteralArray", // name
1263 kArity, 1, 1, 1, 1, 0, // counts
1264 parameters); // parameter
1265 }
1266
CreateArrayFromIterable()1267 const Operator* JSOperatorBuilder::CreateArrayFromIterable() {
1268 return zone()->New<Operator>( // --
1269 IrOpcode::kJSCreateArrayFromIterable, // opcode
1270 Operator::kNoProperties, // properties
1271 "JSCreateArrayFromIterable", // name
1272 1, 1, 1, 1, 1, 2); // counts
1273 }
1274
CreateLiteralObject(Handle<ObjectBoilerplateDescription> constant_properties,FeedbackSource const & feedback,int literal_flags,int number_of_properties)1275 const Operator* JSOperatorBuilder::CreateLiteralObject(
1276 Handle<ObjectBoilerplateDescription> constant_properties,
1277 FeedbackSource const& feedback, int literal_flags,
1278 int number_of_properties) {
1279 CreateLiteralParameters parameters(constant_properties, feedback,
1280 number_of_properties, literal_flags);
1281 return zone()->New<Operator1<CreateLiteralParameters>>( // --
1282 IrOpcode::kJSCreateLiteralObject, // opcode
1283 Operator::kNoProperties, // properties
1284 "JSCreateLiteralObject", // name
1285 1, 1, 1, 1, 1, 2, // counts
1286 parameters); // parameter
1287 }
1288
GetTemplateObject(Handle<TemplateObjectDescription> description,Handle<SharedFunctionInfo> shared,FeedbackSource const & feedback)1289 const Operator* JSOperatorBuilder::GetTemplateObject(
1290 Handle<TemplateObjectDescription> description,
1291 Handle<SharedFunctionInfo> shared, FeedbackSource const& feedback) {
1292 GetTemplateObjectParameters parameters(description, shared, feedback);
1293 return zone()->New<Operator1<GetTemplateObjectParameters>>( // --
1294 IrOpcode::kJSGetTemplateObject, // opcode
1295 Operator::kEliminatable, // properties
1296 "JSGetTemplateObject", // name
1297 1, 1, 1, 1, 1, 0, // counts
1298 parameters); // parameter
1299 }
1300
CloneObject(FeedbackSource const & feedback,int literal_flags)1301 const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback,
1302 int literal_flags) {
1303 CloneObjectParameters parameters(feedback, literal_flags);
1304 return zone()->New<Operator1<CloneObjectParameters>>( // --
1305 IrOpcode::kJSCloneObject, // opcode
1306 Operator::kNoProperties, // properties
1307 "JSCloneObject", // name
1308 2, 1, 1, 1, 1, 2, // counts
1309 parameters); // parameter
1310 }
1311
StackCheck(StackCheckKind kind)1312 const Operator* JSOperatorBuilder::StackCheck(StackCheckKind kind) {
1313 return zone()->New<Operator1<StackCheckKind>>( // --
1314 IrOpcode::kJSStackCheck, // opcode
1315 Operator::kNoWrite, // properties
1316 "JSStackCheck", // name
1317 0, 1, 1, 0, 1, 2, // counts
1318 kind); // parameter
1319 }
1320
CreateEmptyLiteralObject()1321 const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
1322 return zone()->New<Operator>( // --
1323 IrOpcode::kJSCreateEmptyLiteralObject, // opcode
1324 Operator::kNoProperties, // properties
1325 "JSCreateEmptyLiteralObject", // name
1326 0, 1, 1, 1, 1, 2); // counts
1327 }
1328
CreateLiteralRegExp(Handle<String> constant_pattern,FeedbackSource const & feedback,int literal_flags)1329 const Operator* JSOperatorBuilder::CreateLiteralRegExp(
1330 Handle<String> constant_pattern, FeedbackSource const& feedback,
1331 int literal_flags) {
1332 CreateLiteralParameters parameters(constant_pattern, feedback, -1,
1333 literal_flags);
1334 return zone()->New<Operator1<CreateLiteralParameters>>( // --
1335 IrOpcode::kJSCreateLiteralRegExp, // opcode
1336 Operator::kNoProperties, // properties
1337 "JSCreateLiteralRegExp", // name
1338 1, 1, 1, 1, 1, 2, // counts
1339 parameters); // parameter
1340 }
1341
CreateFunctionContext(Handle<ScopeInfo> scope_info,int slot_count,ScopeType scope_type)1342 const Operator* JSOperatorBuilder::CreateFunctionContext(
1343 Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type) {
1344 CreateFunctionContextParameters parameters(scope_info, slot_count,
1345 scope_type);
1346 return zone()->New<Operator1<CreateFunctionContextParameters>>( // --
1347 IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties, // opcode
1348 "JSCreateFunctionContext", // name
1349 0, 1, 1, 1, 1, 2, // counts
1350 parameters); // parameter
1351 }
1352
CreateCatchContext(const Handle<ScopeInfo> & scope_info)1353 const Operator* JSOperatorBuilder::CreateCatchContext(
1354 const Handle<ScopeInfo>& scope_info) {
1355 return zone()->New<Operator1<Handle<ScopeInfo>>>(
1356 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode
1357 "JSCreateCatchContext", // name
1358 1, 1, 1, 1, 1, 2, // counts
1359 scope_info); // parameter
1360 }
1361
CreateWithContext(const Handle<ScopeInfo> & scope_info)1362 const Operator* JSOperatorBuilder::CreateWithContext(
1363 const Handle<ScopeInfo>& scope_info) {
1364 return zone()->New<Operator1<Handle<ScopeInfo>>>(
1365 IrOpcode::kJSCreateWithContext, Operator::kNoProperties, // opcode
1366 "JSCreateWithContext", // name
1367 1, 1, 1, 1, 1, 2, // counts
1368 scope_info); // parameter
1369 }
1370
CreateBlockContext(const Handle<ScopeInfo> & scope_info)1371 const Operator* JSOperatorBuilder::CreateBlockContext(
1372 const Handle<ScopeInfo>& scope_info) {
1373 return zone()->New<Operator1<Handle<ScopeInfo>>>( // --
1374 IrOpcode::kJSCreateBlockContext, Operator::kNoProperties, // opcode
1375 "JSCreateBlockContext", // name
1376 0, 1, 1, 1, 1, 2, // counts
1377 scope_info); // parameter
1378 }
1379
ScopeInfoOf(const Operator * op)1380 Handle<ScopeInfo> ScopeInfoOf(const Operator* op) {
1381 DCHECK(IrOpcode::kJSCreateBlockContext == op->opcode() ||
1382 IrOpcode::kJSCreateWithContext == op->opcode() ||
1383 IrOpcode::kJSCreateCatchContext == op->opcode());
1384 return OpParameter<Handle<ScopeInfo>>(op);
1385 }
1386
1387 #undef CACHED_OP_LIST
1388
1389 } // namespace compiler
1390 } // namespace internal
1391 } // namespace v8
1392