v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
simplified-operator.cc
Go to the documentation of this file.
1// Copyright 2012 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
6
9#include "src/base/logging.h"
14#include "src/handles/handles-inl.h" // for operator<<
16#include "src/objects/map.h"
17#include "src/objects/name.h"
18
19#if V8_ENABLE_WEBASSEMBLY
21#endif
22
23namespace v8 {
24namespace internal {
25namespace compiler {
26
27size_t hash_value(BaseTaggedness base_taggedness) {
28 return static_cast<uint8_t>(base_taggedness);
29}
30
31std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
32 switch (base_taggedness) {
33 case kUntaggedBase:
34 return os << "untagged base";
35 case kTaggedBase:
36 return os << "tagged base";
37 }
39}
40
41std::ostream& operator<<(std::ostream& os,
42 ConstFieldInfo const& const_field_info) {
43 if (const_field_info.IsConst()) {
44 return os << "const (field owner: "
45 << Brief(*const_field_info.owner_map->object()) << ")";
46 } else {
47 return os << "mutable";
48 }
50}
51
52bool operator==(ConstFieldInfo const& lhs, ConstFieldInfo const& rhs) {
53 return lhs.owner_map == rhs.owner_map;
54}
55
56size_t hash_value(ConstFieldInfo const& const_field_info) {
57 return hash_value(const_field_info.owner_map);
58}
59
60bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
61 // On purpose we don't include the write barrier kind here, as this method is
62 // really only relevant for eliminating loads and they don't care about the
63 // write barrier mode.
64 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
65 lhs.map == rhs.map && lhs.machine_type == rhs.machine_type &&
68}
69
70size_t hash_value(FieldAccess const& access) {
71 // On purpose we don't include the write barrier kind here, as this method is
72 // really only relevant for eliminating loads and they don't care about the
73 // write barrier mode.
74 return base::hash_combine(access.base_is_tagged, access.offset,
75 access.machine_type, access.const_field_info,
76 access.is_store_in_literal);
77}
78
79std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
80 os << "[";
81 if (access.creator_mnemonic != nullptr) {
82 os << access.creator_mnemonic << ", ";
83 }
84 os << access.base_is_tagged << ", " << access.offset << ", ";
85#ifdef OBJECT_PRINT
87 if (access.name.ToHandle(&name)) {
88 name->NamePrint(os);
89 os << ", ";
90 }
91 if (access.map.has_value()) {
92 os << Brief(*access.map->object()) << ", ";
93 }
94#endif
95 os << access.type << ", " << access.machine_type << ", "
96 << access.write_barrier_kind << ", " << access.const_field_info;
97 if (access.is_store_in_literal) {
98 os << " (store in literal)";
99 }
100 if (access.maybe_initializing_or_transitioning_store) {
101 os << " (initializing or transitioning store)";
102 }
103 os << "]";
104 return os;
105}
106
107template <>
109 PrintVerbosity verbose) const {
110 if (verbose == PrintVerbosity::kVerbose) {
111 os << parameter();
112 } else {
113 os << "[+" << parameter().offset << "]";
114 }
115}
116
117bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
118 // On purpose we don't include the write barrier kind here, as this method is
119 // really only relevant for eliminating loads and they don't care about the
120 // write barrier mode.
121 return lhs.base_is_tagged == rhs.base_is_tagged &&
122 lhs.header_size == rhs.header_size &&
123 lhs.machine_type == rhs.machine_type;
124}
125
126size_t hash_value(ElementAccess const& access) {
127 // On purpose we don't include the write barrier kind here, as this method is
128 // really only relevant for eliminating loads and they don't care about the
129 // write barrier mode.
130 return base::hash_combine(access.base_is_tagged, access.header_size,
131 access.machine_type);
132}
133
134std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
135 os << access.base_is_tagged << ", " << access.header_size << ", "
136 << access.type << ", " << access.machine_type << ", "
137 << access.write_barrier_kind;
138 return os;
139}
140
141bool operator==(ObjectAccess const& lhs, ObjectAccess const& rhs) {
142 return lhs.machine_type == rhs.machine_type &&
144}
145
146size_t hash_value(ObjectAccess const& access) {
147 return base::hash_combine(access.machine_type, access.write_barrier_kind);
148}
149
150std::ostream& operator<<(std::ostream& os, ObjectAccess const& access) {
151 os << access.machine_type << ", " << access.write_barrier_kind;
152 return os;
153}
154
155#if V8_ENABLE_WEBASSEMBLY
156
157V8_EXPORT_PRIVATE bool operator==(WasmFieldInfo const& lhs,
158 WasmFieldInfo const& rhs) {
159 return lhs.field_index == rhs.field_index && lhs.type == rhs.type &&
160 lhs.is_signed == rhs.is_signed && lhs.null_check == rhs.null_check;
161}
162
163size_t hash_value(WasmFieldInfo const& info) {
164 return base::hash_combine(info.field_index, info.type, info.is_signed,
165 info.null_check);
166}
167
168V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
169 WasmFieldInfo const& info) {
170 return os << info.field_index << ", "
171 << (info.is_signed ? "signed" : "unsigned") << ", "
172 << (info.null_check == kWithNullCheck ? "null check"
173 : "no null check");
174}
175
176V8_EXPORT_PRIVATE bool operator==(WasmElementInfo const& lhs,
177 WasmElementInfo const& rhs) {
178 return lhs.type == rhs.type && lhs.is_signed == rhs.is_signed;
179}
180
181size_t hash_value(WasmElementInfo const& info) {
182 return base::hash_combine(info.type, info.is_signed);
183}
184
185V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
186 WasmElementInfo const& info) {
187 return os << (info.is_signed ? "signed" : "unsigned");
188}
189
190#endif
191
193 DCHECK_NOT_NULL(op);
194 DCHECK(op->opcode() == IrOpcode::kLoadField ||
195 op->opcode() == IrOpcode::kStoreField);
196 return OpParameter<FieldAccess>(op);
197}
198
200 DCHECK_NOT_NULL(op);
201 DCHECK(op->opcode() == IrOpcode::kLoadElement ||
202 op->opcode() == IrOpcode::kStoreElement);
204}
205
207 DCHECK_NOT_NULL(op);
208 DCHECK(op->opcode() == IrOpcode::kLoadFromObject ||
209 op->opcode() == IrOpcode::kLoadImmutableFromObject ||
210 op->opcode() == IrOpcode::kStoreToObject ||
211 op->opcode() == IrOpcode::kInitializeImmutableInObject);
212 return OpParameter<ObjectAccess>(op);
213}
214
216 DCHECK(op->opcode() == IrOpcode::kLoadTypedElement ||
217 op->opcode() == IrOpcode::kLoadDataViewElement ||
218 op->opcode() == IrOpcode::kStoreTypedElement ||
219 op->opcode() == IrOpcode::kStoreDataViewElement);
221}
222
224 DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
226}
227
229 return static_cast<size_t>(mode);
230}
231
232std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
233 switch (mode) {
235 return os << "allow-return-hole";
237 return os << "never-return-hole";
238 }
239 UNREACHABLE();
240}
241
243 Operator const* op) {
244 DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
246}
247
248std::ostream& operator<<(std::ostream& os,
249 CheckFloat64HoleParameters const& params) {
250 return os << params.mode() << ", " << params.feedback();
251}
252
254 FeedbackSource::Hash feedback_hash;
255 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
256}
257
259 CheckFloat64HoleParameters const& rhs) {
260 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
261}
262
264 CheckFloat64HoleParameters const& rhs) {
265 return !(lhs == rhs);
266}
267
269 DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
270 op->opcode() == IrOpcode::kCheckedInt32Mul);
272}
273
274std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
276 return os << "TryMigrateInstance";
278 return os << "TryMigrateInstanceAndDeopt";
279 } else {
280 return os << "None";
281 }
282}
283
285 CheckMapsParameters const& rhs) {
286 return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
287 lhs.feedback() == rhs.feedback();
288}
289
291 FeedbackSource::Hash feedback_hash;
292 return base::hash_combine(p.flags(), p.maps(), feedback_hash(p.feedback()));
293}
294
295std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
296 return os << p.flags() << ", " << p.maps() << ", " << p.feedback();
297}
298
300 DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
302}
303
305 DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
306 return OpParameter<ZoneRefSet<Map>>(op);
307}
308
310 DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
311 return OpParameter<ZoneRefSet<Map>>(op);
312}
313
315 return static_cast<size_t>(mode);
316}
317
318std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
319 switch (mode) {
321 return os << "AdditiveSafeInteger";
323 return os << "Number";
325 return os << "NumberOrBoolean";
327 return os << "NumberOrOddball";
328 }
329 UNREACHABLE();
330}
331
332std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) {
333 switch (mode) {
335 return os << "DoubleElements";
337 return os << "SmiOrObjectElements";
338 }
339 UNREACHABLE();
340}
341
343 const GrowFastElementsParameters& rhs) {
344 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
345}
346
347inline size_t hash_value(const GrowFastElementsParameters& params) {
348 FeedbackSource::Hash feedback_hash;
349 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
350}
351
352std::ostream& operator<<(std::ostream& os,
353 const GrowFastElementsParameters& params) {
354 return os << params.mode() << ", " << params.feedback();
355}
356
358 const Operator* op) {
359 DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
361}
362
364 return lhs.mode() == rhs.mode() && lhs.source() == rhs.source() &&
365 lhs.target() == rhs.target();
366}
367
370 if (lhs.target() != rhs.target()) return false;
371 return lhs.sources() == rhs.sources();
372}
373
374size_t hash_value(ElementsTransition transition) {
375 return base::hash_combine(static_cast<uint8_t>(transition.mode()),
376 transition.source(), transition.target());
377}
378
380 return base::hash_combine(transition.target(), transition.sources());
381}
382
383std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
384 switch (transition.mode()) {
386 return os << "fast-transition from "
387 << Brief(*transition.source().object()) << " to "
388 << Brief(*transition.target().object());
390 return os << "slow-transition from "
391 << Brief(*transition.source().object()) << " to "
392 << Brief(*transition.target().object());
393 }
394 UNREACHABLE();
395}
396
397std::ostream& operator<<(std::ostream& os,
399 os << "transition from (";
400 bool first = true;
401 for (MapRef source : transition.sources()) {
402 if (!first) {
403 os << ", ";
404 }
405 first = false;
406 os << Brief(*source.object());
407 }
408 os << ") to " << Brief(*transition.target().object());
409 return os;
410}
411
413 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
415}
416
417ElementsTransitionWithMultipleSources const&
419 DCHECK_EQ(IrOpcode::kTransitionElementsKindOrCheckMap, op->opcode());
421}
422
423namespace {
424
425// Parameters for the TransitionAndStoreElement opcode.
426class TransitionAndStoreElementParameters final {
427 public:
428 TransitionAndStoreElementParameters(MapRef double_map, MapRef fast_map);
429
430 MapRef double_map() const { return double_map_; }
431 MapRef fast_map() const { return fast_map_; }
432
433 private:
434 MapRef const double_map_;
435 MapRef const fast_map_;
436};
437
438TransitionAndStoreElementParameters::TransitionAndStoreElementParameters(
439 MapRef double_map, MapRef fast_map)
440 : double_map_(double_map), fast_map_(fast_map) {}
441
442bool operator==(TransitionAndStoreElementParameters const& lhs,
443 TransitionAndStoreElementParameters const& rhs) {
444 return lhs.fast_map() == rhs.fast_map() &&
445 lhs.double_map() == rhs.double_map();
446}
447
448size_t hash_value(TransitionAndStoreElementParameters parameters) {
449 return base::hash_combine(parameters.fast_map(), parameters.double_map());
450}
451
452std::ostream& operator<<(std::ostream& os,
453 TransitionAndStoreElementParameters parameters) {
454 return os << "fast-map" << Brief(*parameters.fast_map().object())
455 << " double-map" << Brief(*parameters.double_map().object());
456}
457
458} // namespace
459
460namespace {
461
462// Parameters for the TransitionAndStoreNonNumberElement opcode.
463class TransitionAndStoreNonNumberElementParameters final {
464 public:
465 TransitionAndStoreNonNumberElementParameters(MapRef fast_map,
466 Type value_type);
467
468 MapRef fast_map() const { return fast_map_; }
469 Type value_type() const { return value_type_; }
470
471 private:
472 MapRef const fast_map_;
474};
475
476TransitionAndStoreNonNumberElementParameters::
477 TransitionAndStoreNonNumberElementParameters(MapRef fast_map,
478 Type value_type)
479 : fast_map_(fast_map), value_type_(value_type) {}
480
481bool operator==(TransitionAndStoreNonNumberElementParameters const& lhs,
482 TransitionAndStoreNonNumberElementParameters const& rhs) {
483 return lhs.fast_map() == rhs.fast_map() &&
484 lhs.value_type() == rhs.value_type();
485}
486
487size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
488 return base::hash_combine(parameters.fast_map(), parameters.value_type());
489}
490
491std::ostream& operator<<(
492 std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) {
493 return os << parameters.value_type() << ", fast-map"
494 << Brief(*parameters.fast_map().object());
495}
496
497} // namespace
498
499namespace {
500
501// Parameters for the TransitionAndStoreNumberElement opcode.
502class TransitionAndStoreNumberElementParameters final {
503 public:
504 explicit TransitionAndStoreNumberElementParameters(MapRef double_map);
505
506 MapRef double_map() const { return double_map_; }
507
508 private:
509 MapRef const double_map_;
510};
511
512TransitionAndStoreNumberElementParameters::
513 TransitionAndStoreNumberElementParameters(MapRef double_map)
514 : double_map_(double_map) {}
515
516bool operator==(TransitionAndStoreNumberElementParameters const& lhs,
517 TransitionAndStoreNumberElementParameters const& rhs) {
518 return lhs.double_map() == rhs.double_map();
519}
520
521size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
522 return base::hash_combine(parameters.double_map());
523}
524
525std::ostream& operator<<(std::ostream& os,
526 TransitionAndStoreNumberElementParameters parameters) {
527 return os << "double-map" << Brief(*parameters.double_map().object());
528}
529
530} // namespace
531
533 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
534 return OpParameter<TransitionAndStoreElementParameters>(op).double_map();
535 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) {
536 return OpParameter<TransitionAndStoreNumberElementParameters>(op)
537 .double_map();
538 }
539 UNREACHABLE();
540}
541
543 DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
544 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
545 .value_type();
546}
547
549 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
550 return OpParameter<TransitionAndStoreElementParameters>(op).fast_map();
551 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) {
552 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
553 .fast_map();
554 }
555 UNREACHABLE();
556}
557
558std::ostream& operator<<(std::ostream& os, BigIntOperationHint hint) {
559 switch (hint) {
560 case BigIntOperationHint::kBigInt:
561 return os << "BigInt";
562 case BigIntOperationHint::kBigInt64:
563 return os << "BigInt64";
564 }
565 UNREACHABLE();
566}
567
568size_t hash_value(BigIntOperationHint hint) {
569 return static_cast<uint8_t>(hint);
570}
571
572std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
573 switch (hint) {
574 case NumberOperationHint::kSignedSmall:
575 return os << "SignedSmall";
576 case NumberOperationHint::kSignedSmallInputs:
577 return os << "SignedSmallInputs";
578 case NumberOperationHint::kAdditiveSafeInteger:
579 return os << "AdditiveSafeInteger";
580 case NumberOperationHint::kNumber:
581 return os << "Number";
582 case NumberOperationHint::kNumberOrBoolean:
583 return os << "NumberOrBoolean";
584 case NumberOperationHint::kNumberOrOddball:
585 return os << "NumberOrOddball";
586 }
587 UNREACHABLE();
588}
589
590size_t hash_value(NumberOperationHint hint) {
591 return static_cast<uint8_t>(hint);
592}
593
595 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
596 op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
597 op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
598 op->opcode() == IrOpcode::kSpeculativeNumberPow ||
599 op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
600 op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
601 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
602 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
603 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
604 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
605 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
606 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
607 op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
608 op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
609 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
610 op->opcode() == IrOpcode::kSpeculativeAdditiveSafeIntegerAdd ||
611 op->opcode() == IrOpcode::kSpeculativeAdditiveSafeIntegerSubtract ||
612 op->opcode() == IrOpcode::kSpeculativeSmallIntegerAdd ||
613 op->opcode() == IrOpcode::kSpeculativeSmallIntegerSubtract);
614 return OpParameter<NumberOperationHint>(op);
615}
616
618 // TODO(panq): Expand the DCHECK when more BigInt operations are supported.
619 DCHECK(op->opcode() == IrOpcode::kSpeculativeBigIntAdd ||
620 op->opcode() == IrOpcode::kSpeculativeBigIntSubtract ||
621 op->opcode() == IrOpcode::kSpeculativeBigIntMultiply ||
622 op->opcode() == IrOpcode::kSpeculativeBigIntDivide ||
623 op->opcode() == IrOpcode::kSpeculativeBigIntModulus ||
624 op->opcode() == IrOpcode::kSpeculativeBigIntBitwiseAnd ||
625 op->opcode() == IrOpcode::kSpeculativeBigIntBitwiseOr ||
626 op->opcode() == IrOpcode::kSpeculativeBigIntBitwiseXor ||
627 op->opcode() == IrOpcode::kSpeculativeBigIntShiftLeft ||
628 op->opcode() == IrOpcode::kSpeculativeBigIntShiftRight ||
629 op->opcode() == IrOpcode::kSpeculativeBigIntEqual ||
630 op->opcode() == IrOpcode::kSpeculativeBigIntLessThan ||
631 op->opcode() == IrOpcode::kSpeculativeBigIntLessThanOrEqual);
632 BigIntOperationHint hint = OpParameter<BigIntOperationHint>(op);
633 DCHECK_IMPLIES(hint == BigIntOperationHint::kBigInt64, Is64());
634 return hint;
635}
636
637bool operator==(NumberOperationParameters const& lhs,
638 NumberOperationParameters const& rhs) {
639 return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
640}
641
642size_t hash_value(NumberOperationParameters const& p) {
643 FeedbackSource::Hash feedback_hash;
644 return base::hash_combine(p.hint(), feedback_hash(p.feedback()));
645}
646
647std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) {
648 return os << p.hint() << ", " << p.feedback();
649}
650
652 Operator const* op) {
653 DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
654 return OpParameter<NumberOperationParameters>(op);
655}
656
657bool operator==(BigIntOperationParameters const& lhs,
658 BigIntOperationParameters const& rhs) {
659 return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
660}
661
662size_t hash_value(BigIntOperationParameters const& p) {
663 FeedbackSource::Hash feedback_hash;
664 return base::hash_combine(p.hint(), feedback_hash(p.feedback()));
665}
666
667std::ostream& operator<<(std::ostream& os, BigIntOperationParameters const& p) {
668 return os << p.hint() << ", " << p.feedback();
669}
670
672 Operator const* op) {
673 DCHECK_EQ(IrOpcode::kSpeculativeToBigInt, op->opcode());
674 return OpParameter<BigIntOperationParameters>(op);
675}
676
677bool operator==(SpeculativeBigIntAsNParameters const& lhs,
679 return lhs.bits() == rhs.bits() && lhs.feedback() == rhs.feedback();
680}
681
682size_t hash_value(SpeculativeBigIntAsNParameters const& p) {
683 FeedbackSource::Hash feedback_hash;
684 return base::hash_combine(p.bits(), feedback_hash(p.feedback()));
685}
686
687std::ostream& operator<<(std::ostream& os,
689 return os << p.bits() << ", " << p.feedback();
690}
691
693 Operator const* op) {
694 DCHECK(op->opcode() == IrOpcode::kSpeculativeBigIntAsUintN ||
695 op->opcode() == IrOpcode::kSpeculativeBigIntAsIntN);
696 return OpParameter<SpeculativeBigIntAsNParameters>(op);
697}
698
699size_t hash_value(AllocateParameters info) {
700 return base::hash_combine(info.type(),
701 static_cast<int>(info.allocation_type()));
702}
703
704V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
705 AllocateParameters info) {
706 return os << info.type() << ", " << info.allocation_type();
707}
708
709bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
710 return lhs.allocation_type() == rhs.allocation_type() &&
711 lhs.type() == rhs.type();
712}
713
715 DCHECK(op->opcode() == IrOpcode::kAllocate ||
716 op->opcode() == IrOpcode::kAllocateRaw);
717 return OpParameter<AllocateParameters>(op);
718}
719
721 if (op->opcode() == IrOpcode::kNewDoubleElements ||
722 op->opcode() == IrOpcode::kNewSmiOrObjectElements) {
723 return OpParameter<AllocationType>(op);
724 }
725 return AllocateParametersOf(op).allocation_type();
726}
727
729 DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
730 return AllocateParametersOf(op).type();
731}
732
734 DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
735 return static_cast<AbortReason>(OpParameter<int>(op));
736}
737
739 const Operator* op) {
740 DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 ||
741 op->opcode() == IrOpcode::kCheckedTaggedToFloat64);
742 return OpParameter<CheckTaggedInputParameters>(op);
743}
744
745std::ostream& operator<<(std::ostream& os,
746 const CheckTaggedInputParameters& params) {
747 return os << params.mode() << ", " << params.feedback();
748}
749
750size_t hash_value(const CheckTaggedInputParameters& params) {
751 FeedbackSource::Hash feedback_hash;
752 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
753}
754
755bool operator==(CheckTaggedInputParameters const& lhs,
756 CheckTaggedInputParameters const& rhs) {
757 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
758}
759
761 DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 ||
762 op->opcode() == IrOpcode::kCheckedTaggedToAdditiveSafeInteger ||
763 op->opcode() == IrOpcode::kCheckedTaggedToInt64 ||
764 op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
765 op->opcode() == IrOpcode::kCheckedFloat64ToAdditiveSafeInteger ||
766 op->opcode() == IrOpcode::kCheckedFloat64ToInt64);
767 return OpParameter<CheckMinusZeroParameters>(op);
768}
769
770std::ostream& operator<<(std::ostream& os,
771 const CheckMinusZeroParameters& params) {
772 return os << params.mode() << ", " << params.feedback();
773}
774
775size_t hash_value(const CheckMinusZeroParameters& params) {
776 FeedbackSource::Hash feedback_hash;
777 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
778}
779
780bool operator==(CheckMinusZeroParameters const& lhs,
781 CheckMinusZeroParameters const& rhs) {
782 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
783}
784
785#if V8_ENABLE_WEBASSEMBLY
786V8_EXPORT_PRIVATE std::ostream& operator<<(
787 std::ostream& os, AssertNotNullParameters const& params) {
788 return os << params.type << ", " << params.trap_id;
789}
790
791size_t hash_value(AssertNotNullParameters const& params) {
792 return base::hash_combine(params.type, params.trap_id);
793}
794
795bool operator==(AssertNotNullParameters const& lhs,
796 AssertNotNullParameters const& rhs) {
797 return lhs.type == rhs.type && lhs.trap_id == rhs.trap_id;
798}
799#endif
800
801#define PURE_OP_LIST(V) \
802 V(BooleanNot, Operator::kNoProperties, 1, 0) \
803 V(NumberEqual, Operator::kCommutative, 2, 0) \
804 V(NumberLessThan, Operator::kNoProperties, 2, 0) \
805 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
806 V(NumberAdd, Operator::kCommutative, 2, 0) \
807 V(NumberSubtract, Operator::kNoProperties, 2, 0) \
808 V(NumberMultiply, Operator::kCommutative, 2, 0) \
809 V(NumberDivide, Operator::kNoProperties, 2, 0) \
810 V(NumberModulus, Operator::kNoProperties, 2, 0) \
811 V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
812 V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
813 V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
814 V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
815 V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
816 V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
817 V(NumberImul, Operator::kCommutative, 2, 0) \
818 V(NumberAbs, Operator::kNoProperties, 1, 0) \
819 V(NumberClz32, Operator::kNoProperties, 1, 0) \
820 V(NumberCeil, Operator::kNoProperties, 1, 0) \
821 V(NumberFloor, Operator::kNoProperties, 1, 0) \
822 V(NumberFround, Operator::kNoProperties, 1, 0) \
823 V(NumberAcos, Operator::kNoProperties, 1, 0) \
824 V(NumberAcosh, Operator::kNoProperties, 1, 0) \
825 V(NumberAsin, Operator::kNoProperties, 1, 0) \
826 V(NumberAsinh, Operator::kNoProperties, 1, 0) \
827 V(NumberAtan, Operator::kNoProperties, 1, 0) \
828 V(NumberAtan2, Operator::kNoProperties, 2, 0) \
829 V(NumberAtanh, Operator::kNoProperties, 1, 0) \
830 V(NumberCbrt, Operator::kNoProperties, 1, 0) \
831 V(NumberCos, Operator::kNoProperties, 1, 0) \
832 V(NumberCosh, Operator::kNoProperties, 1, 0) \
833 V(NumberExp, Operator::kNoProperties, 1, 0) \
834 V(NumberExpm1, Operator::kNoProperties, 1, 0) \
835 V(NumberLog, Operator::kNoProperties, 1, 0) \
836 V(NumberLog1p, Operator::kNoProperties, 1, 0) \
837 V(NumberLog10, Operator::kNoProperties, 1, 0) \
838 V(NumberLog2, Operator::kNoProperties, 1, 0) \
839 V(NumberMax, Operator::kNoProperties, 2, 0) \
840 V(NumberMin, Operator::kNoProperties, 2, 0) \
841 V(NumberPow, Operator::kNoProperties, 2, 0) \
842 V(NumberRound, Operator::kNoProperties, 1, 0) \
843 V(NumberSign, Operator::kNoProperties, 1, 0) \
844 V(NumberSin, Operator::kNoProperties, 1, 0) \
845 V(NumberSinh, Operator::kNoProperties, 1, 0) \
846 V(NumberSqrt, Operator::kNoProperties, 1, 0) \
847 V(NumberTan, Operator::kNoProperties, 1, 0) \
848 V(NumberTanh, Operator::kNoProperties, 1, 0) \
849 V(NumberTrunc, Operator::kNoProperties, 1, 0) \
850 V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
851 V(NumberToInt32, Operator::kNoProperties, 1, 0) \
852 V(NumberToString, Operator::kNoProperties, 1, 0) \
853 V(NumberToUint32, Operator::kNoProperties, 1, 0) \
854 V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
855 V(Integral32OrMinusZeroToBigInt, Operator::kNoProperties, 1, 0) \
856 V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
857 V(BigIntEqual, Operator::kNoProperties, 2, 0) \
858 V(BigIntLessThan, Operator::kNoProperties, 2, 0) \
859 V(BigIntLessThanOrEqual, Operator::kNoProperties, 2, 0) \
860 V(BigIntNegate, Operator::kNoProperties, 1, 0) \
861 V(StringConcat, Operator::kNoProperties, 3, 0) \
862 V(StringToNumber, Operator::kNoProperties, 1, 0) \
863 V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
864 V(StringFromSingleCodePoint, Operator::kNoProperties, 1, 0) \
865 V(StringIndexOf, Operator::kNoProperties, 3, 0) \
866 V(StringLength, Operator::kNoProperties, 1, 0) \
867 V(StringWrapperLength, Operator::kNoProperties, 1, 0) \
868 V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
869 V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
870 V(TypeOf, Operator::kNoProperties, 1, 1) \
871 V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
872 V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
873 V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
874 V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
875 V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
876 V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
877 V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
878 V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
879 V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
880 V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
881 V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
882 V(ChangeFloat64HoleToTagged, Operator::kNoProperties, 1, 0) \
883 V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
884 V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
885 V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
886 V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
887 V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
888 V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
889 V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
890 V(TruncateBigIntToWord64, Operator::kNoProperties, 1, 0) \
891 V(ChangeInt64ToBigInt, Operator::kNoProperties, 1, 0) \
892 V(ChangeUint64ToBigInt, Operator::kNoProperties, 1, 0) \
893 V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
894 V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
895 V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
896 V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
897 V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
898 V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
899 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
900 V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
901 V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
902 V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
903 V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
904 V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
905 V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
906 V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
907 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
908 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
909 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
910 V(ObjectIsString, Operator::kNoProperties, 1, 0) \
911 V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
912 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
913 V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
914 V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
915 V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
916 V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
917 V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
918 V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
919 V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
920 V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
921 V(SameValue, Operator::kCommutative, 2, 0) \
922 V(SameValueNumbersOnly, Operator::kCommutative, 2, 0) \
923 V(NumberSameValue, Operator::kCommutative, 2, 0) \
924 V(ReferenceEqual, Operator::kCommutative, 2, 0) \
925 V(StringEqual, Operator::kCommutative, 2, 0) \
926 V(StringLessThan, Operator::kNoProperties, 2, 0) \
927 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
928 V(ToBoolean, Operator::kNoProperties, 1, 0) \
929 V(NewConsString, Operator::kNoProperties, 3, 0) \
930 V(Unsigned32Divide, Operator::kNoProperties, 2, 0)
931
932#define EFFECT_DEPENDENT_OP_LIST(V) \
933 V(BigIntAdd, Operator::kNoProperties, 2, 1) \
934 V(BigIntSubtract, Operator::kNoProperties, 2, 1) \
935 V(BigIntMultiply, Operator::kNoProperties, 2, 1) \
936 V(BigIntDivide, Operator::kNoProperties, 2, 1) \
937 V(BigIntModulus, Operator::kNoProperties, 2, 1) \
938 V(BigIntBitwiseAnd, Operator::kNoProperties, 2, 1) \
939 V(BigIntBitwiseOr, Operator::kNoProperties, 2, 1) \
940 V(BigIntBitwiseXor, Operator::kNoProperties, 2, 1) \
941 V(BigIntShiftLeft, Operator::kNoProperties, 2, 1) \
942 V(BigIntShiftRight, Operator::kNoProperties, 2, 1) \
943 V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
944 V(StringCodePointAt, Operator::kNoProperties, 2, 1) \
945 V(StringFromCodePointAt, Operator::kNoProperties, 2, 1) \
946 V(StringSubstring, Operator::kNoProperties, 3, 1) \
947 V(DateNow, Operator::kNoProperties, 0, 1) \
948 V(DoubleArrayMax, Operator::kNoProperties, 1, 1) \
949 V(DoubleArrayMin, Operator::kNoProperties, 1, 1)
950
951#define SPECULATIVE_NUMBER_BINOP_LIST(V) \
952 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
953 V(SpeculativeNumberEqual) \
954 V(SpeculativeNumberLessThan) \
955 V(SpeculativeNumberLessThanOrEqual)
956
957#define CHECKED_OP_LIST(V) \
958 V(CheckEqualsInternalizedString, 2, 0) \
959 V(CheckEqualsSymbol, 2, 0) \
960 V(CheckHeapObject, 1, 1) \
961 V(CheckInternalizedString, 1, 1) \
962 V(CheckNotTaggedHole, 1, 1) \
963 V(CheckReceiver, 1, 1) \
964 V(CheckReceiverOrNullOrUndefined, 1, 1) \
965 V(CheckSymbol, 1, 1) \
966 V(CheckedInt32Add, 2, 1) \
967 V(CheckedInt32Div, 2, 1) \
968 V(CheckedInt32Mod, 2, 1) \
969 V(CheckedInt32Sub, 2, 1) \
970 V(CheckedUint32Div, 2, 1) \
971 V(CheckedUint32Mod, 2, 1) \
972 V(CheckedAdditiveSafeIntegerAdd, 2, 1) \
973 V(CheckedAdditiveSafeIntegerSub, 2, 1) \
974 V(CheckedInt64Add, 2, 1) \
975 V(CheckedInt64Sub, 2, 1) \
976 V(CheckedInt64Mul, 2, 1) \
977 V(CheckedInt64Div, 2, 1) \
978 V(CheckedInt64Mod, 2, 1)
979
980#define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
981 V(CheckNumber, 1, 1) \
982 V(CheckNumberFitsInt32, 1, 1) \
983 V(CheckSmi, 1, 1) \
984 V(CheckString, 1, 1) \
985 V(CheckStringOrStringWrapper, 1, 1) \
986 V(CheckBigInt, 1, 1) \
987 V(CheckedBigIntToBigInt64, 1, 1) \
988 V(CheckedInt32ToTaggedSigned, 1, 1) \
989 V(CheckedInt64ToInt32, 1, 1) \
990 V(CheckedInt64ToTaggedSigned, 1, 1) \
991 V(CheckedTaggedToArrayIndex, 1, 1) \
992 V(CheckedTaggedSignedToInt32, 1, 1) \
993 V(CheckedTaggedToTaggedPointer, 1, 1) \
994 V(CheckedTaggedToTaggedSigned, 1, 1) \
995 V(CheckedUint32ToInt32, 1, 1) \
996 V(CheckedUint32ToTaggedSigned, 1, 1) \
997 V(CheckedUint64ToInt32, 1, 1) \
998 V(CheckedUint64ToInt64, 1, 1) \
999 V(CheckedUint64ToTaggedSigned, 1, 1)
1000
1001#define CHECKED_BOUNDS_OP_LIST(V) \
1002 V(CheckedUint32Bounds) \
1003 V(CheckedUint64Bounds)
1004
1006#define PURE(Name, properties, value_input_count, control_input_count) \
1007 struct Name##Operator final : public Operator { \
1008 Name##Operator() \
1009 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
1010 value_input_count, 0, control_input_count, 1, 0, 0) {} \
1011 }; \
1012 Name##Operator k##Name;
1014#undef PURE
1015
1016#define EFFECT_DEPENDENT(Name, properties, value_input_count, \
1017 control_input_count) \
1018 struct Name##Operator final : public Operator { \
1019 Name##Operator() \
1020 : Operator(IrOpcode::k##Name, Operator::kEliminatable | properties, \
1021 #Name, value_input_count, 1, control_input_count, 1, 1, \
1022 0) {} \
1023 }; \
1024 Name##Operator k##Name;
1026#undef EFFECT_DEPENDENT
1027
1028#define CHECKED(Name, value_input_count, value_output_count) \
1029 struct Name##Operator final : public Operator { \
1030 Name##Operator() \
1031 : Operator(IrOpcode::k##Name, \
1032 Operator::kFoldable | Operator::kNoThrow, #Name, \
1033 value_input_count, 1, 1, value_output_count, 1, 0) {} \
1034 }; \
1035 Name##Operator k##Name;
1037#undef CHECKED
1038
1039#define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \
1040 struct Name##Operator final : public Operator1<CheckParameters> { \
1041 Name##Operator() \
1042 : Operator1<CheckParameters>( \
1043 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1044 #Name, value_input_count, 1, 1, value_output_count, 1, 0, \
1045 CheckParameters(FeedbackSource())) {} \
1046 }; \
1047 Name##Operator k##Name;
1049#undef CHECKED_WITH_FEEDBACK
1050
1051#define CHECKED_BOUNDS(Name) \
1052 struct Name##Operator final : public Operator1<CheckBoundsParameters> { \
1053 Name##Operator(FeedbackSource feedback, CheckBoundsFlags flags) \
1054 : Operator1<CheckBoundsParameters>( \
1055 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1056 #Name, 2, 1, 1, 1, 1, 0, \
1057 CheckBoundsParameters(feedback, flags)) {} \
1058 }; \
1059 Name##Operator k##Name = {FeedbackSource(), CheckBoundsFlags()}; \
1060 Name##Operator k##Name##Aborting = {FeedbackSource(), \
1061 CheckBoundsFlag::kAbortOnOutOfBounds};
1063 CHECKED_BOUNDS(CheckBounds)
1064 // For IrOpcode::kCheckBounds, we allow additional flags:
1065 CheckBoundsOperator kCheckBoundsConverting = {
1066 FeedbackSource(), CheckBoundsFlag::kConvertStringAndMinusZero};
1067 CheckBoundsOperator kCheckBoundsAbortingAndConverting = {
1069 CheckBoundsFlags(CheckBoundsFlag::kAbortOnOutOfBounds) |
1070 CheckBoundsFlags(CheckBoundsFlag::kConvertStringAndMinusZero)};
1071#undef CHECKED_BOUNDS
1072
1073 template <DeoptimizeReason kDeoptimizeReason>
1074 struct CheckIfOperator final : public Operator1<CheckIfParameters> {
1077 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
1078 "CheckIf", 1, 1, 1, 0, 1, 0,
1079 CheckIfParameters(kDeoptimizeReason, FeedbackSource())) {}
1080 };
1081#define CHECK_IF(Name, message) \
1082 CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name;
1084#undef CHECK_IF
1085
1088 : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
1089 "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
1090 };
1092
1095 : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
1096 Operator::kEliminatable,
1097 "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
1098 };
1099 FindOrderedHashMapEntryForInt32KeyOperator
1101
1104 : Operator(IrOpcode::kFindOrderedHashSetEntry, Operator::kEliminatable,
1105 "FindOrderedHashSetEntry", 2, 1, 1, 1, 1, 0) {}
1106 };
1108
1109 template <CheckForMinusZeroMode kMode>
1111 : public Operator1<CheckForMinusZeroMode> {
1114 IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
1115 "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
1116 };
1117 ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero>
1121
1122 template <CheckForMinusZeroMode kMode>
1124 : public Operator1<CheckForMinusZeroMode> {
1127 IrOpcode::kCheckedInt32Mul,
1128 Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
1129 1, 1, 1, 0, kMode) {}
1130 };
1131 CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero>
1135
1136 template <CheckForMinusZeroMode kMode>
1138 : public Operator1<CheckMinusZeroParameters> {
1141 IrOpcode::kCheckedFloat64ToInt32,
1142 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
1143 1, 1, 1, 1, 1, 0,
1145 };
1146 CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1150
1151 template <CheckForMinusZeroMode kMode>
1153 : public Operator1<CheckMinusZeroParameters> {
1156 IrOpcode::kCheckedFloat64ToAdditiveSafeInteger,
1157 Operator::kFoldable | Operator::kNoThrow,
1158 "CheckedFloat64ToAdditiveSafeInteger", 1, 1, 1, 1, 1, 0,
1160 };
1161 CheckedFloat64ToAdditiveSafeIntegerOperator<
1162 CheckForMinusZeroMode::kCheckForMinusZero>
1165 CheckForMinusZeroMode::kDontCheckForMinusZero>
1167
1168 template <CheckForMinusZeroMode kMode>
1170 : public Operator1<CheckMinusZeroParameters> {
1173 IrOpcode::kCheckedFloat64ToInt64,
1174 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64",
1175 1, 1, 1, 1, 1, 0,
1177 };
1178 CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1182
1183 template <CheckForMinusZeroMode kMode>
1185 : public Operator1<CheckMinusZeroParameters> {
1188 IrOpcode::kCheckedTaggedToInt32,
1189 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
1190 1, 1, 1, 1, 1, 0,
1192 };
1193 CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1197
1198 template <CheckForMinusZeroMode kMode>
1200 : public Operator1<CheckMinusZeroParameters> {
1203 IrOpcode::kCheckedTaggedToAdditiveSafeInteger,
1204 Operator::kFoldable | Operator::kNoThrow,
1205 "CheckedTaggedToAdditiveSafeInteger", 1, 1, 1, 1, 1, 0,
1207 };
1208 CheckedTaggedToAdditiveSafeIntegerOperator<
1209 CheckForMinusZeroMode::kCheckForMinusZero>
1212 CheckForMinusZeroMode::kDontCheckForMinusZero>
1214
1215 template <CheckForMinusZeroMode kMode>
1217 : public Operator1<CheckMinusZeroParameters> {
1220 IrOpcode::kCheckedTaggedToInt64,
1221 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64",
1222 1, 1, 1, 1, 1, 0,
1224 };
1225 CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1229
1230 template <CheckTaggedInputMode kMode>
1232 : public Operator1<CheckTaggedInputParameters> {
1235 IrOpcode::kCheckedTaggedToFloat64,
1236 Operator::kFoldable | Operator::kNoThrow,
1237 "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1239 };
1240 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber>
1246
1247 template <CheckTaggedInputMode kMode>
1249 : public Operator1<CheckTaggedInputParameters> {
1252 IrOpcode::kCheckedTruncateTaggedToWord32,
1253 Operator::kFoldable | Operator::kNoThrow,
1254 "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1256 };
1257 CheckedTruncateTaggedToWord32Operator<
1258 CheckTaggedInputMode::kAdditiveSafeInteger>
1264
1265 template <ConvertReceiverMode kMode>
1266 struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> {
1269 IrOpcode::kConvertReceiver, // opcode
1270 Operator::kEliminatable, // flags
1271 "ConvertReceiver", // name
1272 3, 1, 1, 1, 1, 0, // counts
1273 kMode) {} // param
1274 };
1275 ConvertReceiverOperator<ConvertReceiverMode::kAny>
1281
1282 template <CheckFloat64HoleMode kMode>
1284 : public Operator1<CheckFloat64HoleParameters> {
1287 IrOpcode::kCheckFloat64Hole,
1288 Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
1289 1, 1, 1, 1, 0,
1291 };
1292 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
1296
1299 : Operator( // --
1300 IrOpcode::kEnsureWritableFastElements, // opcode
1301 Operator::kNoDeopt | Operator::kNoThrow, // flags
1302 "EnsureWritableFastElements", // name
1303 2, 1, 1, 1, 1, 0) {} // counts
1304 };
1306
1307 template <GrowFastElementsMode kMode>
1309 : public Operator1<GrowFastElementsParameters> {
1311 : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1312 "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1314 };
1315
1316 GrowFastElementsOperator<GrowFastElementsMode::kDoubleElements>
1320
1321 struct LoadFieldByIndexOperator final : public Operator {
1323 : Operator( // --
1324 IrOpcode::kLoadFieldByIndex, // opcode
1325 Operator::kEliminatable, // flags,
1326 "LoadFieldByIndex", // name
1327 2, 1, 1, 1, 1, 0) {} // counts;
1328 };
1330
1331 struct LoadStackArgumentOperator final : public Operator {
1333 : Operator( // --
1334 IrOpcode::kLoadStackArgument, // opcode
1335 Operator::kEliminatable, // flags
1336 "LoadStackArgument", // name
1337 2, 1, 1, 1, 1, 0) {} // counts
1338 };
1340
1341#if V8_ENABLE_WEBASSEMBLY
1342 struct WasmArrayLengthOperator final : public Operator1<bool> {
1343 explicit WasmArrayLengthOperator(bool null_check)
1344 : Operator1<bool>(IrOpcode::kWasmArrayLength, Operator::kEliminatable,
1345 "WasmArrayLength", 1, 1, 1, 1, 1, 1, null_check) {}
1346 };
1347 WasmArrayLengthOperator kWasmArrayLengthNullCheck{true};
1348 WasmArrayLengthOperator kWasmArrayLengthNoNullCheck{false};
1349
1350 struct WasmArrayInitializeLengthOperator final : public Operator {
1351 WasmArrayInitializeLengthOperator()
1352 : Operator(IrOpcode::kWasmArrayInitializeLength,
1353 Operator::kNoThrow | Operator::kNoRead | Operator::kNoDeopt,
1354 "WasmArrayInitializeLength", 2, 1, 1, 0, 1, 0) {}
1355 };
1356 WasmArrayInitializeLengthOperator kWasmArrayInitializeLength;
1357
1358 struct StringAsWtf16Operator final : public Operator {
1359 StringAsWtf16Operator()
1360 : Operator(IrOpcode::kStringAsWtf16,
1361 Operator::kEliminatable | Operator::kIdempotent,
1362 "StringAsWtf16", 1, 1, 1, 1, 1, 1) {}
1363 };
1364 StringAsWtf16Operator kStringAsWtf16;
1365
1366 struct StringPrepareForGetCodeunitOperator final : public Operator {
1367 StringPrepareForGetCodeunitOperator()
1368 : Operator(IrOpcode::kStringPrepareForGetCodeunit,
1369 Operator::kEliminatable, "StringPrepareForGetCodeunit", 1, 1,
1370 1, 3, 1, 1) {}
1371 };
1372 StringPrepareForGetCodeunitOperator kStringPrepareForGetCodeunit;
1373
1374#endif
1375
1376#define SPECULATIVE_NUMBER_BINOP(Name) \
1377 template <NumberOperationHint kHint> \
1378 struct Name##Operator final : public Operator1<NumberOperationHint> { \
1379 Name##Operator() \
1380 : Operator1<NumberOperationHint>( \
1381 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1382 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
1383 }; \
1384 Name##Operator<NumberOperationHint::kSignedSmall> \
1385 k##Name##SignedSmallOperator; \
1386 Name##Operator<NumberOperationHint::kSignedSmallInputs> \
1387 k##Name##SignedSmallInputsOperator; \
1388 Name##Operator<NumberOperationHint::kAdditiveSafeInteger> \
1389 k##Name##SafeIntOperator; \
1390 Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
1391 Name##Operator<NumberOperationHint::kNumberOrOddball> \
1392 k##Name##NumberOrOddballOperator;
1394#undef SPECULATIVE_NUMBER_BINOP
1395 SpeculativeNumberEqualOperator<NumberOperationHint::kNumberOrBoolean>
1397
1398 template <NumberOperationHint kHint>
1400 : public Operator1<NumberOperationParameters> {
1403 IrOpcode::kSpeculativeToNumber,
1404 Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber",
1405 1, 1, 1, 1, 1, 0,
1407 };
1408 SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
1414
1415 template <BigIntOperationHint kHint>
1417 : public Operator1<BigIntOperationParameters> {
1420 IrOpcode::kSpeculativeToBigInt,
1421 Operator::kFoldable | Operator::kNoThrow, "SpeculativeToBigInt",
1422 1, 1, 1, 1, 1, 0,
1424 };
1425 SpeculativeToBigIntOperator<BigIntOperationHint::kBigInt64>
1429
1430#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
1431 struct GetContinuationPreservedEmbedderDataOperator : public Operator {
1432 GetContinuationPreservedEmbedderDataOperator()
1433 : Operator(IrOpcode::kGetContinuationPreservedEmbedderData,
1434 Operator::kNoThrow | Operator::kNoDeopt | Operator::kNoWrite,
1435 "GetContinuationPreservedEmbedderData", 0, 1, 0, 1, 1, 0) {}
1436 };
1437 GetContinuationPreservedEmbedderDataOperator
1438 kGetContinuationPreservedEmbedderData;
1439
1440 struct SetContinuationPreservedEmbedderDataOperator : public Operator {
1441 SetContinuationPreservedEmbedderDataOperator()
1442 : Operator(IrOpcode::kSetContinuationPreservedEmbedderData,
1443 Operator::kNoThrow | Operator::kNoDeopt | Operator::kNoRead,
1444 "SetContinuationPreservedEmbedderData", 1, 1, 0, 0, 1, 0) {}
1445 };
1446 SetContinuationPreservedEmbedderDataOperator
1447 kSetContinuationPreservedEmbedderData;
1448#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
1449};
1450
1451namespace {
1452DEFINE_LAZY_LEAKY_OBJECT_GETTER(SimplifiedOperatorGlobalCache,
1453 GetSimplifiedOperatorGlobalCache)
1454} // namespace
1455
1456SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
1457 : cache_(*GetSimplifiedOperatorGlobalCache()), zone_(zone) {}
1458
1459#define GET_FROM_CACHE(Name, ...) \
1460 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
1464GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1465GET_FROM_CACHE(LoadFieldByIndex)
1466#undef GET_FROM_CACHE
1467
1469 CollectionKind collection_kind) {
1470 switch (collection_kind) {
1472 return &cache_.kFindOrderedHashMapEntry;
1474 return &cache_.kFindOrderedHashSetEntry;
1475 }
1476}
1477
1478#define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \
1479 value_output_count) \
1480 const Operator* SimplifiedOperatorBuilder::Name( \
1481 const FeedbackSource& feedback) { \
1482 if (!feedback.IsValid()) { \
1483 return &cache_.k##Name; \
1484 } \
1485 return zone()->New<Operator1<CheckParameters>>( \
1486 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \
1487 value_input_count, 1, 1, value_output_count, 1, 0, \
1488 CheckParameters(feedback)); \
1489 }
1491#undef GET_FROM_CACHE_WITH_FEEDBACK
1492
1493#define GET_FROM_CACHE_WITH_FEEDBACK(Name) \
1494 const Operator* SimplifiedOperatorBuilder::Name( \
1495 const FeedbackSource& feedback, CheckBoundsFlags flags) { \
1496 DCHECK(!(flags & CheckBoundsFlag::kConvertStringAndMinusZero)); \
1497 if (!feedback.IsValid()) { \
1498 if (flags & CheckBoundsFlag::kAbortOnOutOfBounds) { \
1499 return &cache_.k##Name##Aborting; \
1500 } else { \
1501 return &cache_.k##Name; \
1502 } \
1503 } \
1504 return zone()->New<SimplifiedOperatorGlobalCache::Name##Operator>( \
1505 feedback, flags); \
1506 }
1508#undef GET_FROM_CACHE_WITH_FEEDBACK
1509
1510// For IrOpcode::kCheckBounds, we allow additional flags:
1512 const FeedbackSource& feedback, CheckBoundsFlags flags) {
1513 if (!feedback.IsValid()) {
1516 return &cache_.kCheckBoundsAbortingAndConverting;
1517 } else {
1518 return &cache_.kCheckBoundsAborting;
1519 }
1520 } else {
1522 return &cache_.kCheckBoundsConverting;
1523 } else {
1524 return &cache_.kCheckBounds;
1525 }
1526 }
1527 }
1528 return zone()->New<SimplifiedOperatorGlobalCache::CheckBoundsOperator>(
1529 feedback, flags);
1530}
1531
1533#define CASE(Name, ...) case IrOpcode::k##Name:
1534 switch (op->opcode()) {
1536 default:
1537 return false;
1538 }
1539#undef CASE
1540}
1541
1543 return zone()->New<Operator1<int>>( // --
1544 IrOpcode::kRuntimeAbort, // opcode
1546 "RuntimeAbort", // name
1547 0, 1, 1, 0, 1, 0, // counts
1548 static_cast<int>(reason)); // parameter
1549}
1550
1552 int bits, const FeedbackSource& feedback) {
1553 CHECK(0 <= bits && bits <= 64);
1554
1556 IrOpcode::kSpeculativeBigIntAsIntN, Operator::kNoProperties,
1557 "SpeculativeBigIntAsIntN", 1, 1, 1, 1, 1, 0,
1558 SpeculativeBigIntAsNParameters(bits, feedback));
1559}
1560
1562 int bits, const FeedbackSource& feedback) {
1563 CHECK(0 <= bits && bits <= 64);
1564
1566 IrOpcode::kSpeculativeBigIntAsUintN, Operator::kNoProperties,
1567 "SpeculativeBigIntAsUintN", 1, 1, 1, 1, 1, 0,
1568 SpeculativeBigIntAsNParameters(bits, feedback));
1569}
1570
1572 DCHECK(type.CanBeAsserted());
1573 return zone()->New<Operator1<Type>>(IrOpcode::kAssertType,
1574 Operator::kEliminatable, "AssertType", 1,
1575 1, 0, 0, 1, 0, type);
1576}
1577
1579 return zone()->New<Operator>(IrOpcode::kVerifyType,
1581 "VerifyType", 1, 1, 0, 0, 1, 0);
1582}
1583
1585 return zone()->New<Operator>(IrOpcode::kCheckTurboshaftTypeOf,
1587 "CheckTurboshaftTypeOf", 2, 1, 1, 1, 1, 0);
1588}
1589
1590#if V8_ENABLE_WEBASSEMBLY
1591const Operator* SimplifiedOperatorBuilder::WasmTypeCheck(
1592 WasmTypeCheckConfig config) {
1594 IrOpcode::kWasmTypeCheck, Operator::kEliminatable | Operator::kIdempotent,
1595 "WasmTypeCheck", 2, 1, 1, 1, 1, 1, config);
1596}
1597
1598const Operator* SimplifiedOperatorBuilder::WasmTypeCheckAbstract(
1599 WasmTypeCheckConfig config) {
1600 return zone_->New<Operator1<WasmTypeCheckConfig>>(
1601 IrOpcode::kWasmTypeCheckAbstract,
1602 Operator::kEliminatable | Operator::kIdempotent, "WasmTypeCheckAbstract",
1603 1, 1, 1, 1, 1, 1, config);
1604}
1605
1606const Operator* SimplifiedOperatorBuilder::WasmTypeCast(
1607 WasmTypeCheckConfig config) {
1608 return zone_->New<Operator1<WasmTypeCheckConfig>>(
1609 IrOpcode::kWasmTypeCast,
1611 "WasmTypeCast", 2, 1, 1, 1, 1, 1, config);
1612}
1613
1614const Operator* SimplifiedOperatorBuilder::WasmTypeCastAbstract(
1615 WasmTypeCheckConfig config) {
1616 return zone_->New<Operator1<WasmTypeCheckConfig>>(
1617 IrOpcode::kWasmTypeCastAbstract,
1619 "WasmTypeCastAbstract", 1, 1, 1, 1, 1, 1, config);
1620}
1621
1622const Operator* SimplifiedOperatorBuilder::RttCanon(
1623 wasm::ModuleTypeIndex index) {
1624 return zone()->New<Operator1<int>>(IrOpcode::kRttCanon, Operator::kPure,
1625 "RttCanon", 1, 0, 0, 1, 0, 0, index.index);
1626}
1627
1628// Note: The following two operators have a control input solely to find the
1629// typing context from the control path in wasm-gc-operator-reducer.
1630struct IsNullOperator final : public Operator1<wasm::ValueType> {
1631 explicit IsNullOperator(wasm::ValueType type)
1632 : Operator1(IrOpcode::kIsNull, Operator::kPure, "IsNull", 1, 0, 1, 1, 0,
1633 0, type) {}
1634};
1635
1636struct IsNotNullOperator final : public Operator1<wasm::ValueType> {
1637 explicit IsNotNullOperator(wasm::ValueType type)
1638 : Operator1(IrOpcode::kIsNotNull, Operator::kPure, "IsNotNull", 1, 0, 1,
1639 1, 0, 0, type) {}
1640};
1641
1642struct NullOperator final : public Operator1<wasm::ValueType> {
1643 explicit NullOperator(wasm::ValueType type)
1644 : Operator1(IrOpcode::kNull, Operator::kPure, "Null", 0, 0, 0, 1, 0, 0,
1645 type) {}
1646};
1647
1648struct AssertNotNullOperator final : public Operator1<AssertNotNullParameters> {
1649 explicit AssertNotNullOperator(wasm::ValueType type, TrapId trap_id)
1650 : Operator1(
1651 IrOpcode::kAssertNotNull,
1652 Operator::kNoWrite | Operator::kNoThrow | Operator::kIdempotent,
1653 "AssertNotNull", 1, 1, 1, 1, 1, 1, {type, trap_id}) {}
1654};
1655
1656const Operator* SimplifiedOperatorBuilder::Null(wasm::ValueType type) {
1657 return zone()->New<NullOperator>(type);
1658}
1659
1660const Operator* SimplifiedOperatorBuilder::AssertNotNull(wasm::ValueType type,
1661 TrapId trap_id) {
1662 return zone()->New<AssertNotNullOperator>(type, trap_id);
1663}
1664
1665const Operator* SimplifiedOperatorBuilder::IsNull(wasm::ValueType type) {
1666 return zone()->New<IsNullOperator>(type);
1667}
1668const Operator* SimplifiedOperatorBuilder::IsNotNull(wasm::ValueType type) {
1669 return zone()->New<IsNotNullOperator>(type);
1670}
1671
1672const Operator* SimplifiedOperatorBuilder::StringAsWtf16() {
1673 return &cache_.kStringAsWtf16;
1674}
1675
1676const Operator* SimplifiedOperatorBuilder::StringPrepareForGetCodeunit() {
1677 return &cache_.kStringPrepareForGetCodeunit;
1678}
1679
1680const Operator* SimplifiedOperatorBuilder::WasmAnyConvertExtern() {
1681 return zone()->New<Operator>(IrOpcode::kWasmAnyConvertExtern,
1682 Operator::kEliminatable, "WasmAnyConvertExtern",
1683 1, 1, 1, 1, 1, 1);
1684}
1685
1686const Operator* SimplifiedOperatorBuilder::WasmExternConvertAny() {
1687 return zone()->New<Operator>(IrOpcode::kWasmExternConvertAny,
1688 Operator::kEliminatable, "WasmExternConvertAny",
1689 1, 1, 1, 1, 1, 1);
1690}
1691
1692const Operator* SimplifiedOperatorBuilder::WasmStructGet(
1693 const wasm::StructType* type, int field_index, bool is_signed,
1694 CheckForNull null_check) {
1695 return zone()->New<Operator1<WasmFieldInfo>>(
1696 IrOpcode::kWasmStructGet, Operator::kEliminatable, "WasmStructGet", 1, 1,
1697 1, 1, 1, 1, WasmFieldInfo{type, field_index, is_signed, null_check});
1698}
1699
1700const Operator* SimplifiedOperatorBuilder::WasmStructSet(
1701 const wasm::StructType* type, int field_index, CheckForNull null_check) {
1702 return zone()->New<Operator1<WasmFieldInfo>>(
1703 IrOpcode::kWasmStructSet,
1705 "WasmStructSet", 2, 1, 1, 0, 1, 1,
1706 WasmFieldInfo{type, field_index, true /* unused */, null_check});
1707}
1708
1709const Operator* SimplifiedOperatorBuilder::WasmArrayGet(
1710 const wasm::ArrayType* type, bool is_signed) {
1711 return zone()->New<Operator1<WasmElementInfo>>(
1712 IrOpcode::kWasmArrayGet, Operator::kEliminatable, "WasmArrayGet", 2, 1, 1,
1713 1, 1, 0, WasmElementInfo{type, is_signed});
1714}
1715
1716const Operator* SimplifiedOperatorBuilder::WasmArraySet(
1717 const wasm::ArrayType* type) {
1718 return zone()->New<Operator1<const wasm::ArrayType*>>(
1719 IrOpcode::kWasmArraySet,
1721 "WasmArraySet", 3, 1, 1, 0, 1, 0, type);
1722}
1723
1724const Operator* SimplifiedOperatorBuilder::WasmArrayLength(
1725 CheckForNull null_check) {
1726 return null_check == kWithNullCheck ? &cache_.kWasmArrayLengthNullCheck
1727 : &cache_.kWasmArrayLengthNoNullCheck;
1728}
1729
1730const Operator* SimplifiedOperatorBuilder::WasmArrayInitializeLength() {
1731 return &cache_.kWasmArrayInitializeLength;
1732}
1733
1734#endif // V8_ENABLE_WEBASSEMBLY
1735
1737 DeoptimizeReason reason, const FeedbackSource& feedback) {
1738 if (!feedback.IsValid()) {
1739 switch (reason) {
1740#define CHECK_IF(Name, message) \
1741 case DeoptimizeReason::k##Name: \
1742 return &cache_.kCheckIf##Name;
1744#undef CHECK_IF
1745 }
1746 }
1748 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf",
1749 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1750}
1751
1753 CheckForMinusZeroMode mode) {
1754 switch (mode) {
1756 return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1758 return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1759 }
1760 UNREACHABLE();
1761}
1762
1764 CheckForMinusZeroMode mode) {
1765 switch (mode) {
1767 return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1769 return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1770 }
1771 UNREACHABLE();
1772}
1773
1775 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1776 if (!feedback.IsValid()) {
1777 switch (mode) {
1779 return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1781 return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1782 }
1783 }
1785 IrOpcode::kCheckedFloat64ToInt32,
1786 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1,
1787 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1788}
1789
1791 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1792 if (!feedback.IsValid()) {
1793 switch (mode) {
1795 return &cache_.kCheckedFloat64ToAddSafeIntCheckForMinusZeroOperator;
1797 return &cache_.kCheckedFloat64ToAddSafeIntDontCheckForMinusZeroOperator;
1798 }
1799 }
1801 IrOpcode::kCheckedFloat64ToAdditiveSafeInteger,
1803 "CheckedFloat64ToAdditiveSafeInteger", 1, 1, 1, 1, 1, 0,
1804 CheckMinusZeroParameters(mode, feedback));
1805}
1806
1808 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1809 if (!feedback.IsValid()) {
1810 switch (mode) {
1812 return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1814 return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1815 }
1816 }
1818 IrOpcode::kCheckedFloat64ToInt64,
1819 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1,
1820 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1821}
1822
1824 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1825 if (!feedback.IsValid()) {
1826 switch (mode) {
1828 return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1830 return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1831 }
1832 }
1834 IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1835 "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1836 CheckMinusZeroParameters(mode, feedback));
1837}
1838
1840 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1841 if (!feedback.IsValid()) {
1842 switch (mode) {
1844 return &cache_.kCheckedTaggedToAddSafeIntCheckForMinusZeroOperator;
1846 return &cache_.kCheckedTaggedToAddSafeIntDontCheckForMinusZeroOperator;
1847 }
1848 }
1850 IrOpcode::kCheckedTaggedToAdditiveSafeInteger,
1852 "CheckedTaggedToAdditiveSafeInteger", 1, 1, 1, 1, 1, 0,
1853 CheckMinusZeroParameters(mode, feedback));
1854}
1855
1857 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1858 if (!feedback.IsValid()) {
1859 switch (mode) {
1861 return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1863 return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1864 }
1865 }
1867 IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1868 "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1869 CheckMinusZeroParameters(mode, feedback));
1870}
1871
1873 CheckTaggedInputMode mode, const FeedbackSource& feedback) {
1874 if (!feedback.IsValid()) {
1875 switch (mode) {
1877 UNREACHABLE();
1879 return &cache_.kCheckedTaggedToFloat64NumberOperator;
1881 return &cache_.kCheckedTaggedToFloat64NumberOrBooleanOperator;
1883 return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1884 }
1885 }
1887 IrOpcode::kCheckedTaggedToFloat64,
1888 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1,
1889 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1890}
1891
1893 CheckTaggedInputMode mode, const FeedbackSource& feedback) {
1894 if (!feedback.IsValid()) {
1895 switch (mode) {
1897 return &cache_
1898 .kCheckedTruncateTaggedToWord32AdditiveSafeIntegerOperator;
1900 return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1902 // Not used currently.
1903 UNREACHABLE();
1905 return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1906 }
1907 }
1909 IrOpcode::kCheckedTruncateTaggedToWord32,
1910 Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32",
1911 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1912}
1913
1915 CheckMapsFlags flags, ZoneRefSet<Map> maps,
1916 const FeedbackSource& feedback) {
1917 CheckMapsParameters const parameters(flags, maps, feedback);
1919 if (!(flags & CheckMapsFlag::kTryMigrateInstance) &&
1921 operator_props |= Operator::kNoWrite;
1922 }
1923 return zone()->New<Operator1<CheckMapsParameters>>( // --
1924 IrOpcode::kCheckMaps, // opcode
1925 operator_props, // flags
1926 "CheckMaps", // name
1927 1, 1, 1, 0, 1, 0, // counts
1928 parameters); // parameter
1929}
1930
1932 DCHECK_LT(0, maps.size());
1933 return zone()->New<Operator1<ZoneRefSet<Map>>>( // --
1934 IrOpcode::kMapGuard, Operator::kEliminatable, // opcode
1935 "MapGuard", // name
1936 1, 1, 1, 0, 1, 0, // counts
1937 maps); // parameter
1938}
1939
1941 DCHECK_LT(0, maps.size());
1942 return zone()->New<Operator1<ZoneRefSet<Map>>>( // --
1943 IrOpcode::kCompareMaps, // opcode
1945 "CompareMaps", // name
1946 1, 1, 1, 1, 1, 0, // counts
1947 maps); // parameter
1948}
1949
1951 ConvertReceiverMode mode) {
1952 switch (mode) {
1954 return &cache_.kConvertReceiverAnyOperator;
1956 return &cache_.kConvertReceiverNullOrUndefinedOperator;
1958 return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1959 }
1960 UNREACHABLE();
1961}
1962
1964 CheckFloat64HoleMode mode, FeedbackSource const& feedback) {
1965 if (!feedback.IsValid()) {
1966 switch (mode) {
1968 return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1970 return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1971 }
1972 UNREACHABLE();
1973 }
1975 IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1976 "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1977 CheckFloat64HoleParameters(mode, feedback));
1978}
1979
1980// TODO(panq): Cache speculative bigint operators.
1981#define SPECULATIVE_BIGINT_BINOP(Name) \
1982 const Operator* SimplifiedOperatorBuilder::Name(BigIntOperationHint hint) { \
1983 return zone()->New<Operator1<BigIntOperationHint>>( \
1984 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \
1985 1, 1, 1, 1, 0, hint); \
1986 }
1988SPECULATIVE_BIGINT_BINOP(SpeculativeBigIntEqual)
1989SPECULATIVE_BIGINT_BINOP(SpeculativeBigIntLessThan)
1990SPECULATIVE_BIGINT_BINOP(SpeculativeBigIntLessThanOrEqual)
1991#undef SPECULATIVE_BIGINT_BINOP
1992
1994 BigIntOperationHint hint) {
1996 IrOpcode::kSpeculativeBigIntNegate,
1997 Operator::kFoldable | Operator::kNoThrow, "SpeculativeBigIntNegate", 1, 1,
1998 1, 1, 1, 0, hint);
1999}
2000
2002 BigIntOperationHint hint, const FeedbackSource& feedback) {
2003 if (!feedback.IsValid()) {
2004 switch (hint) {
2006 return &cache_.kSpeculativeToBigIntBigInt64Operator;
2008 return &cache_.kSpeculativeToBigIntBigIntOperator;
2009 }
2010 }
2012 IrOpcode::kSpeculativeToBigInt, Operator::kFoldable | Operator::kNoThrow,
2013 "SpeculativeToBigInt", 1, 1, 1, 1, 1, 0,
2014 BigIntOperationParameters(hint, feedback));
2015}
2016
2018 const Handle<FeedbackCell>& feedback_cell) {
2020 IrOpcode::kCheckClosure, // opcode
2022 "CheckClosure", // name
2023 1, 1, 1, 1, 1, 0, // counts
2024 feedback_cell); // parameter
2025}
2026
2028 DCHECK(IrOpcode::kCheckClosure == op->opcode());
2030}
2031
2033 NumberOperationHint hint, const FeedbackSource& feedback) {
2034 if (!feedback.IsValid()) {
2035 switch (hint) {
2037 return &cache_.kSpeculativeToNumberSignedSmallOperator;
2039 break;
2042 return &cache_.kSpeculativeToNumberNumberOperator;
2044 // Not used currently.
2045 UNREACHABLE();
2047 return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
2048 }
2049 }
2051 IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
2052 "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
2053 NumberOperationParameters(hint, feedback));
2054}
2055
2057 return &cache_.kEnsureWritableFastElements;
2058}
2059
2061 GrowFastElementsMode mode, const FeedbackSource& feedback) {
2062 if (!feedback.IsValid()) {
2063 switch (mode) {
2065 return &cache_.kGrowFastElementsOperatorDoubleElements;
2067 return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
2068 }
2069 }
2071 IrOpcode::kMaybeGrowFastElements, // opcode
2072 Operator::kNoThrow, // flags
2073 "MaybeGrowFastElements", // name
2074 4, 1, 1, 1, 1, 0, // counts
2075 GrowFastElementsParameters(mode, feedback)); // parameter
2076}
2077
2079 ElementsTransition transition) {
2080 return zone()->New<Operator1<ElementsTransition>>( // --
2081 IrOpcode::kTransitionElementsKind, // opcode
2082 Operator::kNoThrow, // flags
2083 "TransitionElementsKind", // name
2084 1, 1, 1, 0, 1, 0, // counts
2085 transition); // parameter
2086}
2087
2091 IrOpcode::kTransitionElementsKindOrCheckMap, // opcode
2092 Operator::kNoThrow, // flags
2093 "TransitionElementsKindOrCheckMap", // name
2094 1, 1, 1, 0, 1, 0, // counts
2095 transition); // parameter
2096}
2097
2099 return zone()->New<Operator>( // --
2100 IrOpcode::kArgumentsLength, // opcode
2101 Operator::kPure, // flags
2102 "ArgumentsLength", // name
2103 0, 0, 0, 1, 0, 0); // counts
2104}
2105
2107 int formal_parameter_count) {
2108 return zone()->New<Operator1<int>>( // --
2109 IrOpcode::kRestLength, // opcode
2110 Operator::kPure, // flags
2111 "RestLength", // name
2112 0, 0, 0, 1, 0, 0, // counts
2113 formal_parameter_count); // parameter
2114}
2115
2117 ElementsKind elements_kind) {
2118 return zone()->New<Operator1<ElementsKind>>( // --
2119 IrOpcode::kTypedArrayLength, // opcode
2121 "TypedArrayLength", // name
2122 1, 0, 0, 1, 0, 0, // counts
2123 elements_kind); // parameter
2124}
2125
2127 DCHECK(op->opcode() == IrOpcode::kArgumentsLength ||
2128 op->opcode() == IrOpcode::kRestLength);
2129 return OpParameter<int>(op);
2130}
2131
2132bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) {
2133 return lhs.feedback() == rhs.feedback();
2134}
2135
2136size_t hash_value(CheckParameters const& p) {
2137 FeedbackSource::Hash feedback_hash;
2138 return feedback_hash(p.feedback());
2139}
2140
2141std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
2142 return os << p.feedback();
2143}
2144
2146 if (op->opcode() == IrOpcode::kCheckBounds ||
2147 op->opcode() == IrOpcode::kCheckedUint32Bounds ||
2148 op->opcode() == IrOpcode::kCheckedUint64Bounds) {
2149 return OpParameter<CheckBoundsParameters>(op).check_parameters();
2150 }
2151#define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
2153#undef MAKE_OR
2155}
2156
2158 CheckBoundsParameters const& rhs) {
2159 return lhs.check_parameters() == rhs.check_parameters() &&
2160 lhs.flags() == rhs.flags();
2161}
2162
2166
2167std::ostream& operator<<(std::ostream& os, CheckBoundsParameters const& p) {
2168 os << p.check_parameters() << ", " << p.flags();
2169 return os;
2170}
2171
2173 DCHECK(op->opcode() == IrOpcode::kCheckBounds ||
2174 op->opcode() == IrOpcode::kCheckedUint32Bounds ||
2175 op->opcode() == IrOpcode::kCheckedUint64Bounds);
2177}
2178
2179bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) {
2180 return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
2181}
2182
2184 FeedbackSource::Hash feedback_hash;
2185 return base::hash_combine(p.reason(), feedback_hash(p.feedback()));
2186}
2187
2188std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) {
2189 return os << p.reason() << ", " << p.feedback();
2190}
2191
2193 CHECK(op->opcode() == IrOpcode::kCheckIf);
2195}
2196
2198 DCHECK_EQ(IrOpcode::kFastApiCall, op->opcode());
2200}
2201
2202std::ostream& operator<<(std::ostream& os, FastApiCallParameters const& p) {
2203 FastApiCallFunction c_function = p.c_function();
2204 os << c_function.address << ":" << c_function.signature << ", ";
2205 return os << p.feedback() << ", " << p.descriptor();
2206}
2207
2209 FastApiCallFunction c_function = p.c_function();
2210 size_t hash = base::hash_combine(c_function.address, c_function.signature);
2212 p.descriptor());
2213}
2214
2216 FastApiCallParameters const& rhs) {
2217 return lhs.c_function() == rhs.c_function() &&
2218 lhs.feedback() == rhs.feedback() &&
2219 lhs.descriptor() == rhs.descriptor();
2220}
2221
2223 AllocationType allocation) {
2224 return zone()->New<Operator1<AllocationType>>( // --
2225 IrOpcode::kNewDoubleElements, // opcode
2226 Operator::kEliminatable, // flags
2227 "NewDoubleElements", // name
2228 1, 1, 1, 1, 1, 0, // counts
2229 allocation); // parameter
2230}
2231
2233 AllocationType allocation) {
2234 return zone()->New<Operator1<AllocationType>>( // --
2235 IrOpcode::kNewSmiOrObjectElements, // opcode
2236 Operator::kEliminatable, // flags
2237 "NewSmiOrObjectElements", // name
2238 1, 1, 1, 1, 1, 0, // counts
2239 allocation); // parameter
2240}
2241
2243 CreateArgumentsType type, int formal_parameter_count) {
2245 IrOpcode::kNewArgumentsElements, // opcode
2246 Operator::kEliminatable, // flags
2247 "NewArgumentsElements", // name
2248 1, 1, 0, 1, 1, 0, // counts
2250 formal_parameter_count)); // parameter
2251}
2252
2254 const NewArgumentsElementsParameters& rhs) {
2255 return lhs.arguments_type() == rhs.arguments_type() &&
2257}
2258
2259inline size_t hash_value(const NewArgumentsElementsParameters& params) {
2260 return base::hash_combine(params.arguments_type(),
2261 params.formal_parameter_count());
2262}
2263
2264std::ostream& operator<<(std::ostream& os,
2265 const NewArgumentsElementsParameters& params) {
2266 return os << params.arguments_type()
2267 << ", parameter_count = " << params.formal_parameter_count();
2268}
2269
2271 const Operator* op) {
2272 DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
2274}
2275
2277 AllocationType allocation) {
2279 IrOpcode::kAllocate, Operator::kEliminatable, "Allocate", 1, 1, 1, 1, 1,
2280 0, AllocateParameters(type, allocation));
2281}
2282
2284 Type type, AllocationType allocation) {
2286 IrOpcode::kAllocateRaw, Operator::kEliminatable, "AllocateRaw", 1, 1, 1,
2287 1, 1, 1, AllocateParameters(type, allocation));
2288}
2289
2290#define SPECULATIVE_NUMBER_BINOP(Name) \
2291 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
2292 switch (hint) { \
2293 case NumberOperationHint::kSignedSmall: \
2294 return &cache_.k##Name##SignedSmallOperator; \
2295 case NumberOperationHint::kSignedSmallInputs: \
2296 return &cache_.k##Name##SignedSmallInputsOperator; \
2297 case NumberOperationHint::kAdditiveSafeInteger: \
2298 return &cache_.k##Name##SafeIntOperator; \
2299 case NumberOperationHint::kNumber: \
2300 return &cache_.k##Name##NumberOperator; \
2301 case NumberOperationHint::kNumberOrBoolean: \
2302 /* Not used currenly. */ \
2303 UNREACHABLE(); \
2304 case NumberOperationHint::kNumberOrOddball: \
2305 return &cache_.k##Name##NumberOrOddballOperator; \
2306 } \
2307 UNREACHABLE(); \
2308 return nullptr; \
2309 }
2311SPECULATIVE_NUMBER_BINOP(SpeculativeNumberLessThan)
2312SPECULATIVE_NUMBER_BINOP(SpeculativeNumberLessThanOrEqual)
2313#undef SPECULATIVE_NUMBER_BINOP
2315 NumberOperationHint hint) {
2316 switch (hint) {
2318 return &cache_.kSpeculativeNumberEqualSignedSmallOperator;
2320 return &cache_.kSpeculativeNumberEqualSignedSmallInputsOperator;
2323 return &cache_.kSpeculativeNumberEqualNumberOperator;
2325 return &cache_.kSpeculativeNumberEqualNumberOrBooleanOperator;
2327 return &cache_.kSpeculativeNumberEqualNumberOrOddballOperator;
2328 }
2329 UNREACHABLE();
2330}
2331
2332#define ACCESS_OP_LIST(V) \
2333 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
2334 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
2335 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
2336 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
2337 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
2338 V(LoadFromObject, ObjectAccess, Operator::kNoWrite, 2, 1, 1) \
2339 V(StoreToObject, ObjectAccess, Operator::kNoRead, 3, 1, 0) \
2340 V(LoadImmutableFromObject, ObjectAccess, Operator::kNoWrite, 2, 1, 1) \
2341 V(InitializeImmutableInObject, ObjectAccess, Operator::kNoRead, 3, 1, 0) \
2342 V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
2343 V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0)
2344
2345#define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
2346 output_count) \
2347 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
2348 return zone()->New<Operator1<Type>>( \
2349 IrOpcode::k##Name, \
2350 Operator::kNoDeopt | Operator::kNoThrow | properties, #Name, \
2351 value_input_count, 1, control_input_count, output_count, 1, 0, \
2352 access); \
2353 }
2355#undef ACCESS
2356
2358 const FieldAccess& access, bool maybe_initializing_or_transitioning) {
2359 FieldAccess store_access = access;
2361 maybe_initializing_or_transitioning;
2362 return zone()->New<Operator1<FieldAccess>>(
2363 IrOpcode::kStoreField,
2365 2, 1, 1, 0, 1, 0, store_access);
2366}
2367
2368#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
2369const Operator*
2370SimplifiedOperatorBuilder::GetContinuationPreservedEmbedderData() {
2371 return &cache_.kGetContinuationPreservedEmbedderData;
2372}
2373
2374const Operator*
2375SimplifiedOperatorBuilder::SetContinuationPreservedEmbedderData() {
2376 return &cache_.kSetContinuationPreservedEmbedderData;
2377}
2378#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
2379
2381 return zone()->New<Operator>(IrOpcode::kLoadMessage, Operator::kEliminatable,
2382 "LoadMessage", 1, 1, 1, 1, 1, 0);
2383}
2384
2386 return zone()->New<Operator>(
2387 IrOpcode::kStoreMessage,
2389 "StoreMessage", 2, 1, 1, 0, 1, 0);
2390}
2391
2393 return &cache_.kLoadStackArgument;
2394}
2395
2397 MapRef double_map, MapRef fast_map) {
2398 TransitionAndStoreElementParameters parameters(double_map, fast_map);
2400 IrOpcode::kTransitionAndStoreElement,
2401 Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3,
2402 1, 1, 0, 1, 0, parameters);
2403}
2404
2406 return zone()->New<Operator>(IrOpcode::kStoreSignedSmallElement,
2408 "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
2409}
2410
2412 MapRef double_map) {
2413 TransitionAndStoreNumberElementParameters parameters(double_map);
2415 IrOpcode::kTransitionAndStoreNumberElement,
2417 "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
2418}
2419
2421 MapRef fast_map, Type value_type) {
2422 TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
2424 IrOpcode::kTransitionAndStoreNonNumberElement,
2426 "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
2427}
2428
2430 FastApiCallFunction c_function, FeedbackSource const& feedback,
2431 CallDescriptor* descriptor) {
2432 CHECK_NOT_NULL(c_function.signature);
2433 const CFunctionInfo* signature = c_function.signature;
2434 const int c_arg_count = signature->ArgumentCount();
2435 // Arguments for CallApiCallbackOptimizedXXX builtin (including context)
2436 // plus JS arguments (including receiver).
2437 int slow_arg_count = static_cast<int>(descriptor->ParameterCount());
2438
2439 int value_input_count =
2440 FastApiCallNode::ArityForArgc(c_arg_count, slow_arg_count);
2442 IrOpcode::kFastApiCall, Operator::kNoProperties, "FastApiCall",
2443 value_input_count, 1, 1, 1, 1, 2,
2444 FastApiCallParameters(c_function, feedback, descriptor));
2445}
2446
2447// static
2450 const CFunctionInfo* signature = p.c_function().signature;
2451 CHECK_NOT_NULL(signature);
2452 return signature->ArgumentCount();
2453}
2454
2455// static
2458 CallDescriptor* descriptor = p.descriptor();
2459 CHECK_NOT_NULL(descriptor);
2460 return kSlowCodeTarget + static_cast<int>(descriptor->ParameterCount()) +
2462}
2463
2464#undef PURE_OP_LIST
2465#undef EFFECT_DEPENDENT_OP_LIST
2466#undef SPECULATIVE_NUMBER_BINOP_LIST
2467#undef CHECKED_WITH_FEEDBACK_OP_LIST
2468#undef CHECKED_BOUNDS_OP_LIST
2469#undef CHECKED_OP_LIST
2470#undef ACCESS_OP_LIST
2471
2472} // namespace compiler
2473} // namespace internal
2474} // namespace v8
unsigned int ArgumentCount() const
T * New(Args &&... args)
Definition zone.h:114
const CheckParameters & check_parameters() const
FeedbackSource const & feedback() const
static constexpr int ArityForArgc(int c_arg_count, int slow_arg_count)
IndirectHandle< Map > object() const
virtual void PrintParameter(std::ostream &os, PrintVerbosity verbose) const
Definition operator.h:196
constexpr Opcode opcode() const
Definition operator.h:75
const Operator * SpeculativeBigIntAsUintN(int bits, const FeedbackSource &feedback)
const Operator * TransitionElementsKindOrCheckMap(ElementsTransitionWithMultipleSources transition)
const Operator * CheckedInt32Mul(CheckForMinusZeroMode)
const Operator * CheckedTaggedToAdditiveSafeInteger(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * FindOrderedCollectionEntry(CollectionKind collection_kind)
const Operator * TransitionAndStoreElement(MapRef double_map, MapRef fast_map)
const Operator * SpeculativeBigIntAsIntN(int bits, const FeedbackSource &feedback)
const Operator * SpeculativeToBigInt(BigIntOperationHint hint, const FeedbackSource &feedback)
const Operator * CheckedTruncateTaggedToWord32(CheckTaggedInputMode, const FeedbackSource &feedback)
const Operator * ChangeFloat64ToTagged(CheckForMinusZeroMode)
const Operator * CheckedFloat64ToAdditiveSafeInteger(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * RuntimeAbort(AbortReason reason)
const Operator * CheckedTaggedToInt64(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * ConvertReceiver(ConvertReceiverMode)
const Operator * CheckMaps(CheckMapsFlags, ZoneRefSet< Map >, const FeedbackSource &=FeedbackSource())
const Operator * CheckIf(DeoptimizeReason deoptimize_reason, const FeedbackSource &feedback=FeedbackSource())
const Operator * MapGuard(ZoneRefSet< Map > maps)
const Operator * TransitionAndStoreNumberElement(MapRef double_map)
const Operator * CheckedTaggedToInt32(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * CheckedTaggedToFloat64(CheckTaggedInputMode, const FeedbackSource &feedback)
const Operator * MaybeGrowFastElements(GrowFastElementsMode mode, const FeedbackSource &feedback)
const Operator * SpeculativeToNumber(NumberOperationHint hint, const FeedbackSource &feedback)
const Operator * CheckedFloat64ToInt64(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * CheckBounds(const FeedbackSource &feedback, CheckBoundsFlags flags={})
const Operator * TransitionElementsKind(ElementsTransition transition)
const Operator * CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const &)
const Operator * StoreField(FieldAccess const &, bool maybe_initializing_or_transitioning=true)
const Operator * TypedArrayLength(ElementsKind elements_kind)
const Operator * TransitionAndStoreNonNumberElement(MapRef fast_map, Type value_type)
const Operator * SpeculativeBigIntNegate(BigIntOperationHint hint)
const Operator * NewArgumentsElements(CreateArgumentsType type, int formal_parameter_count)
const Operator * CheckedFloat64ToInt32(CheckForMinusZeroMode, const FeedbackSource &feedback)
const Operator * CheckClosure(const Handle< FeedbackCell > &feedback_cell)
const Operator * AllocateRaw(Type type, AllocationType allocation=AllocationType::kYoung)
const Operator * RestLength(int formal_parameter_count)
const Operator * SpeculativeNumberEqual(NumberOperationHint hint)
const Operator * FastApiCall(FastApiCallFunction c_function, FeedbackSource const &feedback, CallDescriptor *descriptor)
const Operator * Allocate(Type type, AllocationType allocation=AllocationType::kYoung)
Zone * zone_
#define DEOPTIMIZE_REASON_LIST(V)
#define DEFINE_LAZY_LEAKY_OBJECT_GETTER(T, FunctionName,...)
#define PURE(Name, properties, value_input_count, control_input_count, output_count)
V8_INLINE size_t hash_value(unsigned int v)
Definition hashing.h:205
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
Definition hashing.h:77
bool operator==(PointerWithPayload< PointerType, PayloadType, NumPayloadBits > lhs, PointerWithPayload< PointerType, PayloadType, NumPayloadBits > rhs)
NumberOperationParameters const & NumberOperationParametersOf(Operator const *op)
FastApiCallParameters const & FastApiCallParametersOf(const Operator *op)
const GrowFastElementsParameters & GrowFastElementsParametersOf(const Operator *op)
CheckParameters const & CheckParametersOf(Operator const *op)
const CheckTaggedInputParameters & CheckTaggedInputParametersOf(const Operator *op)
const NewArgumentsElementsParameters & NewArgumentsElementsParametersOf(const Operator *op)
CheckMapsParameters const & CheckMapsParametersOf(Operator const *op)
CheckFloat64HoleParameters const & CheckFloat64HoleParametersOf(Operator const *op)
CheckIfParameters const & CheckIfParametersOf(Operator const *op)
const CheckMinusZeroParameters & CheckMinusZeroParametersOf(const Operator *op)
int FormalParameterCountOf(const Operator *op)
ZoneRefSet< Map > const & MapGuardMapsOf(Operator const *op)
NumberOperationHint NumberOperationHintOf(const Operator *op)
const FieldAccess & FieldAccessOf(const Operator *op)
const ElementAccess & ElementAccessOf(const Operator *op)
const AllocateParameters & AllocateParametersOf(const Operator *op)
ZoneRefSet< Map > const & CompareMapsParametersOf(Operator const *op)
CheckBoundsParameters const & CheckBoundsParametersOf(Operator const *op)
const ObjectAccess & ObjectAccessOf(const Operator *op)
Type AllocateTypeOf(const Operator *op)
MapRef FastMapParameterOf(const Operator *op)
Handle< FeedbackCell > FeedbackCellOf(const Operator *op)
Type ValueTypeParameterOf(const Operator *op)
size_t hash_value(const BranchParameters &p)
ExternalArrayType ExternalArrayTypeOf(const Operator *op)
T const & OpParameter(const Operator *op)
Definition operator.h:214
ConvertReceiverMode ConvertReceiverModeOf(Operator const *op)
AllocationType AllocationTypeOf(const Operator *op)
bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs)
bool operator==(const BranchParameters &lhs, const BranchParameters &rhs)
CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator *op)
ElementsTransitionWithMultipleSources const & ElementsTransitionWithMultipleSourcesOf(const Operator *op)
std::ostream & operator<<(std::ostream &os, AccessMode access_mode)
BigIntOperationParameters const & BigIntOperationParametersOf(Operator const *op)
ElementsTransition const & ElementsTransitionOf(const Operator *op)
AbortReason AbortReasonOf(const Operator *op)
SpeculativeBigIntAsNParameters const & SpeculativeBigIntAsNParametersOf(Operator const *op)
bool IsCheckedWithFeedback(const Operator *op)
BigIntOperationHint BigIntOperationHintOf(const Operator *op)
MapRef DoubleMapParameterOf(const Operator *op)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
Flag flags[]
Definition flags.cc:3797
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long mode(MIPS/PPC only)") DEFINE_BOOL(partial_constant_pool
constexpr bool Is64()
bool is_signed(Condition cond)
#define SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(V)
Definition opcodes.h:561
#define SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V)
Definition opcodes.h:379
#define SPECULATIVE_BIGINT_BINOP(Name)
#define SPECULATIVE_NUMBER_BINOP(Name)
std::ostream & operator<<(std::ostream &os, const Operation &operation)
Definition operation.h:49
#define GET_FROM_CACHE(Name,...)
#define CHECKED_WITH_FEEDBACK_OP_LIST(V)
#define ACCESS_OP_LIST(V)
#define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, value_output_count)
#define SPECULATIVE_NUMBER_BINOP_LIST(V)
#define CHECKED(Name, value_input_count, value_output_count)
MapRef const fast_map_
#define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count)
#define ACCESS(Name, Type, properties, value_input_count, control_input_count, output_count)
#define CHECK_IF(Name, message)
#define CHECKED_OP_LIST(V)
#define EFFECT_DEPENDENT(Name, properties, value_input_count, control_input_count)
#define CHECKED_BOUNDS_OP_LIST(V)
Type value_type_
#define CHECKED_BOUNDS(Name)
#define MAKE_OR(name, arg2, arg3)
MapRef const double_map_
#define EFFECT_DEPENDENT_OP_LIST(V)
#define PURE_OP_LIST(V)
#define UNREACHABLE()
Definition logging.h:67
#define CHECK(condition)
Definition logging.h:124
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define CHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460
CheckFloat64HoleNaNOperator< CheckFloat64HoleMode::kAllowReturnHole > kCheckFloat64HoleAllowReturnHoleOperator
CheckedTaggedToFloat64Operator< CheckTaggedInputMode::kNumber > kCheckedTaggedToFloat64NumberOperator
CheckedTruncateTaggedToWord32Operator< CheckTaggedInputMode::kAdditiveSafeInteger > kCheckedTruncateTaggedToWord32AdditiveSafeIntegerOperator
CheckedFloat64ToInt64Operator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedFloat64ToInt64CheckForMinusZeroOperator
GrowFastElementsOperator< GrowFastElementsMode::kSmiOrObjectElements > kGrowFastElementsOperatorSmiOrObjectElements
CheckedTaggedToFloat64Operator< CheckTaggedInputMode::kNumberOrOddball > kCheckedTaggedToFloat64NumberOrOddballOperator
ConvertReceiverOperator< ConvertReceiverMode::kNullOrUndefined > kConvertReceiverNullOrUndefinedOperator
CheckFloat64HoleNaNOperator< CheckFloat64HoleMode::kNeverReturnHole > kCheckFloat64HoleNeverReturnHoleOperator
ChangeFloat64ToTaggedOperator< CheckForMinusZeroMode::kDontCheckForMinusZero > kChangeFloat64ToTaggedDontCheckForMinusZeroOperator
GrowFastElementsOperator< GrowFastElementsMode::kDoubleElements > kGrowFastElementsOperatorDoubleElements
SpeculativeToNumberOperator< NumberOperationHint::kNumberOrOddball > kSpeculativeToNumberNumberOrOddballOperator
CheckedFloat64ToAdditiveSafeIntegerOperator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedFloat64ToAddSafeIntCheckForMinusZeroOperator
CheckedInt32MulOperator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedInt32MulCheckForMinusZeroOperator
ConvertReceiverOperator< ConvertReceiverMode::kAny > kConvertReceiverAnyOperator
CheckedTaggedToInt32Operator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedTaggedToInt32DontCheckForMinusZeroOperator
CheckedTruncateTaggedToWord32Operator< CheckTaggedInputMode::kNumber > kCheckedTruncateTaggedToWord32NumberOperator
CheckedFloat64ToInt64Operator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedFloat64ToInt64DontCheckForMinusZeroOperator
CheckedFloat64ToInt32Operator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedFloat64ToInt32CheckForMinusZeroOperator
CheckedTruncateTaggedToWord32Operator< CheckTaggedInputMode::kNumberOrOddball > kCheckedTruncateTaggedToWord32NumberOrOddballOperator
CheckedTaggedToAdditiveSafeIntegerOperator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedTaggedToAddSafeIntCheckForMinusZeroOperator
ConvertReceiverOperator< ConvertReceiverMode::kNotNullOrUndefined > kConvertReceiverNotNullOrUndefinedOperator
CheckedTaggedToInt64Operator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedTaggedToInt64CheckForMinusZeroOperator
SpeculativeNumberEqualOperator< NumberOperationHint::kNumberOrBoolean > kSpeculativeNumberEqualNumberOrBooleanOperator
SpeculativeToBigIntOperator< BigIntOperationHint::kBigInt64 > kSpeculativeToBigIntBigInt64Operator
SpeculativeToNumberOperator< NumberOperationHint::kSignedSmall > kSpeculativeToNumberSignedSmallOperator
CheckedTaggedToInt32Operator< CheckForMinusZeroMode::kCheckForMinusZero > kCheckedTaggedToInt32CheckForMinusZeroOperator
SpeculativeToNumberOperator< NumberOperationHint::kNumber > kSpeculativeToNumberNumberOperator
CheckedFloat64ToInt32Operator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedFloat64ToInt32DontCheckForMinusZeroOperator
SpeculativeToBigIntOperator< BigIntOperationHint::kBigInt > kSpeculativeToBigIntBigIntOperator
FindOrderedHashMapEntryForInt32KeyOperator kFindOrderedHashMapEntryForInt32Key
CheckedFloat64ToAdditiveSafeIntegerOperator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedFloat64ToAddSafeIntDontCheckForMinusZeroOperator
EnsureWritableFastElementsOperator kEnsureWritableFastElements
CheckedTaggedToFloat64Operator< CheckTaggedInputMode::kNumberOrBoolean > kCheckedTaggedToFloat64NumberOrBooleanOperator
CheckedInt32MulOperator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedInt32MulDontCheckForMinusZeroOperator
CheckedTaggedToAdditiveSafeIntegerOperator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedTaggedToAddSafeIntDontCheckForMinusZeroOperator
ChangeFloat64ToTaggedOperator< CheckForMinusZeroMode::kCheckForMinusZero > kChangeFloat64ToTaggedCheckForMinusZeroOperator
CheckedTaggedToInt64Operator< CheckForMinusZeroMode::kDontCheckForMinusZero > kCheckedTaggedToInt64DontCheckForMinusZeroOperator
wasm::ValueType type