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