• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
7 
8 #include <iosfwd>
9 
10 #include "src/base/compiler-specific.h"
11 #include "src/codegen/machine-type.h"
12 #include "src/codegen/tnode.h"
13 #include "src/common/globals.h"
14 #include "src/compiler/feedback-source.h"
15 #include "src/compiler/node-properties.h"
16 #include "src/compiler/operator.h"
17 #include "src/compiler/types.h"
18 #include "src/compiler/write-barrier-kind.h"
19 #include "src/deoptimizer/deoptimize-reason.h"
20 #include "src/handles/handles.h"
21 #include "src/handles/maybe-handles.h"
22 #include "src/objects/objects.h"
23 #include "src/objects/type-hints.h"
24 #include "src/zone/zone-handle-set.h"
25 
26 namespace v8 {
27 class CFunctionInfo;
28 
29 namespace internal {
30 
31 // Forward declarations.
32 enum class AbortReason : uint8_t;
33 class Zone;
34 
35 namespace compiler {
36 
37 // Forward declarations.
38 class Operator;
39 struct SimplifiedOperatorGlobalCache;
40 class CallDescriptor;
41 
42 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
43 
44 size_t hash_value(BaseTaggedness);
45 
46 std::ostream& operator<<(std::ostream&, BaseTaggedness);
47 
48 size_t hash_value(LoadSensitivity);
49 
50 std::ostream& operator<<(std::ostream&, LoadSensitivity);
51 
52 struct ConstFieldInfo {
53   // the map that introduced the const field, if any. An access is considered
54   // mutable iff the handle is null.
55   MaybeHandle<Map> owner_map;
56 
ConstFieldInfoConstFieldInfo57   ConstFieldInfo() : owner_map(MaybeHandle<Map>()) {}
ConstFieldInfoConstFieldInfo58   explicit ConstFieldInfo(Handle<Map> owner_map) : owner_map(owner_map) {}
59 
IsConstConstFieldInfo60   bool IsConst() const { return !owner_map.is_null(); }
61 
62   // No const field owner, i.e., a mutable field
NoneConstFieldInfo63   static ConstFieldInfo None() { return ConstFieldInfo(); }
64 };
65 
66 V8_EXPORT_PRIVATE bool operator==(ConstFieldInfo const&, ConstFieldInfo const&);
67 
68 size_t hash_value(ConstFieldInfo const&);
69 
70 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
71                                            ConstFieldInfo const&);
72 
73 // An access descriptor for loads/stores of fixed structures like field
74 // accesses of heap objects. Accesses from either tagged or untagged base
75 // pointers are supported; untagging is done automatically during lowering.
76 struct FieldAccess {
77   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
78   int offset;                     // offset of the field, without tag.
79   MaybeHandle<Name> name;         // debugging only.
80   MaybeHandle<Map> map;           // map of the field value (if known).
81   Type type;                      // type of the field.
82   MachineType machine_type;       // machine type of the field.
83   WriteBarrierKind write_barrier_kind;  // write barrier hint.
84   LoadSensitivity load_sensitivity;     // load safety for poisoning.
85   ConstFieldInfo const_field_info;      // the constness of this access, and the
86                                     // field owner map, if the access is const
87   bool is_store_in_literal;  // originates from a kStoreInLiteral access
88 #ifdef V8_HEAP_SANDBOX
89   ExternalPointerTag external_pointer_tag = kExternalPointerNullTag;
90 #endif
91 
FieldAccessFieldAccess92   FieldAccess()
93       : base_is_tagged(kTaggedBase),
94         offset(0),
95         type(Type::None()),
96         machine_type(MachineType::None()),
97         write_barrier_kind(kFullWriteBarrier),
98         load_sensitivity(LoadSensitivity::kUnsafe),
99         const_field_info(ConstFieldInfo::None()),
100         is_store_in_literal(false) {}
101 
102   FieldAccess(BaseTaggedness base_is_tagged, int offset, MaybeHandle<Name> name,
103               MaybeHandle<Map> map, Type type, MachineType machine_type,
104               WriteBarrierKind write_barrier_kind,
105               LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe,
106               ConstFieldInfo const_field_info = ConstFieldInfo::None(),
107               bool is_store_in_literal = false
108 #ifdef V8_HEAP_SANDBOX
109               ,
110               ExternalPointerTag external_pointer_tag = kExternalPointerNullTag
111 #endif
112               )
base_is_taggedFieldAccess113       : base_is_tagged(base_is_tagged),
114         offset(offset),
115         name(name),
116         map(map),
117         type(type),
118         machine_type(machine_type),
119         write_barrier_kind(write_barrier_kind),
120         load_sensitivity(load_sensitivity),
121         const_field_info(const_field_info),
122         is_store_in_literal(is_store_in_literal)
123 #ifdef V8_HEAP_SANDBOX
124         ,
125         external_pointer_tag(external_pointer_tag)
126 #endif
127   {
128     DCHECK_GE(offset, 0);
129   }
130 
tagFieldAccess131   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
132 };
133 
134 V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
135 
136 size_t hash_value(FieldAccess const&);
137 
138 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
139 
140 V8_EXPORT_PRIVATE FieldAccess const& FieldAccessOf(const Operator* op)
141     V8_WARN_UNUSED_RESULT;
142 
143 template <>
144 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
145                                             PrintVerbosity verbose) const;
146 
147 // An access descriptor for loads/stores of indexed structures like characters
148 // in strings or off-heap backing stores. Accesses from either tagged or
149 // untagged base pointers are supported; untagging is done automatically during
150 // lowering.
151 struct ElementAccess {
152   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
153   int header_size;                // size of the header, without tag.
154   Type type;                      // type of the element.
155   MachineType machine_type;       // machine type of the element.
156   WriteBarrierKind write_barrier_kind;  // write barrier hint.
157   LoadSensitivity load_sensitivity;     // load safety for poisoning.
158 
ElementAccessElementAccess159   ElementAccess()
160       : base_is_tagged(kTaggedBase),
161         header_size(0),
162         type(Type::None()),
163         machine_type(MachineType::None()),
164         write_barrier_kind(kFullWriteBarrier),
165         load_sensitivity(LoadSensitivity::kUnsafe) {}
166 
167   ElementAccess(BaseTaggedness base_is_tagged, int header_size, Type type,
168                 MachineType machine_type, WriteBarrierKind write_barrier_kind,
169                 LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe)
base_is_taggedElementAccess170       : base_is_tagged(base_is_tagged),
171         header_size(header_size),
172         type(type),
173         machine_type(machine_type),
174         write_barrier_kind(write_barrier_kind),
175         load_sensitivity(load_sensitivity) {}
176 
tagElementAccess177   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
178 };
179 
180 V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&);
181 
182 size_t hash_value(ElementAccess const&);
183 
184 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&);
185 
186 V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op)
187     V8_WARN_UNUSED_RESULT;
188 
189 ExternalArrayType ExternalArrayTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
190 
191 // An access descriptor for loads/stores of CSA-accessible structures.
192 struct ObjectAccess {
193   MachineType machine_type;             // machine type of the field.
194   WriteBarrierKind write_barrier_kind;  // write barrier hint.
195 
ObjectAccessObjectAccess196   ObjectAccess()
197       : machine_type(MachineType::None()),
198         write_barrier_kind(kFullWriteBarrier) {}
199 
ObjectAccessObjectAccess200   ObjectAccess(MachineType machine_type, WriteBarrierKind write_barrier_kind)
201       : machine_type(machine_type), write_barrier_kind(write_barrier_kind) {}
202 
tagObjectAccess203   int tag() const { return kHeapObjectTag; }
204 };
205 
206 V8_EXPORT_PRIVATE bool operator==(ObjectAccess const&, ObjectAccess const&);
207 
208 size_t hash_value(ObjectAccess const&);
209 
210 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ObjectAccess const&);
211 
212 V8_EXPORT_PRIVATE ObjectAccess const& ObjectAccessOf(const Operator* op)
213     V8_WARN_UNUSED_RESULT;
214 
215 // The ConvertReceiverMode is used as parameter by ConvertReceiver operators.
216 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op)
217     V8_WARN_UNUSED_RESULT;
218 
219 // A the parameters for several Check nodes. The {feedback} parameter is
220 // optional. If {feedback} references a valid CallIC slot and this MapCheck
221 // fails, then speculation on that CallIC slot will be disabled.
222 class CheckParameters final {
223  public:
CheckParameters(const FeedbackSource & feedback)224   explicit CheckParameters(const FeedbackSource& feedback)
225       : feedback_(feedback) {}
226 
feedback()227   FeedbackSource const& feedback() const { return feedback_; }
228 
229  private:
230   FeedbackSource feedback_;
231 };
232 
233 bool operator==(CheckParameters const&, CheckParameters const&);
234 
235 size_t hash_value(CheckParameters const&);
236 
237 std::ostream& operator<<(std::ostream&, CheckParameters const&);
238 
239 CheckParameters const& CheckParametersOf(Operator const*) V8_WARN_UNUSED_RESULT;
240 
241 enum class CheckBoundsFlag : uint8_t {
242   kConvertStringAndMinusZero = 1 << 0,  // instead of deopting on such inputs
243   kAbortOnOutOfBounds = 1 << 1,         // instead of deopting if input is OOB
244 };
245 using CheckBoundsFlags = base::Flags<CheckBoundsFlag>;
DEFINE_OPERATORS_FOR_FLAGS(CheckBoundsFlags)246 DEFINE_OPERATORS_FOR_FLAGS(CheckBoundsFlags)
247 
248 class CheckBoundsParameters final {
249  public:
250   CheckBoundsParameters(const FeedbackSource& feedback, CheckBoundsFlags flags)
251       : check_parameters_(feedback), flags_(flags) {}
252 
253   CheckBoundsFlags flags() const { return flags_; }
254   const CheckParameters& check_parameters() const { return check_parameters_; }
255 
256  private:
257   CheckParameters check_parameters_;
258   CheckBoundsFlags flags_;
259 };
260 
261 bool operator==(CheckBoundsParameters const&, CheckBoundsParameters const&);
262 
263 size_t hash_value(CheckBoundsParameters const&);
264 
265 std::ostream& operator<<(std::ostream&, CheckBoundsParameters const&);
266 
267 CheckBoundsParameters const& CheckBoundsParametersOf(Operator const*)
268     V8_WARN_UNUSED_RESULT;
269 
270 class CheckIfParameters final {
271  public:
CheckIfParameters(DeoptimizeReason reason,const FeedbackSource & feedback)272   explicit CheckIfParameters(DeoptimizeReason reason,
273                              const FeedbackSource& feedback)
274       : reason_(reason), feedback_(feedback) {}
275 
feedback()276   FeedbackSource const& feedback() const { return feedback_; }
reason()277   DeoptimizeReason reason() const { return reason_; }
278 
279  private:
280   DeoptimizeReason reason_;
281   FeedbackSource feedback_;
282 };
283 
284 bool operator==(CheckIfParameters const&, CheckIfParameters const&);
285 
286 size_t hash_value(CheckIfParameters const&);
287 
288 std::ostream& operator<<(std::ostream&, CheckIfParameters const&);
289 
290 CheckIfParameters const& CheckIfParametersOf(Operator const*)
291     V8_WARN_UNUSED_RESULT;
292 
293 enum class CheckFloat64HoleMode : uint8_t {
294   kNeverReturnHole,  // Never return the hole (deoptimize instead).
295   kAllowReturnHole   // Allow to return the hole (signaling NaN).
296 };
297 
298 size_t hash_value(CheckFloat64HoleMode);
299 
300 std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
301 
302 class CheckFloat64HoleParameters {
303  public:
CheckFloat64HoleParameters(CheckFloat64HoleMode mode,FeedbackSource const & feedback)304   CheckFloat64HoleParameters(CheckFloat64HoleMode mode,
305                              FeedbackSource const& feedback)
306       : mode_(mode), feedback_(feedback) {}
307 
mode()308   CheckFloat64HoleMode mode() const { return mode_; }
feedback()309   FeedbackSource const& feedback() const { return feedback_; }
310 
311  private:
312   CheckFloat64HoleMode mode_;
313   FeedbackSource feedback_;
314 };
315 
316 CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(Operator const*)
317     V8_WARN_UNUSED_RESULT;
318 
319 std::ostream& operator<<(std::ostream&, CheckFloat64HoleParameters const&);
320 
321 size_t hash_value(CheckFloat64HoleParameters const&);
322 
323 bool operator==(CheckFloat64HoleParameters const&,
324                 CheckFloat64HoleParameters const&);
325 bool operator!=(CheckFloat64HoleParameters const&,
326                 CheckFloat64HoleParameters const&);
327 
328 // Parameter for CheckClosure node.
329 Handle<FeedbackCell> FeedbackCellOf(const Operator* op);
330 
331 enum class CheckTaggedInputMode : uint8_t {
332   kNumber,
333   kNumberOrBoolean,
334   kNumberOrOddball,
335 };
336 
337 size_t hash_value(CheckTaggedInputMode);
338 
339 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
340 
341 class CheckTaggedInputParameters {
342  public:
CheckTaggedInputParameters(CheckTaggedInputMode mode,const FeedbackSource & feedback)343   CheckTaggedInputParameters(CheckTaggedInputMode mode,
344                              const FeedbackSource& feedback)
345       : mode_(mode), feedback_(feedback) {}
346 
mode()347   CheckTaggedInputMode mode() const { return mode_; }
feedback()348   const FeedbackSource& feedback() const { return feedback_; }
349 
350  private:
351   CheckTaggedInputMode mode_;
352   FeedbackSource feedback_;
353 };
354 
355 const CheckTaggedInputParameters& CheckTaggedInputParametersOf(const Operator*)
356     V8_WARN_UNUSED_RESULT;
357 
358 std::ostream& operator<<(std::ostream&,
359                          const CheckTaggedInputParameters& params);
360 
361 size_t hash_value(const CheckTaggedInputParameters& params);
362 
363 bool operator==(CheckTaggedInputParameters const&,
364                 CheckTaggedInputParameters const&);
365 
366 enum class CheckForMinusZeroMode : uint8_t {
367   kCheckForMinusZero,
368   kDontCheckForMinusZero,
369 };
370 
371 size_t hash_value(CheckForMinusZeroMode);
372 
373 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
374                                            CheckForMinusZeroMode);
375 
376 CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*)
377     V8_WARN_UNUSED_RESULT;
378 
379 class CheckMinusZeroParameters {
380  public:
CheckMinusZeroParameters(CheckForMinusZeroMode mode,const FeedbackSource & feedback)381   CheckMinusZeroParameters(CheckForMinusZeroMode mode,
382                            const FeedbackSource& feedback)
383       : mode_(mode), feedback_(feedback) {}
384 
mode()385   CheckForMinusZeroMode mode() const { return mode_; }
feedback()386   const FeedbackSource& feedback() const { return feedback_; }
387 
388  private:
389   CheckForMinusZeroMode mode_;
390   FeedbackSource feedback_;
391 };
392 
393 V8_EXPORT_PRIVATE const CheckMinusZeroParameters& CheckMinusZeroParametersOf(
394     const Operator* op) V8_WARN_UNUSED_RESULT;
395 
396 V8_EXPORT_PRIVATE std::ostream& operator<<(
397     std::ostream&, const CheckMinusZeroParameters& params);
398 
399 size_t hash_value(const CheckMinusZeroParameters& params);
400 
401 bool operator==(CheckMinusZeroParameters const&,
402                 CheckMinusZeroParameters const&);
403 
404 enum class CheckMapsFlag : uint8_t {
405   kNone = 0u,
406   kTryMigrateInstance = 1u << 0,
407 };
408 using CheckMapsFlags = base::Flags<CheckMapsFlag>;
409 
410 DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags)
411 
412 std::ostream& operator<<(std::ostream&, CheckMapsFlags);
413 
414 // A descriptor for map checks. The {feedback} parameter is optional.
415 // If {feedback} references a valid CallIC slot and this MapCheck fails,
416 // then speculation on that CallIC slot will be disabled.
417 class CheckMapsParameters final {
418  public:
CheckMapsParameters(CheckMapsFlags flags,ZoneHandleSet<Map> const & maps,const FeedbackSource & feedback)419   CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps,
420                       const FeedbackSource& feedback)
421       : flags_(flags), maps_(maps), feedback_(feedback) {}
422 
flags()423   CheckMapsFlags flags() const { return flags_; }
maps()424   ZoneHandleSet<Map> const& maps() const { return maps_; }
feedback()425   FeedbackSource const& feedback() const { return feedback_; }
426 
427  private:
428   CheckMapsFlags const flags_;
429   ZoneHandleSet<Map> const maps_;
430   FeedbackSource const feedback_;
431 };
432 
433 bool operator==(CheckMapsParameters const&, CheckMapsParameters const&);
434 
435 size_t hash_value(CheckMapsParameters const&);
436 
437 std::ostream& operator<<(std::ostream&, CheckMapsParameters const&);
438 
439 CheckMapsParameters const& CheckMapsParametersOf(Operator const*)
440     V8_WARN_UNUSED_RESULT;
441 
442 // A descriptor for dynamic map checks.
443 class DynamicCheckMapsParameters final {
444  public:
445   enum ICState { kMonomorphic, kPolymorphic };
446 
DynamicCheckMapsParameters(CheckMapsFlags flags,Handle<Object> handler,ZoneHandleSet<Map> const & maps,const FeedbackSource & feedback)447   DynamicCheckMapsParameters(CheckMapsFlags flags, Handle<Object> handler,
448                              ZoneHandleSet<Map> const& maps,
449                              const FeedbackSource& feedback)
450       : flags_(flags), handler_(handler), maps_(maps), feedback_(feedback) {}
451 
flags()452   CheckMapsFlags flags() const { return flags_; }
handler()453   Handle<Object> handler() const { return handler_; }
maps()454   ZoneHandleSet<Map> const& maps() const { return maps_; }
feedback()455   FeedbackSource const& feedback() const { return feedback_; }
state()456   ICState state() const {
457     return maps_.size() == 1 ? ICState::kMonomorphic : ICState::kPolymorphic;
458   }
459 
460  private:
461   CheckMapsFlags const flags_;
462   Handle<Object> const handler_;
463   ZoneHandleSet<Map> const maps_;
464   FeedbackSource const feedback_;
465 };
466 
467 bool operator==(DynamicCheckMapsParameters const&,
468                 DynamicCheckMapsParameters const&);
469 
470 size_t hash_value(DynamicCheckMapsParameters const&);
471 
472 std::ostream& operator<<(std::ostream&, DynamicCheckMapsParameters const&);
473 
474 DynamicCheckMapsParameters const& DynamicCheckMapsParametersOf(Operator const*)
475     V8_WARN_UNUSED_RESULT;
476 
477 ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const*) V8_WARN_UNUSED_RESULT;
478 
479 // Parameters for CompareMaps operator.
480 ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const*)
481     V8_WARN_UNUSED_RESULT;
482 
483 // A descriptor for growing elements backing stores.
484 enum class GrowFastElementsMode : uint8_t {
485   kDoubleElements,
486   kSmiOrObjectElements
487 };
488 
hash_value(GrowFastElementsMode mode)489 inline size_t hash_value(GrowFastElementsMode mode) {
490   return static_cast<uint8_t>(mode);
491 }
492 
493 std::ostream& operator<<(std::ostream&, GrowFastElementsMode);
494 
495 class GrowFastElementsParameters {
496  public:
GrowFastElementsParameters(GrowFastElementsMode mode,const FeedbackSource & feedback)497   GrowFastElementsParameters(GrowFastElementsMode mode,
498                              const FeedbackSource& feedback)
499       : mode_(mode), feedback_(feedback) {}
500 
mode()501   GrowFastElementsMode mode() const { return mode_; }
feedback()502   const FeedbackSource& feedback() const { return feedback_; }
503 
504  private:
505   GrowFastElementsMode mode_;
506   FeedbackSource feedback_;
507 };
508 
509 bool operator==(const GrowFastElementsParameters&,
510                 const GrowFastElementsParameters&);
511 
512 inline size_t hash_value(const GrowFastElementsParameters&);
513 
514 std::ostream& operator<<(std::ostream&, const GrowFastElementsParameters&);
515 
516 const GrowFastElementsParameters& GrowFastElementsParametersOf(const Operator*)
517     V8_WARN_UNUSED_RESULT;
518 
519 // A descriptor for elements kind transitions.
520 class ElementsTransition final {
521  public:
522   enum Mode : uint8_t {
523     kFastTransition,  // simple transition, just updating the map.
524     kSlowTransition   // full transition, round-trip to the runtime.
525   };
526 
ElementsTransition(Mode mode,Handle<Map> source,Handle<Map> target)527   ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
528       : mode_(mode), source_(source), target_(target) {}
529 
mode()530   Mode mode() const { return mode_; }
source()531   Handle<Map> source() const { return source_; }
target()532   Handle<Map> target() const { return target_; }
533 
534  private:
535   Mode const mode_;
536   Handle<Map> const source_;
537   Handle<Map> const target_;
538 };
539 
540 bool operator==(ElementsTransition const&, ElementsTransition const&);
541 
542 size_t hash_value(ElementsTransition);
543 
544 std::ostream& operator<<(std::ostream&, ElementsTransition);
545 
546 ElementsTransition const& ElementsTransitionOf(const Operator* op)
547     V8_WARN_UNUSED_RESULT;
548 
549 // Parameters for TransitionAndStoreElement, or
550 // TransitionAndStoreNonNumberElement, or
551 // TransitionAndStoreNumberElement.
552 Handle<Map> DoubleMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
553 Handle<Map> FastMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
554 
555 // Parameters for TransitionAndStoreNonNumberElement.
556 Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
557 
558 // A hint for speculative number operations.
559 enum class NumberOperationHint : uint8_t {
560   kSignedSmall,        // Inputs were Smi, output was in Smi.
561   kSignedSmallInputs,  // Inputs were Smi, output was Number.
562   kSigned32,           // Inputs were Signed32, output was Number.
563   kNumber,             // Inputs were Number, output was Number.
564   kNumberOrBoolean,    // Inputs were Number or Boolean, output was Number.
565   kNumberOrOddball,    // Inputs were Number or Oddball, output was Number.
566 };
567 
568 enum class BigIntOperationHint : uint8_t {
569   kBigInt,
570 };
571 
572 size_t hash_value(NumberOperationHint);
573 size_t hash_value(BigIntOperationHint);
574 
575 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
576 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint);
577 V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op)
578     V8_WARN_UNUSED_RESULT;
579 
580 class NumberOperationParameters {
581  public:
NumberOperationParameters(NumberOperationHint hint,const FeedbackSource & feedback)582   NumberOperationParameters(NumberOperationHint hint,
583                             const FeedbackSource& feedback)
584       : hint_(hint), feedback_(feedback) {}
585 
hint()586   NumberOperationHint hint() const { return hint_; }
feedback()587   const FeedbackSource& feedback() const { return feedback_; }
588 
589  private:
590   NumberOperationHint hint_;
591   FeedbackSource feedback_;
592 };
593 
594 size_t hash_value(NumberOperationParameters const&);
595 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
596                                            const NumberOperationParameters&);
597 bool operator==(NumberOperationParameters const&,
598                 NumberOperationParameters const&);
599 const NumberOperationParameters& NumberOperationParametersOf(const Operator* op)
600     V8_WARN_UNUSED_RESULT;
601 
602 int FormalParameterCountOf(const Operator* op) V8_WARN_UNUSED_RESULT;
603 
604 class AllocateParameters {
605  public:
606   AllocateParameters(
607       Type type, AllocationType allocation_type,
608       AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse)
type_(type)609       : type_(type),
610         allocation_type_(allocation_type),
611         allow_large_objects_(allow_large_objects) {}
612 
type()613   Type type() const { return type_; }
allocation_type()614   AllocationType allocation_type() const { return allocation_type_; }
allow_large_objects()615   AllowLargeObjects allow_large_objects() const { return allow_large_objects_; }
616 
617  private:
618   Type type_;
619   AllocationType allocation_type_;
620   AllowLargeObjects allow_large_objects_;
621 };
622 
623 bool IsCheckedWithFeedback(const Operator* op);
624 
625 size_t hash_value(AllocateParameters);
626 
627 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters);
628 
629 bool operator==(AllocateParameters const&, AllocateParameters const&);
630 
631 const AllocateParameters& AllocateParametersOf(const Operator* op)
632     V8_WARN_UNUSED_RESULT;
633 
634 AllocationType AllocationTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
635 
636 Type AllocateTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
637 
638 UnicodeEncoding UnicodeEncodingOf(const Operator*) V8_WARN_UNUSED_RESULT;
639 
640 AbortReason AbortReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
641 
642 DeoptimizeReason DeoptimizeReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
643 
644 class NewArgumentsElementsParameters {
645  public:
NewArgumentsElementsParameters(CreateArgumentsType type,int formal_parameter_count)646   NewArgumentsElementsParameters(CreateArgumentsType type,
647                                  int formal_parameter_count)
648       : type_(type), formal_parameter_count_(formal_parameter_count) {}
649 
arguments_type()650   CreateArgumentsType arguments_type() const { return type_; }
formal_parameter_count()651   int formal_parameter_count() const { return formal_parameter_count_; }
652 
653  private:
654   CreateArgumentsType type_;
655   int formal_parameter_count_;
656 };
657 
658 bool operator==(const NewArgumentsElementsParameters&,
659                 const NewArgumentsElementsParameters&);
660 
661 inline size_t hash_value(const NewArgumentsElementsParameters&);
662 
663 std::ostream& operator<<(std::ostream&, const NewArgumentsElementsParameters&);
664 
665 const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf(
666     const Operator*) V8_WARN_UNUSED_RESULT;
667 
668 class FastApiCallParameters {
669  public:
FastApiCallParameters(const CFunctionInfo * signature,FeedbackSource const & feedback,CallDescriptor * descriptor)670   explicit FastApiCallParameters(const CFunctionInfo* signature,
671                                  FeedbackSource const& feedback,
672                                  CallDescriptor* descriptor)
673       : signature_(signature), feedback_(feedback), descriptor_(descriptor) {}
674 
signature()675   const CFunctionInfo* signature() const { return signature_; }
feedback()676   FeedbackSource const& feedback() const { return feedback_; }
descriptor()677   CallDescriptor* descriptor() const { return descriptor_; }
678 
679  private:
680   const CFunctionInfo* signature_;
681   const FeedbackSource feedback_;
682   CallDescriptor* descriptor_;
683 };
684 
685 FastApiCallParameters const& FastApiCallParametersOf(const Operator* op)
686     V8_WARN_UNUSED_RESULT;
687 
688 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
689                                            FastApiCallParameters const&);
690 
691 size_t hash_value(FastApiCallParameters const&);
692 
693 bool operator==(FastApiCallParameters const&, FastApiCallParameters const&);
694 
695 // Interface for building simplified operators, which represent the
696 // medium-level operations of V8, including adding numbers, allocating objects,
697 // indexing into objects and arrays, etc.
698 // All operators are typed but many are representation independent.
699 
700 // Number values from JS can be in one of these representations:
701 //   - Tagged: word-sized integer that is either
702 //     - a signed small integer (31 or 32 bits plus a tag)
703 //     - a tagged pointer to a HeapNumber object that has a float64 field
704 //   - Int32: an untagged signed 32-bit integer
705 //   - Uint32: an untagged unsigned 32-bit integer
706 //   - Float64: an untagged float64
707 
708 // Additional representations for intermediate code or non-JS code:
709 //   - Int64: an untagged signed 64-bit integer
710 //   - Uint64: an untagged unsigned 64-bit integer
711 //   - Float32: an untagged float32
712 
713 // Boolean values can be:
714 //   - Bool: a tagged pointer to either the canonical JS #false or
715 //           the canonical JS #true object
716 //   - Bit: an untagged integer 0 or 1, but word-sized
717 class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)718     : public NON_EXPORTED_BASE(ZoneObject) {
719  public:
720   explicit SimplifiedOperatorBuilder(Zone* zone);
721   SimplifiedOperatorBuilder(const SimplifiedOperatorBuilder&) = delete;
722   SimplifiedOperatorBuilder& operator=(const SimplifiedOperatorBuilder&) =
723       delete;
724 
725   const Operator* BooleanNot();
726 
727   const Operator* NumberEqual();
728   const Operator* NumberSameValue();
729   const Operator* NumberLessThan();
730   const Operator* NumberLessThanOrEqual();
731   const Operator* NumberAdd();
732   const Operator* NumberSubtract();
733   const Operator* NumberMultiply();
734   const Operator* NumberDivide();
735   const Operator* NumberModulus();
736   const Operator* NumberBitwiseOr();
737   const Operator* NumberBitwiseXor();
738   const Operator* NumberBitwiseAnd();
739   const Operator* NumberShiftLeft();
740   const Operator* NumberShiftRight();
741   const Operator* NumberShiftRightLogical();
742   const Operator* NumberImul();
743   const Operator* NumberAbs();
744   const Operator* NumberClz32();
745   const Operator* NumberCeil();
746   const Operator* NumberFloor();
747   const Operator* NumberFround();
748   const Operator* NumberAcos();
749   const Operator* NumberAcosh();
750   const Operator* NumberAsin();
751   const Operator* NumberAsinh();
752   const Operator* NumberAtan();
753   const Operator* NumberAtan2();
754   const Operator* NumberAtanh();
755   const Operator* NumberCbrt();
756   const Operator* NumberCos();
757   const Operator* NumberCosh();
758   const Operator* NumberExp();
759   const Operator* NumberExpm1();
760   const Operator* NumberLog();
761   const Operator* NumberLog1p();
762   const Operator* NumberLog10();
763   const Operator* NumberLog2();
764   const Operator* NumberMax();
765   const Operator* NumberMin();
766   const Operator* NumberPow();
767   const Operator* NumberRound();
768   const Operator* NumberSign();
769   const Operator* NumberSin();
770   const Operator* NumberSinh();
771   const Operator* NumberSqrt();
772   const Operator* NumberTan();
773   const Operator* NumberTanh();
774   const Operator* NumberTrunc();
775   const Operator* NumberToBoolean();
776   const Operator* NumberToInt32();
777   const Operator* NumberToString();
778   const Operator* NumberToUint32();
779   const Operator* NumberToUint8Clamped();
780 
781   const Operator* NumberSilenceNaN();
782 
783   const Operator* BigIntAdd();
784   const Operator* BigIntSubtract();
785   const Operator* BigIntNegate();
786 
787   const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint);
788   const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint);
789 
790   const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
791   const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
792   const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
793   const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
794   const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
795   const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
796   const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
797   const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
798   const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
799   const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
800   const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
801 
802   const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
803   const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
804   const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
805 
806   const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint);
807   const Operator* SpeculativeBigIntSubtract(BigIntOperationHint hint);
808   const Operator* SpeculativeBigIntNegate(BigIntOperationHint hint);
809   const Operator* BigIntAsUintN(int bits);
810 
811   const Operator* ReferenceEqual();
812   const Operator* SameValue();
813   const Operator* SameValueNumbersOnly();
814 
815   const Operator* TypeOf();
816 
817   // Adds the given delta to the current feedback vector's interrupt budget,
818   // and calls the runtime profiler in case the budget is exhausted.  A note on
819   // the delta parameter: the interrupt budget mechanism originates in the
820   // interpreter and thus still refers to 'bytecodes' even though we are
821   // generating native code. The interrupt budget essentially corresponds to
822   // the number of bytecodes we can execute before calling the profiler. The
823   // delta parameter represents the executed bytecodes since the last update.
824   const Operator* UpdateInterruptBudget(int delta);
825 
826   // Takes the current feedback vector as input 0, and generates a check of the
827   // vector's marker. Depending on the marker's value, we either do nothing,
828   // trigger optimized compilation, or install a finished code object.
829   const Operator* TierUpCheck();
830 
831   const Operator* ToBoolean();
832 
833   const Operator* StringConcat();
834   const Operator* StringEqual();
835   const Operator* StringLessThan();
836   const Operator* StringLessThanOrEqual();
837   const Operator* StringCharCodeAt();
838   const Operator* StringCodePointAt();
839   const Operator* StringFromSingleCharCode();
840   const Operator* StringFromSingleCodePoint();
841   const Operator* StringFromCodePointAt();
842   const Operator* StringIndexOf();
843   const Operator* StringLength();
844   const Operator* StringToLowerCaseIntl();
845   const Operator* StringToUpperCaseIntl();
846   const Operator* StringSubstring();
847 
848   const Operator* FindOrderedHashMapEntry();
849   const Operator* FindOrderedHashMapEntryForInt32Key();
850 
851   const Operator* SpeculativeToNumber(NumberOperationHint hint,
852                                       const FeedbackSource& feedback);
853 
854   const Operator* StringToNumber();
855   const Operator* PlainPrimitiveToNumber();
856   const Operator* PlainPrimitiveToWord32();
857   const Operator* PlainPrimitiveToFloat64();
858 
859   const Operator* ChangeTaggedSignedToInt32();
860   const Operator* ChangeTaggedSignedToInt64();
861   const Operator* ChangeTaggedToInt32();
862   const Operator* ChangeTaggedToInt64();
863   const Operator* ChangeTaggedToUint32();
864   const Operator* ChangeTaggedToFloat64();
865   const Operator* ChangeTaggedToTaggedSigned();
866   const Operator* ChangeInt31ToTaggedSigned();
867   const Operator* ChangeInt32ToTagged();
868   const Operator* ChangeInt64ToTagged();
869   const Operator* ChangeUint32ToTagged();
870   const Operator* ChangeUint64ToTagged();
871   const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode);
872   const Operator* ChangeFloat64ToTaggedPointer();
873   const Operator* ChangeTaggedToBit();
874   const Operator* ChangeBitToTagged();
875   const Operator* TruncateBigIntToUint64();
876   const Operator* ChangeUint64ToBigInt();
877   const Operator* TruncateTaggedToWord32();
878   const Operator* TruncateTaggedToFloat64();
879   const Operator* TruncateTaggedToBit();
880   const Operator* TruncateTaggedPointerToBit();
881 
882   const Operator* PoisonIndex();
883   const Operator* CompareMaps(ZoneHandleSet<Map>);
884   const Operator* MapGuard(ZoneHandleSet<Map> maps);
885 
886   const Operator* CheckBounds(const FeedbackSource& feedback,
887                               CheckBoundsFlags flags = {});
888   const Operator* CheckedUint32Bounds(const FeedbackSource& feedback,
889                                       CheckBoundsFlags flags);
890   const Operator* CheckedUint64Bounds(const FeedbackSource& feedback,
891                                       CheckBoundsFlags flags);
892 
893   const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell);
894   const Operator* CheckEqualsInternalizedString();
895   const Operator* CheckEqualsSymbol();
896   const Operator* CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const&);
897   const Operator* CheckHeapObject();
898   const Operator* CheckIf(DeoptimizeReason deoptimize_reason,
899                           const FeedbackSource& feedback = FeedbackSource());
900   const Operator* CheckInternalizedString();
901   const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>,
902                             const FeedbackSource& = FeedbackSource());
903   const Operator* DynamicCheckMaps(CheckMapsFlags flags, Handle<Object> handler,
904                                    ZoneHandleSet<Map> const& maps,
905                                    const FeedbackSource& feedback);
906   const Operator* CheckNotTaggedHole();
907   const Operator* CheckNumber(const FeedbackSource& feedback);
908   const Operator* CheckReceiver();
909   const Operator* CheckReceiverOrNullOrUndefined();
910   const Operator* CheckSmi(const FeedbackSource& feedback);
911   const Operator* CheckString(const FeedbackSource& feedback);
912   const Operator* CheckSymbol();
913 
914   const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode,
915                                         const FeedbackSource& feedback);
916   const Operator* CheckedFloat64ToInt64(CheckForMinusZeroMode,
917                                         const FeedbackSource& feedback);
918   const Operator* CheckedInt32Add();
919   const Operator* CheckedInt32Div();
920   const Operator* CheckedInt32Mod();
921   const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
922   const Operator* CheckedInt32Sub();
923   const Operator* CheckedInt32ToTaggedSigned(const FeedbackSource& feedback);
924   const Operator* CheckedInt64ToInt32(const FeedbackSource& feedback);
925   const Operator* CheckedInt64ToTaggedSigned(const FeedbackSource& feedback);
926   const Operator* CheckedTaggedSignedToInt32(const FeedbackSource& feedback);
927   const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode,
928                                          const FeedbackSource& feedback);
929   const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode,
930                                        const FeedbackSource& feedback);
931   const Operator* CheckedTaggedToArrayIndex(const FeedbackSource& feedback);
932   const Operator* CheckedTaggedToInt64(CheckForMinusZeroMode,
933                                        const FeedbackSource& feedback);
934   const Operator* CheckedTaggedToTaggedPointer(const FeedbackSource& feedback);
935   const Operator* CheckedTaggedToTaggedSigned(const FeedbackSource& feedback);
936   const Operator* CheckBigInt(const FeedbackSource& feedback);
937   const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode,
938                                                 const FeedbackSource& feedback);
939   const Operator* CheckedUint32Div();
940   const Operator* CheckedUint32Mod();
941   const Operator* CheckedUint32ToInt32(const FeedbackSource& feedback);
942   const Operator* CheckedUint32ToTaggedSigned(const FeedbackSource& feedback);
943   const Operator* CheckedUint64ToInt32(const FeedbackSource& feedback);
944   const Operator* CheckedUint64ToTaggedSigned(const FeedbackSource& feedback);
945 
946   const Operator* ConvertReceiver(ConvertReceiverMode);
947 
948   const Operator* ConvertTaggedHoleToUndefined();
949 
950   const Operator* ObjectIsArrayBufferView();
951   const Operator* ObjectIsBigInt();
952   const Operator* ObjectIsCallable();
953   const Operator* ObjectIsConstructor();
954   const Operator* ObjectIsDetectableCallable();
955   const Operator* ObjectIsMinusZero();
956   const Operator* NumberIsMinusZero();
957   const Operator* ObjectIsNaN();
958   const Operator* NumberIsNaN();
959   const Operator* ObjectIsNonCallable();
960   const Operator* ObjectIsNumber();
961   const Operator* ObjectIsReceiver();
962   const Operator* ObjectIsSmi();
963   const Operator* ObjectIsString();
964   const Operator* ObjectIsSymbol();
965   const Operator* ObjectIsUndetectable();
966 
967   const Operator* NumberIsFloat64Hole();
968   const Operator* NumberIsFinite();
969   const Operator* ObjectIsFiniteNumber();
970   const Operator* NumberIsInteger();
971   const Operator* ObjectIsSafeInteger();
972   const Operator* NumberIsSafeInteger();
973   const Operator* ObjectIsInteger();
974 
975   const Operator* ArgumentsFrame();
976   const Operator* ArgumentsLength(int formal_parameter_count);
977   const Operator* RestLength(int formal_parameter_count);
978 
979   const Operator* NewDoubleElements(AllocationType);
980   const Operator* NewSmiOrObjectElements(AllocationType);
981 
982   // new-arguments-elements frame, arguments count
983   const Operator* NewArgumentsElements(CreateArgumentsType type,
984                                        int formal_parameter_count);
985 
986   // new-cons-string length, first, second
987   const Operator* NewConsString();
988 
989   // ensure-writable-fast-elements object, elements
990   const Operator* EnsureWritableFastElements();
991 
992   // maybe-grow-fast-elements object, elements, index, length
993   const Operator* MaybeGrowFastElements(GrowFastElementsMode mode,
994                                         const FeedbackSource& feedback);
995 
996   // transition-elements-kind object, from-map, to-map
997   const Operator* TransitionElementsKind(ElementsTransition transition);
998 
999   const Operator* Allocate(Type type,
1000                            AllocationType allocation = AllocationType::kYoung);
1001   const Operator* AllocateRaw(
1002       Type type, AllocationType allocation = AllocationType::kYoung,
1003       AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse);
1004 
1005   const Operator* LoadMessage();
1006   const Operator* StoreMessage();
1007 
1008   const Operator* LoadFieldByIndex();
1009   const Operator* LoadField(FieldAccess const&);
1010   const Operator* StoreField(FieldAccess const&);
1011 
1012   // load-element [base + index]
1013   const Operator* LoadElement(ElementAccess const&);
1014 
1015   // load-stack-argument [base + index]
1016   const Operator* LoadStackArgument();
1017 
1018   // store-element [base + index], value
1019   const Operator* StoreElement(ElementAccess const&);
1020 
1021   // store-element [base + index], value, only with fast arrays.
1022   const Operator* TransitionAndStoreElement(Handle<Map> double_map,
1023                                             Handle<Map> fast_map);
1024   // store-element [base + index], smi value, only with fast arrays.
1025   const Operator* StoreSignedSmallElement();
1026 
1027   // store-element [base + index], double value, only with fast arrays.
1028   const Operator* TransitionAndStoreNumberElement(Handle<Map> double_map);
1029 
1030   // store-element [base + index], object value, only with fast arrays.
1031   const Operator* TransitionAndStoreNonNumberElement(Handle<Map> fast_map,
1032                                                      Type value_type);
1033 
1034   // load-from-object [base + offset]
1035   const Operator* LoadFromObject(ObjectAccess const&);
1036 
1037   // store-to-object [base + offset], value
1038   const Operator* StoreToObject(ObjectAccess const&);
1039 
1040   // load-typed-element buffer, [base + external + index]
1041   const Operator* LoadTypedElement(ExternalArrayType const&);
1042 
1043   // load-data-view-element object, [base + index]
1044   const Operator* LoadDataViewElement(ExternalArrayType const&);
1045 
1046   // store-typed-element buffer, [base + external + index], value
1047   const Operator* StoreTypedElement(ExternalArrayType const&);
1048 
1049   // store-data-view-element object, [base + index], value
1050   const Operator* StoreDataViewElement(ExternalArrayType const&);
1051 
1052   // Abort (for terminating execution on internal error).
1053   const Operator* RuntimeAbort(AbortReason reason);
1054 
1055   // Abort if the value input does not inhabit the given type
1056   const Operator* AssertType(Type type);
1057 
1058   const Operator* DateNow();
1059 
1060   // Represents the inputs necessary to construct a fast and a slow API call.
1061   const Operator* FastApiCall(const CFunctionInfo* signature,
1062                               FeedbackSource const& feedback,
1063                               CallDescriptor* descriptor);
1064 
1065  private:
1066   Zone* zone() const { return zone_; }
1067 
1068   const SimplifiedOperatorGlobalCache& cache_;
1069   Zone* const zone_;
1070 };
1071 
1072 // Node wrappers.
1073 
1074 // TODO(jgruber): Consider merging with JSNodeWrapperBase.
1075 class SimplifiedNodeWrapperBase : public NodeWrapper {
1076  public:
SimplifiedNodeWrapperBase(Node * node)1077   explicit constexpr SimplifiedNodeWrapperBase(Node* node)
1078       : NodeWrapper(node) {}
1079 
1080   // Valid iff this node has a context input.
context()1081   TNode<Object> context() const {
1082     // Could be a Context or NoContextConstant.
1083     return TNode<Object>::UncheckedCast(
1084         NodeProperties::GetContextInput(node()));
1085   }
1086 
1087   // Valid iff this node has exactly one effect input.
effect()1088   Effect effect() const {
1089     DCHECK_EQ(node()->op()->EffectInputCount(), 1);
1090     return Effect{NodeProperties::GetEffectInput(node())};
1091   }
1092 
1093   // Valid iff this node has exactly one control input.
control()1094   Control control() const {
1095     DCHECK_EQ(node()->op()->ControlInputCount(), 1);
1096     return Control{NodeProperties::GetControlInput(node())};
1097   }
1098 
1099   // Valid iff this node has a frame state input.
frame_state()1100   FrameState frame_state() const {
1101     return FrameState{NodeProperties::GetFrameStateInput(node())};
1102   }
1103 };
1104 
1105 #define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
1106   static constexpr int Name##Index() { return TheIndex; }  \
1107   TNode<Type> name() const {                               \
1108     return TNode<Type>::UncheckedCast(                     \
1109         NodeProperties::GetValueInput(node(), TheIndex));  \
1110   }
1111 
1112 class FastApiCallNode final : public SimplifiedNodeWrapperBase {
1113  public:
FastApiCallNode(Node * node)1114   explicit constexpr FastApiCallNode(Node* node)
1115       : SimplifiedNodeWrapperBase(node) {
1116     CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kFastApiCall);
1117   }
1118 
Parameters()1119   const FastApiCallParameters& Parameters() const {
1120     return FastApiCallParametersOf(node()->op());
1121   }
1122 
1123 #define INPUTS(V)              \
1124   V(Target, target, 0, Object) \
1125   V(Receiver, receiver, 1, Object)
1126   INPUTS(DEFINE_INPUT_ACCESSORS)
1127 #undef INPUTS
1128 
1129   // Besides actual arguments, FastApiCall nodes also take:
1130   static constexpr int kFastTargetInputCount = 1;
1131   static constexpr int kSlowTargetInputCount = 1;
1132   static constexpr int kFastReceiverInputCount = 1;
1133   static constexpr int kSlowReceiverInputCount = 1;
1134   static constexpr int kExtraInputCount =
1135       kFastTargetInputCount + kFastReceiverInputCount;
1136 
1137   static constexpr int kHasErrorInputCount = 1;
1138   static constexpr int kArityInputCount = 1;
1139   static constexpr int kNewTargetInputCount = 1;
1140   static constexpr int kHolderInputCount = 1;
1141   static constexpr int kContextAndFrameStateInputCount = 2;
1142   static constexpr int kEffectAndControlInputCount = 2;
1143   static constexpr int kFastCallExtraInputCount =
1144       kFastTargetInputCount + kHasErrorInputCount + kEffectAndControlInputCount;
1145   static constexpr int kSlowCallExtraInputCount =
1146       kSlowTargetInputCount + kArityInputCount + kNewTargetInputCount +
1147       kSlowReceiverInputCount + kHolderInputCount +
1148       kContextAndFrameStateInputCount + kEffectAndControlInputCount;
1149 
1150   // This is the arity fed into FastApiCallArguments.
ArityForArgc(int c_arg_count,int js_arg_count)1151   static constexpr int ArityForArgc(int c_arg_count, int js_arg_count) {
1152     return c_arg_count + kFastTargetInputCount + js_arg_count +
1153            kEffectAndControlInputCount;
1154   }
1155 
1156   int FastCallArgumentCount() const;
1157   int SlowCallArgumentCount() const;
1158 
FirstFastCallArgumentIndex()1159   constexpr int FirstFastCallArgumentIndex() const {
1160     return ReceiverIndex() + 1;
1161   }
FastCallArgumentIndex(int i)1162   constexpr int FastCallArgumentIndex(int i) const {
1163     return FirstFastCallArgumentIndex() + i;
1164   }
FastCallArgument(int i)1165   TNode<Object> FastCallArgument(int i) const {
1166     DCHECK_LT(i, FastCallArgumentCount());
1167     return TNode<Object>::UncheckedCast(
1168         NodeProperties::GetValueInput(node(), FastCallArgumentIndex(i)));
1169   }
1170 
FirstSlowCallArgumentIndex()1171   int FirstSlowCallArgumentIndex() const {
1172     return FastCallArgumentCount() + FastApiCallNode::kFastTargetInputCount;
1173   }
SlowCallArgumentIndex(int i)1174   int SlowCallArgumentIndex(int i) const {
1175     return FirstSlowCallArgumentIndex() + i;
1176   }
SlowCallArgument(int i)1177   TNode<Object> SlowCallArgument(int i) const {
1178     DCHECK_LT(i, SlowCallArgumentCount());
1179     return TNode<Object>::UncheckedCast(
1180         NodeProperties::GetValueInput(node(), SlowCallArgumentIndex(i)));
1181   }
1182 };
1183 
1184 class TierUpCheckNode final : public SimplifiedNodeWrapperBase {
1185  public:
TierUpCheckNode(Node * node)1186   explicit constexpr TierUpCheckNode(Node* node)
1187       : SimplifiedNodeWrapperBase(node) {
1188     CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kTierUpCheck);
1189   }
1190 
1191 #define INPUTS(V)                                       \
1192   V(FeedbackVector, feedback_vector, 0, FeedbackVector) \
1193   V(Target, target, 1, JSReceiver)                      \
1194   V(NewTarget, new_target, 2, Object)                   \
1195   V(InputCount, input_count, 3, UntaggedT)              \
1196   V(Context, context, 4, Context)
1197   INPUTS(DEFINE_INPUT_ACCESSORS)
1198 #undef INPUTS
1199 };
1200 
1201 class UpdateInterruptBudgetNode final : public SimplifiedNodeWrapperBase {
1202  public:
UpdateInterruptBudgetNode(Node * node)1203   explicit constexpr UpdateInterruptBudgetNode(Node* node)
1204       : SimplifiedNodeWrapperBase(node) {
1205     CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kUpdateInterruptBudget);
1206   }
1207 
delta()1208   int delta() const { return OpParameter<int>(node()->op()); }
1209 
1210 #define INPUTS(V) V(FeedbackCell, feedback_cell, 0, FeedbackCell)
1211   INPUTS(DEFINE_INPUT_ACCESSORS)
1212 #undef INPUTS
1213 };
1214 
1215 #undef DEFINE_INPUT_ACCESSORS
1216 
1217 }  // namespace compiler
1218 }  // namespace internal
1219 }  // namespace v8
1220 
1221 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
1222