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