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