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