• 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/common-operator.h"
15 #include "src/compiler/feedback-source.h"
16 #include "src/compiler/node-properties.h"
17 #include "src/compiler/operator.h"
18 #include "src/compiler/types.h"
19 #include "src/compiler/write-barrier-kind.h"
20 #include "src/deoptimizer/deoptimize-reason.h"
21 #include "src/handles/handles.h"
22 #include "src/handles/maybe-handles.h"
23 #include "src/objects/objects.h"
24 #include "src/objects/type-hints.h"
25 #include "src/zone/zone-handle-set.h"
26 
27 namespace v8 {
28 class CFunctionInfo;
29 
30 namespace internal {
31 
32 // Forward declarations.
33 enum class AbortReason : uint8_t;
34 class Zone;
35 
36 namespace compiler {
37 
38 // Forward declarations.
39 class Operator;
40 struct SimplifiedOperatorGlobalCache;
41 class CallDescriptor;
42 
43 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
44 
45 size_t hash_value(BaseTaggedness);
46 
47 std::ostream& operator<<(std::ostream&, BaseTaggedness);
48 
49 struct ConstFieldInfo {
50   // the map that introduced the const field, if any. An access is considered
51   // mutable iff the handle is null.
52   MaybeHandle<Map> owner_map;
53 
ConstFieldInfoConstFieldInfo54   ConstFieldInfo() : owner_map(MaybeHandle<Map>()) {}
ConstFieldInfoConstFieldInfo55   explicit ConstFieldInfo(Handle<Map> owner_map) : owner_map(owner_map) {}
56 
IsConstConstFieldInfo57   bool IsConst() const { return !owner_map.is_null(); }
58 
59   // No const field owner, i.e., a mutable field
NoneConstFieldInfo60   static ConstFieldInfo None() { return ConstFieldInfo(); }
61 };
62 
63 V8_EXPORT_PRIVATE bool operator==(ConstFieldInfo const&, ConstFieldInfo const&);
64 
65 size_t hash_value(ConstFieldInfo const&);
66 
67 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
68                                            ConstFieldInfo const&);
69 
70 // An access descriptor for loads/stores of fixed structures like field
71 // accesses of heap objects. Accesses from either tagged or untagged base
72 // pointers are supported; untagging is done automatically during lowering.
73 struct FieldAccess {
74   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
75   int offset;                     // offset of the field, without tag.
76   MaybeHandle<Name> name;         // debugging only.
77   MaybeHandle<Map> map;           // map of the field value (if known).
78   Type type;                      // type of the field.
79   MachineType machine_type;       // machine type of the field.
80   WriteBarrierKind write_barrier_kind;  // write barrier hint.
81   ConstFieldInfo const_field_info;      // the constness of this access, and the
82                                     // field owner map, if the access is const
83   bool is_store_in_literal;  // originates from a kStoreInLiteral access
84 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
85   ExternalPointerTag external_pointer_tag = kExternalPointerNullTag;
86 #endif
87   bool maybe_initializing_or_transitioning_store;  // store is potentially
88                                                    // initializing a newly
89                                                    // allocated object or part
90                                                    // of a map transition.
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         const_field_info(ConstFieldInfo::None()),
99         is_store_in_literal(false),
100         maybe_initializing_or_transitioning_store(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               ConstFieldInfo const_field_info = ConstFieldInfo::None(),
106               bool is_store_in_literal = false,
107 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
108               ExternalPointerTag external_pointer_tag = kExternalPointerNullTag,
109 #endif
110               bool maybe_initializing_or_transitioning_store = false)
base_is_taggedFieldAccess111       : base_is_tagged(base_is_tagged),
112         offset(offset),
113         name(name),
114         map(map),
115         type(type),
116         machine_type(machine_type),
117         write_barrier_kind(write_barrier_kind),
118         const_field_info(const_field_info),
119         is_store_in_literal(is_store_in_literal),
120 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
121         external_pointer_tag(external_pointer_tag),
122 #endif
123         maybe_initializing_or_transitioning_store(
124             maybe_initializing_or_transitioning_store) {
125     DCHECK_GE(offset, 0);
126     DCHECK_IMPLIES(
127         machine_type.IsMapWord(),
128         offset == HeapObject::kMapOffset && base_is_tagged != kUntaggedBase);
129     DCHECK_IMPLIES(machine_type.IsMapWord(),
130                    (write_barrier_kind == kMapWriteBarrier ||
131                     write_barrier_kind == kNoWriteBarrier ||
132                     write_barrier_kind == kAssertNoWriteBarrier));
133   }
134 
tagFieldAccess135   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
136 };
137 
138 V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
139 
140 size_t hash_value(FieldAccess const&);
141 
142 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
143 
144 V8_EXPORT_PRIVATE FieldAccess const& FieldAccessOf(const Operator* op)
145     V8_WARN_UNUSED_RESULT;
146 
147 template <>
148 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
149                                             PrintVerbosity verbose) const;
150 
151 // An access descriptor for loads/stores of indexed structures like characters
152 // in strings or off-heap backing stores. Accesses from either tagged or
153 // untagged base pointers are supported; untagging is done automatically during
154 // lowering.
155 struct ElementAccess {
156   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
157   int header_size;                // size of the header, without tag.
158   Type type;                      // type of the element.
159   MachineType machine_type;       // machine type of the element.
160   WriteBarrierKind write_barrier_kind;  // write barrier hint.
161 
ElementAccessElementAccess162   ElementAccess()
163       : base_is_tagged(kTaggedBase),
164         header_size(0),
165         type(Type::None()),
166         machine_type(MachineType::None()),
167         write_barrier_kind(kFullWriteBarrier) {}
168 
ElementAccessElementAccess169   ElementAccess(BaseTaggedness base_is_tagged, int header_size, Type type,
170                 MachineType machine_type, WriteBarrierKind write_barrier_kind)
171       : base_is_tagged(base_is_tagged),
172         header_size(header_size),
173         type(type),
174         machine_type(machine_type),
175         write_barrier_kind(write_barrier_kind) {}
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 ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const*) V8_WARN_UNUSED_RESULT;
443 
444 // Parameters for CompareMaps operator.
445 ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const*)
446     V8_WARN_UNUSED_RESULT;
447 
448 // A descriptor for growing elements backing stores.
449 enum class GrowFastElementsMode : uint8_t {
450   kDoubleElements,
451   kSmiOrObjectElements
452 };
453 
hash_value(GrowFastElementsMode mode)454 inline size_t hash_value(GrowFastElementsMode mode) {
455   return static_cast<uint8_t>(mode);
456 }
457 
458 std::ostream& operator<<(std::ostream&, GrowFastElementsMode);
459 
460 class GrowFastElementsParameters {
461  public:
GrowFastElementsParameters(GrowFastElementsMode mode,const FeedbackSource & feedback)462   GrowFastElementsParameters(GrowFastElementsMode mode,
463                              const FeedbackSource& feedback)
464       : mode_(mode), feedback_(feedback) {}
465 
mode()466   GrowFastElementsMode mode() const { return mode_; }
feedback()467   const FeedbackSource& feedback() const { return feedback_; }
468 
469  private:
470   GrowFastElementsMode mode_;
471   FeedbackSource feedback_;
472 };
473 
474 bool operator==(const GrowFastElementsParameters&,
475                 const GrowFastElementsParameters&);
476 
477 inline size_t hash_value(const GrowFastElementsParameters&);
478 
479 std::ostream& operator<<(std::ostream&, const GrowFastElementsParameters&);
480 
481 const GrowFastElementsParameters& GrowFastElementsParametersOf(const Operator*)
482     V8_WARN_UNUSED_RESULT;
483 
484 // A descriptor for elements kind transitions.
485 class ElementsTransition final {
486  public:
487   enum Mode : uint8_t {
488     kFastTransition,  // simple transition, just updating the map.
489     kSlowTransition   // full transition, round-trip to the runtime.
490   };
491 
ElementsTransition(Mode mode,Handle<Map> source,Handle<Map> target)492   ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
493       : mode_(mode), source_(source), target_(target) {}
494 
mode()495   Mode mode() const { return mode_; }
source()496   Handle<Map> source() const { return source_; }
target()497   Handle<Map> target() const { return target_; }
498 
499  private:
500   Mode const mode_;
501   Handle<Map> const source_;
502   Handle<Map> const target_;
503 };
504 
505 bool operator==(ElementsTransition const&, ElementsTransition const&);
506 
507 size_t hash_value(ElementsTransition);
508 
509 std::ostream& operator<<(std::ostream&, ElementsTransition);
510 
511 ElementsTransition const& ElementsTransitionOf(const Operator* op)
512     V8_WARN_UNUSED_RESULT;
513 
514 // Parameters for TransitionAndStoreElement, or
515 // TransitionAndStoreNonNumberElement, or
516 // TransitionAndStoreNumberElement.
517 Handle<Map> DoubleMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
518 Handle<Map> FastMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
519 
520 // Parameters for TransitionAndStoreNonNumberElement.
521 Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
522 
523 // A hint for speculative number operations.
524 enum class NumberOperationHint : uint8_t {
525   kSignedSmall,        // Inputs were Smi, output was in Smi.
526   kSignedSmallInputs,  // Inputs were Smi, output was Number.
527   kNumber,             // Inputs were Number, output was Number.
528   kNumberOrBoolean,    // Inputs were Number or Boolean, output was Number.
529   kNumberOrOddball,    // Inputs were Number or Oddball, output was Number.
530 };
531 
532 enum class BigIntOperationHint : uint8_t {
533   kBigInt,
534 };
535 
536 size_t hash_value(NumberOperationHint);
537 size_t hash_value(BigIntOperationHint);
538 
539 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
540 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint);
541 V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op)
542     V8_WARN_UNUSED_RESULT;
543 
544 class NumberOperationParameters {
545  public:
NumberOperationParameters(NumberOperationHint hint,const FeedbackSource & feedback)546   NumberOperationParameters(NumberOperationHint hint,
547                             const FeedbackSource& feedback)
548       : hint_(hint), feedback_(feedback) {}
549 
hint()550   NumberOperationHint hint() const { return hint_; }
feedback()551   const FeedbackSource& feedback() const { return feedback_; }
552 
553  private:
554   NumberOperationHint hint_;
555   FeedbackSource feedback_;
556 };
557 
558 size_t hash_value(NumberOperationParameters const&);
559 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
560                                            const NumberOperationParameters&);
561 bool operator==(NumberOperationParameters const&,
562                 NumberOperationParameters const&);
563 const NumberOperationParameters& NumberOperationParametersOf(const Operator* op)
564     V8_WARN_UNUSED_RESULT;
565 
566 class SpeculativeBigIntAsNParameters {
567  public:
SpeculativeBigIntAsNParameters(int bits,const FeedbackSource & feedback)568   SpeculativeBigIntAsNParameters(int bits, const FeedbackSource& feedback)
569       : bits_(bits), feedback_(feedback) {
570     DCHECK_GE(bits_, 0);
571     DCHECK_LE(bits_, 64);
572   }
573 
bits()574   int bits() const { return bits_; }
feedback()575   const FeedbackSource& feedback() const { return feedback_; }
576 
577  private:
578   int bits_;
579   FeedbackSource feedback_;
580 };
581 
582 size_t hash_value(SpeculativeBigIntAsNParameters const&);
583 V8_EXPORT_PRIVATE std::ostream& operator<<(
584     std::ostream&, const SpeculativeBigIntAsNParameters&);
585 bool operator==(SpeculativeBigIntAsNParameters const&,
586                 SpeculativeBigIntAsNParameters const&);
587 const SpeculativeBigIntAsNParameters& SpeculativeBigIntAsNParametersOf(
588     const Operator* op) V8_WARN_UNUSED_RESULT;
589 
590 int FormalParameterCountOf(const Operator* op) V8_WARN_UNUSED_RESULT;
591 
592 class AllocateParameters {
593  public:
594   AllocateParameters(
595       Type type, AllocationType allocation_type,
596       AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse)
type_(type)597       : type_(type),
598         allocation_type_(allocation_type),
599         allow_large_objects_(allow_large_objects) {}
600 
type()601   Type type() const { return type_; }
allocation_type()602   AllocationType allocation_type() const { return allocation_type_; }
allow_large_objects()603   AllowLargeObjects allow_large_objects() const { return allow_large_objects_; }
604 
605  private:
606   Type type_;
607   AllocationType allocation_type_;
608   AllowLargeObjects allow_large_objects_;
609 };
610 
611 bool IsCheckedWithFeedback(const Operator* op);
612 
613 size_t hash_value(AllocateParameters);
614 
615 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters);
616 
617 bool operator==(AllocateParameters const&, AllocateParameters const&);
618 
619 const AllocateParameters& AllocateParametersOf(const Operator* op)
620     V8_WARN_UNUSED_RESULT;
621 
622 AllocationType AllocationTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
623 
624 Type AllocateTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
625 
626 UnicodeEncoding UnicodeEncodingOf(const Operator*) V8_WARN_UNUSED_RESULT;
627 
628 AbortReason AbortReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
629 
630 DeoptimizeReason DeoptimizeReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
631 
632 class NewArgumentsElementsParameters {
633  public:
NewArgumentsElementsParameters(CreateArgumentsType type,int formal_parameter_count)634   NewArgumentsElementsParameters(CreateArgumentsType type,
635                                  int formal_parameter_count)
636       : type_(type), formal_parameter_count_(formal_parameter_count) {}
637 
arguments_type()638   CreateArgumentsType arguments_type() const { return type_; }
formal_parameter_count()639   int formal_parameter_count() const { return formal_parameter_count_; }
640 
641  private:
642   CreateArgumentsType type_;
643   int formal_parameter_count_;
644 };
645 
646 bool operator==(const NewArgumentsElementsParameters&,
647                 const NewArgumentsElementsParameters&);
648 
649 inline size_t hash_value(const NewArgumentsElementsParameters&);
650 
651 std::ostream& operator<<(std::ostream&, const NewArgumentsElementsParameters&);
652 
653 const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf(
654     const Operator*) V8_WARN_UNUSED_RESULT;
655 
656 struct FastApiCallFunction {
657   Address address;
658   const CFunctionInfo* signature;
659 
660   bool operator==(const FastApiCallFunction& rhs) const {
661     return address == rhs.address && signature == rhs.signature;
662   }
663 };
664 typedef ZoneVector<FastApiCallFunction> FastApiCallFunctionVector;
665 
666 class FastApiCallParameters {
667  public:
FastApiCallParameters(const FastApiCallFunctionVector & c_functions,FeedbackSource const & feedback,CallDescriptor * descriptor)668   explicit FastApiCallParameters(const FastApiCallFunctionVector& c_functions,
669                                  FeedbackSource const& feedback,
670                                  CallDescriptor* descriptor)
671       : c_functions_(c_functions),
672         feedback_(feedback),
673         descriptor_(descriptor) {}
674 
c_functions()675   const FastApiCallFunctionVector& c_functions() const { return c_functions_; }
feedback()676   FeedbackSource const& feedback() const { return feedback_; }
descriptor()677   CallDescriptor* descriptor() const { return descriptor_; }
678 
679  private:
680   // A single FastApiCall node can represent multiple overloaded functions.
681   const FastApiCallFunctionVector c_functions_;
682 
683   const FeedbackSource feedback_;
684   CallDescriptor* descriptor_;
685 };
686 
687 FastApiCallParameters const& FastApiCallParametersOf(const Operator* op)
688     V8_WARN_UNUSED_RESULT;
689 
690 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
691                                            FastApiCallParameters const&);
692 
693 size_t hash_value(FastApiCallParameters const&);
694 
695 bool operator==(FastApiCallParameters const&, FastApiCallParameters const&);
696 
697 // Interface for building simplified operators, which represent the
698 // medium-level operations of V8, including adding numbers, allocating objects,
699 // indexing into objects and arrays, etc.
700 // All operators are typed but many are representation independent.
701 
702 // Number values from JS can be in one of these representations:
703 //   - Tagged: word-sized integer that is either
704 //     - a signed small integer (31 or 32 bits plus a tag)
705 //     - a tagged pointer to a HeapNumber object that has a float64 field
706 //   - Int32: an untagged signed 32-bit integer
707 //   - Uint32: an untagged unsigned 32-bit integer
708 //   - Float64: an untagged float64
709 
710 // Additional representations for intermediate code or non-JS code:
711 //   - Int64: an untagged signed 64-bit integer
712 //   - Uint64: an untagged unsigned 64-bit integer
713 //   - Float32: an untagged float32
714 
715 // Boolean values can be:
716 //   - Bool: a tagged pointer to either the canonical JS #false or
717 //           the canonical JS #true object
718 //   - Bit: an untagged integer 0 or 1, but word-sized
719 class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)720     : public NON_EXPORTED_BASE(ZoneObject) {
721  public:
722   explicit SimplifiedOperatorBuilder(Zone* zone);
723   SimplifiedOperatorBuilder(const SimplifiedOperatorBuilder&) = delete;
724   SimplifiedOperatorBuilder& operator=(const SimplifiedOperatorBuilder&) =
725       delete;
726 
727   const Operator* BooleanNot();
728 
729   const Operator* NumberEqual();
730   const Operator* NumberSameValue();
731   const Operator* NumberLessThan();
732   const Operator* NumberLessThanOrEqual();
733   const Operator* NumberAdd();
734   const Operator* NumberSubtract();
735   const Operator* NumberMultiply();
736   const Operator* NumberDivide();
737   const Operator* NumberModulus();
738   const Operator* NumberBitwiseOr();
739   const Operator* NumberBitwiseXor();
740   const Operator* NumberBitwiseAnd();
741   const Operator* NumberShiftLeft();
742   const Operator* NumberShiftRight();
743   const Operator* NumberShiftRightLogical();
744   const Operator* NumberImul();
745   const Operator* NumberAbs();
746   const Operator* NumberClz32();
747   const Operator* NumberCeil();
748   const Operator* NumberFloor();
749   const Operator* NumberFround();
750   const Operator* NumberAcos();
751   const Operator* NumberAcosh();
752   const Operator* NumberAsin();
753   const Operator* NumberAsinh();
754   const Operator* NumberAtan();
755   const Operator* NumberAtan2();
756   const Operator* NumberAtanh();
757   const Operator* NumberCbrt();
758   const Operator* NumberCos();
759   const Operator* NumberCosh();
760   const Operator* NumberExp();
761   const Operator* NumberExpm1();
762   const Operator* NumberLog();
763   const Operator* NumberLog1p();
764   const Operator* NumberLog10();
765   const Operator* NumberLog2();
766   const Operator* NumberMax();
767   const Operator* NumberMin();
768   const Operator* NumberPow();
769   const Operator* NumberRound();
770   const Operator* NumberSign();
771   const Operator* NumberSin();
772   const Operator* NumberSinh();
773   const Operator* NumberSqrt();
774   const Operator* NumberTan();
775   const Operator* NumberTanh();
776   const Operator* NumberTrunc();
777   const Operator* NumberToBoolean();
778   const Operator* NumberToInt32();
779   const Operator* NumberToString();
780   const Operator* NumberToUint32();
781   const Operator* NumberToUint8Clamped();
782 
783   const Operator* NumberSilenceNaN();
784 
785   const Operator* BigIntAdd();
786   const Operator* BigIntSubtract();
787   const Operator* BigIntNegate();
788 
789   const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint);
790   const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint);
791 
792   const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
793   const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
794   const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
795   const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
796   const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
797   const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
798   const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
799   const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
800   const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
801   const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
802   const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
803   const Operator* SpeculativeNumberPow(NumberOperationHint hint);
804 
805   const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
806   const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
807   const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
808 
809   const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint);
810   const Operator* SpeculativeBigIntSubtract(BigIntOperationHint hint);
811   const Operator* SpeculativeBigIntNegate(BigIntOperationHint hint);
812   const Operator* SpeculativeBigIntAsIntN(int bits,
813                                           const FeedbackSource& feedback);
814   const Operator* SpeculativeBigIntAsUintN(int bits,
815                                            const FeedbackSource& feedback);
816 
817   const Operator* ReferenceEqual();
818   const Operator* SameValue();
819   const Operator* SameValueNumbersOnly();
820 
821   const Operator* TypeOf();
822 
823   const Operator* ToBoolean();
824 
825   const Operator* StringConcat();
826   const Operator* StringEqual();
827   const Operator* StringLessThan();
828   const Operator* StringLessThanOrEqual();
829   const Operator* StringCharCodeAt();
830   const Operator* StringCodePointAt();
831   const Operator* StringFromSingleCharCode();
832   const Operator* StringFromSingleCodePoint();
833   const Operator* StringFromCodePointAt();
834   const Operator* StringIndexOf();
835   const Operator* StringLength();
836   const Operator* StringToLowerCaseIntl();
837   const Operator* StringToUpperCaseIntl();
838   const Operator* StringSubstring();
839 
840   const Operator* FindOrderedHashMapEntry();
841   const Operator* FindOrderedHashMapEntryForInt32Key();
842 
843   const Operator* SpeculativeToNumber(NumberOperationHint hint,
844                                       const FeedbackSource& feedback);
845 
846   const Operator* StringToNumber();
847   const Operator* PlainPrimitiveToNumber();
848   const Operator* PlainPrimitiveToWord32();
849   const Operator* PlainPrimitiveToFloat64();
850 
851   const Operator* ChangeTaggedSignedToInt32();
852   const Operator* ChangeTaggedSignedToInt64();
853   const Operator* ChangeTaggedToInt32();
854   const Operator* ChangeTaggedToInt64();
855   const Operator* ChangeTaggedToUint32();
856   const Operator* ChangeTaggedToFloat64();
857   const Operator* ChangeTaggedToTaggedSigned();
858   const Operator* ChangeInt31ToTaggedSigned();
859   const Operator* ChangeInt32ToTagged();
860   const Operator* ChangeInt64ToTagged();
861   const Operator* ChangeUint32ToTagged();
862   const Operator* ChangeUint64ToTagged();
863   const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode);
864   const Operator* ChangeFloat64ToTaggedPointer();
865   const Operator* ChangeTaggedToBit();
866   const Operator* ChangeBitToTagged();
867   const Operator* TruncateBigIntToWord64();
868   const Operator* ChangeInt64ToBigInt();
869   const Operator* ChangeUint64ToBigInt();
870   const Operator* TruncateTaggedToWord32();
871   const Operator* TruncateTaggedToFloat64();
872   const Operator* TruncateTaggedToBit();
873   const Operator* TruncateTaggedPointerToBit();
874 
875   const Operator* CompareMaps(ZoneHandleSet<Map>);
876   const Operator* MapGuard(ZoneHandleSet<Map> maps);
877 
878   const Operator* CheckBounds(const FeedbackSource& feedback,
879                               CheckBoundsFlags flags = {});
880   const Operator* CheckedUint32Bounds(const FeedbackSource& feedback,
881                                       CheckBoundsFlags flags);
882   const Operator* CheckedUint64Bounds(const FeedbackSource& feedback,
883                                       CheckBoundsFlags flags);
884 
885   const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell);
886   const Operator* CheckEqualsInternalizedString();
887   const Operator* CheckEqualsSymbol();
888   const Operator* CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const&);
889   const Operator* CheckHeapObject();
890   const Operator* CheckIf(DeoptimizeReason deoptimize_reason,
891                           const FeedbackSource& feedback = FeedbackSource());
892   const Operator* CheckInternalizedString();
893   const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>,
894                             const FeedbackSource& = FeedbackSource());
895   const Operator* CheckNotTaggedHole();
896   const Operator* CheckNumber(const FeedbackSource& feedback);
897   const Operator* CheckReceiver();
898   const Operator* CheckReceiverOrNullOrUndefined();
899   const Operator* CheckSmi(const FeedbackSource& feedback);
900   const Operator* CheckString(const FeedbackSource& feedback);
901   const Operator* CheckSymbol();
902 
903   const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode,
904                                         const FeedbackSource& feedback);
905   const Operator* CheckedFloat64ToInt64(CheckForMinusZeroMode,
906                                         const FeedbackSource& feedback);
907   const Operator* CheckedInt32Add();
908   const Operator* CheckedInt32Div();
909   const Operator* CheckedInt32Mod();
910   const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
911   const Operator* CheckedInt32Sub();
912   const Operator* CheckedInt32ToTaggedSigned(const FeedbackSource& feedback);
913   const Operator* CheckedInt64ToInt32(const FeedbackSource& feedback);
914   const Operator* CheckedInt64ToTaggedSigned(const FeedbackSource& feedback);
915   const Operator* CheckedTaggedSignedToInt32(const FeedbackSource& feedback);
916   const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode,
917                                          const FeedbackSource& feedback);
918   const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode,
919                                        const FeedbackSource& feedback);
920   const Operator* CheckedTaggedToArrayIndex(const FeedbackSource& feedback);
921   const Operator* CheckedTaggedToInt64(CheckForMinusZeroMode,
922                                        const FeedbackSource& feedback);
923   const Operator* CheckedTaggedToTaggedPointer(const FeedbackSource& feedback);
924   const Operator* CheckedTaggedToTaggedSigned(const FeedbackSource& feedback);
925   const Operator* CheckBigInt(const FeedbackSource& feedback);
926   const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode,
927                                                 const FeedbackSource& feedback);
928   const Operator* CheckedUint32Div();
929   const Operator* CheckedUint32Mod();
930   const Operator* CheckedUint32ToInt32(const FeedbackSource& feedback);
931   const Operator* CheckedUint32ToTaggedSigned(const FeedbackSource& feedback);
932   const Operator* CheckedUint64ToInt32(const FeedbackSource& feedback);
933   const Operator* CheckedUint64ToTaggedSigned(const FeedbackSource& feedback);
934 
935   const Operator* ConvertReceiver(ConvertReceiverMode);
936 
937   const Operator* ConvertTaggedHoleToUndefined();
938 
939   const Operator* ObjectIsArrayBufferView();
940   const Operator* ObjectIsBigInt();
941   const Operator* ObjectIsCallable();
942   const Operator* ObjectIsConstructor();
943   const Operator* ObjectIsDetectableCallable();
944   const Operator* ObjectIsMinusZero();
945   const Operator* NumberIsMinusZero();
946   const Operator* ObjectIsNaN();
947   const Operator* NumberIsNaN();
948   const Operator* ObjectIsNonCallable();
949   const Operator* ObjectIsNumber();
950   const Operator* ObjectIsReceiver();
951   const Operator* ObjectIsSmi();
952   const Operator* ObjectIsString();
953   const Operator* ObjectIsSymbol();
954   const Operator* ObjectIsUndetectable();
955 
956   const Operator* NumberIsFloat64Hole();
957   const Operator* NumberIsFinite();
958   const Operator* ObjectIsFiniteNumber();
959   const Operator* NumberIsInteger();
960   const Operator* ObjectIsSafeInteger();
961   const Operator* NumberIsSafeInteger();
962   const Operator* ObjectIsInteger();
963 
964   const Operator* ArgumentsLength();
965   const Operator* RestLength(int formal_parameter_count);
966 
967   const Operator* NewDoubleElements(AllocationType);
968   const Operator* NewSmiOrObjectElements(AllocationType);
969 
970   // new-arguments-elements arguments-length
971   const Operator* NewArgumentsElements(CreateArgumentsType type,
972                                        int formal_parameter_count);
973 
974   // new-cons-string length, first, second
975   const Operator* NewConsString();
976 
977   // ensure-writable-fast-elements object, elements
978   const Operator* EnsureWritableFastElements();
979 
980   // maybe-grow-fast-elements object, elements, index, length
981   const Operator* MaybeGrowFastElements(GrowFastElementsMode mode,
982                                         const FeedbackSource& feedback);
983 
984   // transition-elements-kind object, from-map, to-map
985   const Operator* TransitionElementsKind(ElementsTransition transition);
986 
987   const Operator* Allocate(Type type,
988                            AllocationType allocation = AllocationType::kYoung);
989   const Operator* AllocateRaw(
990       Type type, AllocationType allocation = AllocationType::kYoung,
991       AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse);
992 
993   const Operator* LoadMessage();
994   const Operator* StoreMessage();
995 
996   const Operator* LoadFieldByIndex();
997   const Operator* LoadField(FieldAccess const&);
998   const Operator* StoreField(FieldAccess const&,
999                              bool maybe_initializing_or_transitioning = true);
1000 
1001   // load-element [base + index]
1002   const Operator* LoadElement(ElementAccess const&);
1003 
1004   // load-stack-argument [base + index]
1005   const Operator* LoadStackArgument();
1006 
1007   // store-element [base + index], value
1008   const Operator* StoreElement(ElementAccess const&);
1009 
1010   // store-element [base + index], value, only with fast arrays.
1011   const Operator* TransitionAndStoreElement(Handle<Map> double_map,
1012                                             Handle<Map> fast_map);
1013   // store-element [base + index], smi value, only with fast arrays.
1014   const Operator* StoreSignedSmallElement();
1015 
1016   // store-element [base + index], double value, only with fast arrays.
1017   const Operator* TransitionAndStoreNumberElement(Handle<Map> double_map);
1018 
1019   // store-element [base + index], object value, only with fast arrays.
1020   const Operator* TransitionAndStoreNonNumberElement(Handle<Map> fast_map,
1021                                                      Type value_type);
1022 
1023   // load-from-object [base + offset]
1024   // This operator comes in two flavors: LoadImmutableFromObject guarantees that
1025   // the underlying object field will be initialized at most once for the
1026   // duration of the program. This enables more optimizations in
1027   // CsaLoadElimination.
1028   // Note: LoadImmutableFromObject is unrelated to LoadImmutable and is lowered
1029   // into a regular Load.
1030   const Operator* LoadFromObject(ObjectAccess const&);
1031   const Operator* LoadImmutableFromObject(ObjectAccess const&);
1032 
1033   // store-to-object [base + offset], value
1034   // This operator comes in two flavors: InitializeImmutableInObject guarantees
1035   // that the underlying object field has not and will not be initialized again
1036   // for the duration of the program. This enables more optimizations in
1037   // CsaLoadElimination.
1038   const Operator* StoreToObject(ObjectAccess const&);
1039   const Operator* InitializeImmutableInObject(ObjectAccess const&);
1040 
1041   // load-typed-element buffer, [base + external + index]
1042   const Operator* LoadTypedElement(ExternalArrayType const&);
1043 
1044   // load-data-view-element object, [base + index]
1045   const Operator* LoadDataViewElement(ExternalArrayType const&);
1046 
1047   // store-typed-element buffer, [base + external + index], value
1048   const Operator* StoreTypedElement(ExternalArrayType const&);
1049 
1050   // store-data-view-element object, [base + index], value
1051   const Operator* StoreDataViewElement(ExternalArrayType const&);
1052 
1053   // Abort (for terminating execution on internal error).
1054   const Operator* RuntimeAbort(AbortReason reason);
1055 
1056   // Abort if the value input does not inhabit the given type
1057   const Operator* AssertType(Type type);
1058 
1059   // Abort if the value does not match the node's computed type after
1060   // SimplifiedLowering.
1061   const Operator* VerifyType();
1062 
1063   const Operator* DateNow();
1064 
1065   // Represents the inputs necessary to construct a fast and a slow API call.
1066   const Operator* FastApiCall(
1067       const FastApiCallFunctionVector& c_candidate_functions,
1068       FeedbackSource const& feedback, CallDescriptor* descriptor);
1069 
1070  private:
1071   Zone* zone() const { return zone_; }
1072 
1073   const SimplifiedOperatorGlobalCache& cache_;
1074   Zone* const zone_;
1075 };
1076 
1077 // Node wrappers.
1078 
1079 // TODO(jgruber): Consider merging with JSNodeWrapperBase.
1080 class SimplifiedNodeWrapperBase : public NodeWrapper {
1081  public:
SimplifiedNodeWrapperBase(Node * node)1082   explicit constexpr SimplifiedNodeWrapperBase(Node* node)
1083       : NodeWrapper(node) {}
1084 
1085   // Valid iff this node has a context input.
context()1086   TNode<Object> context() const {
1087     // Could be a Context or NoContextConstant.
1088     return TNode<Object>::UncheckedCast(
1089         NodeProperties::GetContextInput(node()));
1090   }
1091 
1092   // Valid iff this node has exactly one effect input.
effect()1093   Effect effect() const {
1094     DCHECK_EQ(node()->op()->EffectInputCount(), 1);
1095     return Effect{NodeProperties::GetEffectInput(node())};
1096   }
1097 
1098   // Valid iff this node has exactly one control input.
control()1099   Control control() const {
1100     DCHECK_EQ(node()->op()->ControlInputCount(), 1);
1101     return Control{NodeProperties::GetControlInput(node())};
1102   }
1103 
1104   // Valid iff this node has a frame state input.
frame_state()1105   FrameState frame_state() const {
1106     return FrameState{NodeProperties::GetFrameStateInput(node())};
1107   }
1108 };
1109 
1110 #define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
1111   static constexpr int Name##Index() { return TheIndex; }  \
1112   TNode<Type> name() const {                               \
1113     return TNode<Type>::UncheckedCast(                     \
1114         NodeProperties::GetValueInput(node(), TheIndex));  \
1115   }
1116 
1117 class FastApiCallNode final : public SimplifiedNodeWrapperBase {
1118  public:
FastApiCallNode(Node * node)1119   explicit constexpr FastApiCallNode(Node* node)
1120       : SimplifiedNodeWrapperBase(node) {
1121     DCHECK_EQ(IrOpcode::kFastApiCall, node->opcode());
1122   }
1123 
Parameters()1124   const FastApiCallParameters& Parameters() const {
1125     return FastApiCallParametersOf(node()->op());
1126   }
1127 
1128 #define INPUTS(V) V(Receiver, receiver, 0, Object)
1129   INPUTS(DEFINE_INPUT_ACCESSORS)
1130 #undef INPUTS
1131 
1132   // Besides actual arguments, FastApiCall nodes also take:
1133   static constexpr int kSlowTargetInputCount = 1;
1134   static constexpr int kFastReceiverInputCount = 1;
1135   static constexpr int kSlowReceiverInputCount = 1;
1136   static constexpr int kExtraInputCount = kFastReceiverInputCount;
1137 
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   int FastCallExtraInputCount() const;
1144   static constexpr int kSlowCallExtraInputCount =
1145       kSlowTargetInputCount + kArityInputCount + kNewTargetInputCount +
1146       kSlowReceiverInputCount + kHolderInputCount +
1147       kContextAndFrameStateInputCount + kEffectAndControlInputCount;
1148 
1149   static constexpr int kSlowCallDataArgumentIndex = 3;
1150 
1151   // This is the arity fed into FastApiCallArguments.
ArityForArgc(int c_arg_count,int js_arg_count)1152   static constexpr int ArityForArgc(int c_arg_count, int js_arg_count) {
1153     return c_arg_count + js_arg_count + 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 { return FastCallArgumentCount(); }
SlowCallArgumentIndex(int i)1172   int SlowCallArgumentIndex(int i) const {
1173     return FirstSlowCallArgumentIndex() + i;
1174   }
SlowCallArgument(int i)1175   TNode<Object> SlowCallArgument(int i) const {
1176     DCHECK_LT(i, SlowCallArgumentCount());
1177     return TNode<Object>::UncheckedCast(
1178         NodeProperties::GetValueInput(node(), SlowCallArgumentIndex(i)));
1179   }
1180 };
1181 
1182 #undef DEFINE_INPUT_ACCESSORS
1183 
1184 }  // namespace compiler
1185 }  // namespace internal
1186 }  // namespace v8
1187 
1188 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
1189