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