• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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_JS_OPERATOR_H_
6 #define V8_COMPILER_JS_OPERATOR_H_
7 
8 #include "src/base/compiler-specific.h"
9 #include "src/codegen/tnode.h"
10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/feedback-source.h"
12 #include "src/compiler/globals.h"
13 #include "src/compiler/node-properties.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/opcodes.h"
16 #include "src/handles/maybe-handles.h"
17 #include "src/objects/type-hints.h"
18 #include "src/runtime/runtime.h"
19 
20 namespace v8 {
21 namespace internal {
22 
23 class AllocationSite;
24 class ObjectBoilerplateDescription;
25 class ArrayBoilerplateDescription;
26 class FeedbackCell;
27 class SharedFunctionInfo;
28 
29 namespace wasm {
30 class ValueType;
31 }
32 
33 namespace compiler {
34 
35 // Forward declarations.
36 class JSGraph;
37 class Operator;
38 struct JSOperatorGlobalCache;
39 
40 // Macro lists.
41 #define JS_UNOP_WITH_FEEDBACK(V) \
42   JS_BITWISE_UNOP_LIST(V)        \
43   JS_ARITH_UNOP_LIST(V)
44 
45 #define JS_BINOP_WITH_FEEDBACK(V) \
46   JS_ARITH_BINOP_LIST(V)          \
47   JS_BITWISE_BINOP_LIST(V)        \
48   JS_COMPARE_BINOP_LIST(V)        \
49   V(JSInstanceOf, InstanceOf)
50 
51 // Predicates.
52 class JSOperator final : public AllStatic {
53  public:
IsUnaryWithFeedback(Operator::Opcode opcode)54   static constexpr bool IsUnaryWithFeedback(Operator::Opcode opcode) {
55 #define CASE(Name, ...)   \
56   case IrOpcode::k##Name: \
57     return true;
58     switch (opcode) {
59       JS_UNOP_WITH_FEEDBACK(CASE);
60       default:
61         return false;
62     }
63 #undef CASE
64     return false;
65   }
66 
IsBinaryWithFeedback(Operator::Opcode opcode)67   static constexpr bool IsBinaryWithFeedback(Operator::Opcode opcode) {
68 #define CASE(Name, ...)   \
69   case IrOpcode::k##Name: \
70     return true;
71     switch (opcode) {
72       JS_BINOP_WITH_FEEDBACK(CASE);
73       default:
74         return false;
75     }
76 #undef CASE
77     return false;
78   }
79 };
80 
81 // Defines the frequency a given Call/Construct site was executed. For some
82 // call sites the frequency is not known.
83 class CallFrequency final {
84  public:
CallFrequency()85   CallFrequency() : value_(std::numeric_limits<float>::quiet_NaN()) {}
CallFrequency(float value)86   explicit CallFrequency(float value) : value_(value) {
87     DCHECK(!std::isnan(value));
88   }
89 
IsKnown()90   bool IsKnown() const { return !IsUnknown(); }
IsUnknown()91   bool IsUnknown() const { return std::isnan(value_); }
value()92   float value() const {
93     DCHECK(IsKnown());
94     return value_;
95   }
96 
97   bool operator==(CallFrequency const& that) const {
98     return bit_cast<uint32_t>(this->value_) == bit_cast<uint32_t>(that.value_);
99   }
100   bool operator!=(CallFrequency const& that) const { return !(*this == that); }
101 
hash_value(CallFrequency const & f)102   friend size_t hash_value(CallFrequency const& f) {
103     return bit_cast<uint32_t>(f.value_);
104   }
105 
106   static constexpr float kNoFeedbackCallFrequency = -1;
107 
108  private:
109   float value_;
110 };
111 
112 std::ostream& operator<<(std::ostream&, CallFrequency const&);
113 
114 // Defines the flags for a JavaScript call forwarding parameters. This
115 // is used as parameter by JSConstructForwardVarargs operators.
116 class ConstructForwardVarargsParameters final {
117  public:
ConstructForwardVarargsParameters(size_t arity,uint32_t start_index)118   ConstructForwardVarargsParameters(size_t arity, uint32_t start_index)
119       : bit_field_(ArityField::encode(arity) |
120                    StartIndexField::encode(start_index)) {}
121 
arity()122   size_t arity() const { return ArityField::decode(bit_field_); }
start_index()123   uint32_t start_index() const { return StartIndexField::decode(bit_field_); }
124 
125   bool operator==(ConstructForwardVarargsParameters const& that) const {
126     return this->bit_field_ == that.bit_field_;
127   }
128   bool operator!=(ConstructForwardVarargsParameters const& that) const {
129     return !(*this == that);
130   }
131 
132  private:
hash_value(ConstructForwardVarargsParameters const & p)133   friend size_t hash_value(ConstructForwardVarargsParameters const& p) {
134     return p.bit_field_;
135   }
136 
137   using ArityField = base::BitField<size_t, 0, 16>;
138   using StartIndexField = base::BitField<uint32_t, 16, 16>;
139 
140   uint32_t const bit_field_;
141 };
142 
143 std::ostream& operator<<(std::ostream&,
144                          ConstructForwardVarargsParameters const&);
145 
146 ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf(
147     Operator const*) V8_WARN_UNUSED_RESULT;
148 
149 // Defines the arity (parameters plus the target and new target) and the
150 // feedback for a JavaScript constructor call. This is used as a parameter by
151 // JSConstruct, JSConstructWithArrayLike, and JSConstructWithSpread operators.
152 class ConstructParameters final {
153  public:
154   // A separate declaration to get around circular declaration dependencies.
155   // Checked to equal JSConstructNode::kExtraInputCount below.
156   static constexpr int kExtraConstructInputCount = 3;
157 
ConstructParameters(uint32_t arity,CallFrequency const & frequency,FeedbackSource const & feedback)158   ConstructParameters(uint32_t arity, CallFrequency const& frequency,
159                       FeedbackSource const& feedback)
160       : arity_(arity), frequency_(frequency), feedback_(feedback) {
161     DCHECK_GE(arity, kExtraConstructInputCount);
162     DCHECK(is_int32(arity));
163   }
164 
165   // TODO(jgruber): Consider removing `arity()` and just storing the arity
166   // without extra args in ConstructParameters. Every spot that creates
167   // ConstructParameters artifically adds the extra args. Every spot that uses
168   // ConstructParameters artificially subtracts the extra args.
169   // We keep them for now for consistency with other spots
170   // that expect `arity()` to include extra args.
arity()171   uint32_t arity() const { return arity_; }
arity_without_implicit_args()172   int arity_without_implicit_args() const {
173     return static_cast<int>(arity_ - kExtraConstructInputCount);
174   }
175 
frequency()176   CallFrequency const& frequency() const { return frequency_; }
feedback()177   FeedbackSource const& feedback() const { return feedback_; }
178 
179  private:
180   uint32_t const arity_;
181   CallFrequency const frequency_;
182   FeedbackSource const feedback_;
183 };
184 
185 bool operator==(ConstructParameters const&, ConstructParameters const&);
186 bool operator!=(ConstructParameters const&, ConstructParameters const&);
187 
188 size_t hash_value(ConstructParameters const&);
189 
190 std::ostream& operator<<(std::ostream&, ConstructParameters const&);
191 
192 ConstructParameters const& ConstructParametersOf(Operator const*);
193 
194 // Defines the flags for a JavaScript call forwarding parameters. This
195 // is used as parameter by JSCallForwardVarargs operators.
196 class CallForwardVarargsParameters final {
197  public:
CallForwardVarargsParameters(size_t arity,uint32_t start_index)198   CallForwardVarargsParameters(size_t arity, uint32_t start_index)
199       : bit_field_(ArityField::encode(arity) |
200                    StartIndexField::encode(start_index)) {}
201 
arity()202   size_t arity() const { return ArityField::decode(bit_field_); }
start_index()203   uint32_t start_index() const { return StartIndexField::decode(bit_field_); }
204 
205   bool operator==(CallForwardVarargsParameters const& that) const {
206     return this->bit_field_ == that.bit_field_;
207   }
208   bool operator!=(CallForwardVarargsParameters const& that) const {
209     return !(*this == that);
210   }
211 
212  private:
hash_value(CallForwardVarargsParameters const & p)213   friend size_t hash_value(CallForwardVarargsParameters const& p) {
214     return p.bit_field_;
215   }
216 
217   using ArityField = base::BitField<size_t, 0, 15>;
218   using StartIndexField = base::BitField<uint32_t, 15, 15>;
219 
220   uint32_t const bit_field_;
221 };
222 
223 std::ostream& operator<<(std::ostream&, CallForwardVarargsParameters const&);
224 
225 CallForwardVarargsParameters const& CallForwardVarargsParametersOf(
226     Operator const*) V8_WARN_UNUSED_RESULT;
227 
228 // Defines the arity (parameters plus the target and receiver) and the call
229 // flags for a JavaScript function call. This is used as a parameter by JSCall,
230 // JSCallWithArrayLike and JSCallWithSpread operators.
231 class CallParameters final {
232  public:
233   // A separate declaration to get around circular declaration dependencies.
234   // Checked to equal JSCallNode::kExtraInputCount below.
235   static constexpr int kExtraCallInputCount = 3;
236 
CallParameters(size_t arity,CallFrequency const & frequency,FeedbackSource const & feedback,ConvertReceiverMode convert_mode,SpeculationMode speculation_mode,CallFeedbackRelation feedback_relation)237   CallParameters(size_t arity, CallFrequency const& frequency,
238                  FeedbackSource const& feedback,
239                  ConvertReceiverMode convert_mode,
240                  SpeculationMode speculation_mode,
241                  CallFeedbackRelation feedback_relation)
242       : bit_field_(ArityField::encode(arity) |
243                    CallFeedbackRelationField::encode(feedback_relation) |
244                    SpeculationModeField::encode(speculation_mode) |
245                    ConvertReceiverModeField::encode(convert_mode)),
246         frequency_(frequency),
247         feedback_(feedback) {
248     // CallFeedbackRelation is ignored if the feedback slot is invalid.
249     DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
250                    feedback.IsValid());
251     DCHECK_IMPLIES(!feedback.IsValid(),
252                    feedback_relation == CallFeedbackRelation::kUnrelated);
253     DCHECK_GE(arity, kExtraCallInputCount);
254     DCHECK(is_int32(arity));
255   }
256 
257   // TODO(jgruber): Consider removing `arity()` and just storing the arity
258   // without extra args in CallParameters.
arity()259   size_t arity() const { return ArityField::decode(bit_field_); }
arity_without_implicit_args()260   int arity_without_implicit_args() const {
261     return static_cast<int>(arity() - kExtraCallInputCount);
262   }
263 
frequency()264   CallFrequency const& frequency() const { return frequency_; }
convert_mode()265   ConvertReceiverMode convert_mode() const {
266     return ConvertReceiverModeField::decode(bit_field_);
267   }
feedback()268   FeedbackSource const& feedback() const { return feedback_; }
269 
speculation_mode()270   SpeculationMode speculation_mode() const {
271     return SpeculationModeField::decode(bit_field_);
272   }
273 
feedback_relation()274   CallFeedbackRelation feedback_relation() const {
275     return CallFeedbackRelationField::decode(bit_field_);
276   }
277 
278   bool operator==(CallParameters const& that) const {
279     return this->bit_field_ == that.bit_field_ &&
280            this->frequency_ == that.frequency_ &&
281            this->feedback_ == that.feedback_;
282   }
283   bool operator!=(CallParameters const& that) const { return !(*this == that); }
284 
285  private:
hash_value(CallParameters const & p)286   friend size_t hash_value(CallParameters const& p) {
287     FeedbackSource::Hash feedback_hash;
288     return base::hash_combine(p.bit_field_, p.frequency_,
289                               feedback_hash(p.feedback_));
290   }
291 
292   using ArityField = base::BitField<size_t, 0, 27>;
293   using CallFeedbackRelationField = base::BitField<CallFeedbackRelation, 27, 2>;
294   using SpeculationModeField = base::BitField<SpeculationMode, 29, 1>;
295   using ConvertReceiverModeField = base::BitField<ConvertReceiverMode, 30, 2>;
296 
297   uint32_t const bit_field_;
298   CallFrequency const frequency_;
299   FeedbackSource const feedback_;
300 };
301 
302 size_t hash_value(CallParameters const&);
303 
304 std::ostream& operator<<(std::ostream&, CallParameters const&);
305 
306 const CallParameters& CallParametersOf(const Operator* op);
307 
308 
309 // Defines the arity and the ID for a runtime function call. This is used as a
310 // parameter by JSCallRuntime operators.
311 class V8_EXPORT_PRIVATE CallRuntimeParameters final {
312  public:
CallRuntimeParameters(Runtime::FunctionId id,size_t arity)313   CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
314       : id_(id), arity_(arity) {}
315 
id()316   Runtime::FunctionId id() const { return id_; }
arity()317   size_t arity() const { return arity_; }
318 
319  private:
320   const Runtime::FunctionId id_;
321   const size_t arity_;
322 };
323 
324 bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
325 bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
326 
327 size_t hash_value(CallRuntimeParameters const&);
328 
329 std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
330 
331 V8_EXPORT_PRIVATE const CallRuntimeParameters& CallRuntimeParametersOf(
332     const Operator* op);
333 
334 // Defines the location of a context slot relative to a specific scope. This is
335 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
336 // accessing a context-allocated variable without keeping track of the scope.
337 class ContextAccess final {
338  public:
339   ContextAccess(size_t depth, size_t index, bool immutable);
340 
depth()341   size_t depth() const { return depth_; }
index()342   size_t index() const { return index_; }
immutable()343   bool immutable() const { return immutable_; }
344 
345  private:
346   // For space reasons, we keep this tightly packed, otherwise we could just use
347   // a simple int/int/bool POD.
348   const bool immutable_;
349   const uint16_t depth_;
350   const uint32_t index_;
351 };
352 
353 bool operator==(ContextAccess const&, ContextAccess const&);
354 bool operator!=(ContextAccess const&, ContextAccess const&);
355 
356 size_t hash_value(ContextAccess const&);
357 
358 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ContextAccess const&);
359 
360 V8_EXPORT_PRIVATE ContextAccess const& ContextAccessOf(Operator const*);
361 
362 // Defines the slot count and ScopeType for a new function or eval context. This
363 // is used as a parameter by the JSCreateFunctionContext operator.
364 class CreateFunctionContextParameters final {
365  public:
CreateFunctionContextParameters(const ScopeInfoRef & scope_info,int slot_count,ScopeType scope_type)366   CreateFunctionContextParameters(const ScopeInfoRef& scope_info,
367                                   int slot_count, ScopeType scope_type)
368       : scope_info_(scope_info),
369         slot_count_(slot_count),
370         scope_type_(scope_type) {}
371 
scope_info(JSHeapBroker * broker)372   ScopeInfoRef scope_info(JSHeapBroker* broker) const {
373     return scope_info_.AsRef(broker);
374   }
slot_count()375   int slot_count() const { return slot_count_; }
scope_type()376   ScopeType scope_type() const { return scope_type_; }
377 
378  private:
379   const ScopeInfoTinyRef scope_info_;
380   int const slot_count_;
381   ScopeType const scope_type_;
382 
383   friend bool operator==(CreateFunctionContextParameters const& lhs,
384                          CreateFunctionContextParameters const& rhs);
385   friend bool operator!=(CreateFunctionContextParameters const& lhs,
386                          CreateFunctionContextParameters const& rhs);
387 
388   friend size_t hash_value(CreateFunctionContextParameters const& parameters);
389 
390   friend std::ostream& operator<<(
391       std::ostream& os, CreateFunctionContextParameters const& parameters);
392 };
393 
394 CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
395     Operator const*);
396 
397 // Defines parameters for JSDefineNamedOwnProperty operator.
398 class DefineNamedOwnPropertyParameters final {
399  public:
DefineNamedOwnPropertyParameters(const NameRef & name,FeedbackSource const & feedback)400   DefineNamedOwnPropertyParameters(const NameRef& name,
401                                    FeedbackSource const& feedback)
402       : name_(name), feedback_(feedback) {}
403 
name(JSHeapBroker * broker)404   NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
feedback()405   FeedbackSource const& feedback() const { return feedback_; }
406 
407  private:
408   const NameTinyRef name_;
409   FeedbackSource const feedback_;
410 
411   friend bool operator==(DefineNamedOwnPropertyParameters const&,
412                          DefineNamedOwnPropertyParameters const&);
413   friend bool operator!=(DefineNamedOwnPropertyParameters const&,
414                          DefineNamedOwnPropertyParameters const&);
415   friend size_t hash_value(DefineNamedOwnPropertyParameters const&);
416   friend std::ostream& operator<<(std::ostream&,
417                                   DefineNamedOwnPropertyParameters const&);
418 };
419 
420 const DefineNamedOwnPropertyParameters& DefineNamedOwnPropertyParametersOf(
421     const Operator* op);
422 
423 // Defines the feedback, i.e., vector and index, for storing a data property in
424 // an object literal. This is used as a parameter by JSCreateEmptyLiteralArray
425 // and JSDefineKeyedOwnPropertyInLiteral operators.
426 class FeedbackParameter final {
427  public:
FeedbackParameter(FeedbackSource const & feedback)428   explicit FeedbackParameter(FeedbackSource const& feedback)
429       : feedback_(feedback) {}
430 
feedback()431   FeedbackSource const& feedback() const { return feedback_; }
432 
433  private:
434   FeedbackSource const feedback_;
435 };
436 
437 bool operator==(FeedbackParameter const&, FeedbackParameter const&);
438 bool operator!=(FeedbackParameter const&, FeedbackParameter const&);
439 
440 size_t hash_value(FeedbackParameter const&);
441 
442 std::ostream& operator<<(std::ostream&, FeedbackParameter const&);
443 
444 const FeedbackParameter& FeedbackParameterOf(const Operator* op);
445 
446 // Defines the property of an object for a named access. This is
447 // used as a parameter by the JSLoadNamed and JSSetNamedProperty operators.
448 class NamedAccess final {
449  public:
NamedAccess(LanguageMode language_mode,const NameRef & name,FeedbackSource const & feedback)450   NamedAccess(LanguageMode language_mode, const NameRef& name,
451               FeedbackSource const& feedback)
452       : name_(name), feedback_(feedback), language_mode_(language_mode) {}
453 
name(JSHeapBroker * broker)454   NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
language_mode()455   LanguageMode language_mode() const { return language_mode_; }
feedback()456   FeedbackSource const& feedback() const { return feedback_; }
457 
458  private:
459   const NameTinyRef name_;
460   FeedbackSource const feedback_;
461   LanguageMode const language_mode_;
462 
463   friend bool operator==(NamedAccess const&, NamedAccess const&);
464   friend bool operator!=(NamedAccess const&, NamedAccess const&);
465 
466   friend size_t hash_value(NamedAccess const&);
467 
468   friend std::ostream& operator<<(std::ostream&, NamedAccess const&);
469 };
470 
471 const NamedAccess& NamedAccessOf(const Operator* op);
472 
473 
474 // Defines the property being loaded from an object by a named load. This is
475 // used as a parameter by JSLoadGlobal operator.
476 class LoadGlobalParameters final {
477  public:
LoadGlobalParameters(const NameRef & name,const FeedbackSource & feedback,TypeofMode typeof_mode)478   LoadGlobalParameters(const NameRef& name, const FeedbackSource& feedback,
479                        TypeofMode typeof_mode)
480       : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
481 
name(JSHeapBroker * broker)482   NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
typeof_mode()483   TypeofMode typeof_mode() const { return typeof_mode_; }
484 
feedback()485   const FeedbackSource& feedback() const { return feedback_; }
486 
487  private:
488   const NameTinyRef name_;
489   const FeedbackSource feedback_;
490   const TypeofMode typeof_mode_;
491 
492   friend bool operator==(LoadGlobalParameters const&,
493                          LoadGlobalParameters const&);
494   friend bool operator!=(LoadGlobalParameters const&,
495                          LoadGlobalParameters const&);
496 
497   friend size_t hash_value(LoadGlobalParameters const&);
498 
499   friend std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&);
500 };
501 
502 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op);
503 
504 
505 // Defines the property being stored to an object by a named store. This is
506 // used as a parameter by JSStoreGlobal operator.
507 class StoreGlobalParameters final {
508  public:
StoreGlobalParameters(LanguageMode language_mode,const FeedbackSource & feedback,const NameRef & name)509   StoreGlobalParameters(LanguageMode language_mode,
510                         const FeedbackSource& feedback, const NameRef& name)
511       : language_mode_(language_mode), name_(name), feedback_(feedback) {}
512 
language_mode()513   LanguageMode language_mode() const { return language_mode_; }
feedback()514   FeedbackSource const& feedback() const { return feedback_; }
name(JSHeapBroker * broker)515   NameRef name(JSHeapBroker* broker) const { return name_.AsRef(broker); }
516 
517  private:
518   LanguageMode const language_mode_;
519   const NameTinyRef name_;
520   FeedbackSource const feedback_;
521 
522   friend bool operator==(StoreGlobalParameters const&,
523                          StoreGlobalParameters const&);
524   friend bool operator!=(StoreGlobalParameters const&,
525                          StoreGlobalParameters const&);
526 
527   friend size_t hash_value(StoreGlobalParameters const&);
528 
529   friend std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&);
530 };
531 
532 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op);
533 
534 // Defines the property of an object for a keyed access. This is used
535 // as a parameter by the JSLoadProperty and JSSetKeyedProperty
536 // operators.
537 class PropertyAccess final {
538  public:
PropertyAccess(LanguageMode language_mode,FeedbackSource const & feedback)539   PropertyAccess(LanguageMode language_mode, FeedbackSource const& feedback)
540       : feedback_(feedback), language_mode_(language_mode) {}
541 
language_mode()542   LanguageMode language_mode() const { return language_mode_; }
feedback()543   FeedbackSource const& feedback() const { return feedback_; }
544 
545  private:
546   FeedbackSource const feedback_;
547   LanguageMode const language_mode_;
548 };
549 
550 bool operator==(PropertyAccess const&, PropertyAccess const&);
551 bool operator!=(PropertyAccess const&, PropertyAccess const&);
552 
553 size_t hash_value(PropertyAccess const&);
554 
555 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
556                                            PropertyAccess const&);
557 
558 PropertyAccess const& PropertyAccessOf(const Operator* op);
559 
560 
561 // CreateArgumentsType is used as parameter to JSCreateArguments nodes.
562 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op);
563 
564 
565 // Defines shared information for the array that should be created. This is
566 // used as parameter by JSCreateArray operators.
567 class CreateArrayParameters final {
568  public:
CreateArrayParameters(size_t arity,base::Optional<AllocationSiteRef> site)569   CreateArrayParameters(size_t arity, base::Optional<AllocationSiteRef> site)
570       : arity_(arity), site_(site) {}
571 
arity()572   size_t arity() const { return arity_; }
site(JSHeapBroker * broker)573   base::Optional<AllocationSiteRef> site(JSHeapBroker* broker) const {
574     return AllocationSiteTinyRef::AsOptionalRef(broker, site_);
575   }
576 
577  private:
578   size_t const arity_;
579   base::Optional<AllocationSiteTinyRef> const site_;
580 
581   friend bool operator==(CreateArrayParameters const&,
582                          CreateArrayParameters const&);
583   friend bool operator!=(CreateArrayParameters const&,
584                          CreateArrayParameters const&);
585   friend size_t hash_value(CreateArrayParameters const&);
586   friend std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
587 };
588 
589 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
590 
591 // Defines shared information for the array iterator that should be created.
592 // This is used as parameter by JSCreateArrayIterator operators.
593 class CreateArrayIteratorParameters final {
594  public:
CreateArrayIteratorParameters(IterationKind kind)595   explicit CreateArrayIteratorParameters(IterationKind kind) : kind_(kind) {}
596 
kind()597   IterationKind kind() const { return kind_; }
598 
599  private:
600   IterationKind const kind_;
601 };
602 
603 bool operator==(CreateArrayIteratorParameters const&,
604                 CreateArrayIteratorParameters const&);
605 bool operator!=(CreateArrayIteratorParameters const&,
606                 CreateArrayIteratorParameters const&);
607 
608 size_t hash_value(CreateArrayIteratorParameters const&);
609 
610 std::ostream& operator<<(std::ostream&, CreateArrayIteratorParameters const&);
611 
612 const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf(
613     const Operator* op);
614 
615 // Defines shared information for the array iterator that should be created.
616 // This is used as parameter by JSCreateCollectionIterator operators.
617 class CreateCollectionIteratorParameters final {
618  public:
CreateCollectionIteratorParameters(CollectionKind collection_kind,IterationKind iteration_kind)619   explicit CreateCollectionIteratorParameters(CollectionKind collection_kind,
620                                               IterationKind iteration_kind)
621       : collection_kind_(collection_kind), iteration_kind_(iteration_kind) {
622     CHECK(!(collection_kind == CollectionKind::kSet &&
623             iteration_kind == IterationKind::kKeys));
624   }
625 
collection_kind()626   CollectionKind collection_kind() const { return collection_kind_; }
iteration_kind()627   IterationKind iteration_kind() const { return iteration_kind_; }
628 
629  private:
630   CollectionKind const collection_kind_;
631   IterationKind const iteration_kind_;
632 };
633 
634 bool operator==(CreateCollectionIteratorParameters const&,
635                 CreateCollectionIteratorParameters const&);
636 bool operator!=(CreateCollectionIteratorParameters const&,
637                 CreateCollectionIteratorParameters const&);
638 
639 size_t hash_value(CreateCollectionIteratorParameters const&);
640 
641 std::ostream& operator<<(std::ostream&,
642                          CreateCollectionIteratorParameters const&);
643 
644 const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf(
645     const Operator* op);
646 
647 // Defines shared information for the bound function that should be created.
648 // This is used as parameter by JSCreateBoundFunction operators.
649 class CreateBoundFunctionParameters final {
650  public:
CreateBoundFunctionParameters(size_t arity,const MapRef & map)651   CreateBoundFunctionParameters(size_t arity, const MapRef& map)
652       : arity_(arity), map_(map) {}
653 
arity()654   size_t arity() const { return arity_; }
map(JSHeapBroker * broker)655   MapRef map(JSHeapBroker* broker) const { return map_.AsRef(broker); }
656 
657  private:
658   size_t const arity_;
659   const MapTinyRef map_;
660 
661   friend bool operator==(CreateBoundFunctionParameters const&,
662                          CreateBoundFunctionParameters const&);
663   friend bool operator!=(CreateBoundFunctionParameters const&,
664                          CreateBoundFunctionParameters const&);
665 
666   friend size_t hash_value(CreateBoundFunctionParameters const&);
667 
668   friend std::ostream& operator<<(std::ostream&,
669                                   CreateBoundFunctionParameters const&);
670 };
671 
672 const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
673     const Operator* op);
674 
675 // Defines shared information for the closure that should be created. This is
676 // used as a parameter by JSCreateClosure operators.
677 class CreateClosureParameters final {
678  public:
CreateClosureParameters(const SharedFunctionInfoRef & shared_info,const CodeTRef & code,AllocationType allocation)679   CreateClosureParameters(const SharedFunctionInfoRef& shared_info,
680                           const CodeTRef& code, AllocationType allocation)
681       : shared_info_(shared_info), code_(code), allocation_(allocation) {}
682 
shared_info(JSHeapBroker * broker)683   SharedFunctionInfoRef shared_info(JSHeapBroker* broker) const {
684     return shared_info_.AsRef(broker);
685   }
code(JSHeapBroker * broker)686   CodeTRef code(JSHeapBroker* broker) const { return code_.AsRef(broker); }
allocation()687   AllocationType allocation() const { return allocation_; }
688 
689  private:
690   const SharedFunctionInfoTinyRef shared_info_;
691   const CodeTTinyRef code_;
692   AllocationType const allocation_;
693 
694   friend bool operator==(CreateClosureParameters const&,
695                          CreateClosureParameters const&);
696   friend bool operator!=(CreateClosureParameters const&,
697                          CreateClosureParameters const&);
698 
699   friend size_t hash_value(CreateClosureParameters const&);
700 
701   friend std::ostream& operator<<(std::ostream&,
702                                   CreateClosureParameters const&);
703 };
704 
705 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
706 
707 class GetTemplateObjectParameters final {
708  public:
GetTemplateObjectParameters(const TemplateObjectDescriptionRef & description,const SharedFunctionInfoRef & shared,FeedbackSource const & feedback)709   GetTemplateObjectParameters(const TemplateObjectDescriptionRef& description,
710                               const SharedFunctionInfoRef& shared,
711                               FeedbackSource const& feedback)
712       : description_(description), shared_(shared), feedback_(feedback) {}
713 
description(JSHeapBroker * broker)714   TemplateObjectDescriptionRef description(JSHeapBroker* broker) const {
715     return description_.AsRef(broker);
716   }
shared(JSHeapBroker * broker)717   SharedFunctionInfoRef shared(JSHeapBroker* broker) const {
718     return shared_.AsRef(broker);
719   }
feedback()720   FeedbackSource const& feedback() const { return feedback_; }
721 
722  private:
723   const TemplateObjectDescriptionTinyRef description_;
724   const SharedFunctionInfoTinyRef shared_;
725   FeedbackSource const feedback_;
726 
727   friend bool operator==(GetTemplateObjectParameters const&,
728                          GetTemplateObjectParameters const&);
729   friend bool operator!=(GetTemplateObjectParameters const&,
730                          GetTemplateObjectParameters const&);
731 
732   friend size_t hash_value(GetTemplateObjectParameters const&);
733 
734   friend std::ostream& operator<<(std::ostream&,
735                                   GetTemplateObjectParameters const&);
736 };
737 
738 const GetTemplateObjectParameters& GetTemplateObjectParametersOf(
739     const Operator* op);
740 
741 // Defines shared information for the literal that should be created. This is
742 // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
743 // JSCreateLiteralRegExp operators.
744 class CreateLiteralParameters final {
745  public:
CreateLiteralParameters(const HeapObjectRef & constant,FeedbackSource const & feedback,int length,int flags)746   CreateLiteralParameters(const HeapObjectRef& constant,
747                           FeedbackSource const& feedback, int length, int flags)
748       : constant_(constant),
749         feedback_(feedback),
750         length_(length),
751         flags_(flags) {}
752 
constant(JSHeapBroker * broker)753   HeapObjectRef constant(JSHeapBroker* broker) const {
754     return constant_.AsRef(broker);
755   }
feedback()756   FeedbackSource const& feedback() const { return feedback_; }
length()757   int length() const { return length_; }
flags()758   int flags() const { return flags_; }
759 
760  private:
761   const HeapObjectTinyRef constant_;
762   FeedbackSource const feedback_;
763   int const length_;
764   int const flags_;
765 
766   friend bool operator==(CreateLiteralParameters const&,
767                          CreateLiteralParameters const&);
768   friend bool operator!=(CreateLiteralParameters const&,
769                          CreateLiteralParameters const&);
770 
771   friend size_t hash_value(CreateLiteralParameters const&);
772 
773   friend std::ostream& operator<<(std::ostream&,
774                                   CreateLiteralParameters const&);
775 };
776 
777 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
778 
779 class CloneObjectParameters final {
780  public:
CloneObjectParameters(FeedbackSource const & feedback,int flags)781   CloneObjectParameters(FeedbackSource const& feedback, int flags)
782       : feedback_(feedback), flags_(flags) {}
783 
feedback()784   FeedbackSource const& feedback() const { return feedback_; }
flags()785   int flags() const { return flags_; }
786 
787  private:
788   FeedbackSource const feedback_;
789   int const flags_;
790 };
791 
792 bool operator==(CloneObjectParameters const&, CloneObjectParameters const&);
793 bool operator!=(CloneObjectParameters const&, CloneObjectParameters const&);
794 
795 size_t hash_value(CloneObjectParameters const&);
796 
797 std::ostream& operator<<(std::ostream&, CloneObjectParameters const&);
798 
799 const CloneObjectParameters& CloneObjectParametersOf(const Operator* op);
800 
801 // Defines the shared information for the iterator symbol thats loaded and
802 // called. This is used as a parameter by JSGetIterator operator.
803 class GetIteratorParameters final {
804  public:
GetIteratorParameters(const FeedbackSource & load_feedback,const FeedbackSource & call_feedback)805   GetIteratorParameters(const FeedbackSource& load_feedback,
806                         const FeedbackSource& call_feedback)
807       : load_feedback_(load_feedback), call_feedback_(call_feedback) {}
808 
loadFeedback()809   FeedbackSource const& loadFeedback() const { return load_feedback_; }
callFeedback()810   FeedbackSource const& callFeedback() const { return call_feedback_; }
811 
812  private:
813   FeedbackSource const load_feedback_;
814   FeedbackSource const call_feedback_;
815 };
816 
817 bool operator==(GetIteratorParameters const&, GetIteratorParameters const&);
818 bool operator!=(GetIteratorParameters const&, GetIteratorParameters const&);
819 
820 size_t hash_value(GetIteratorParameters const&);
821 
822 std::ostream& operator<<(std::ostream&, GetIteratorParameters const&);
823 
824 const GetIteratorParameters& GetIteratorParametersOf(const Operator* op);
825 
826 enum class ForInMode : uint8_t {
827   kUseEnumCacheKeysAndIndices,
828   kUseEnumCacheKeys,
829   kGeneric
830 };
831 size_t hash_value(ForInMode const&);
832 std::ostream& operator<<(std::ostream&, ForInMode const&);
833 
834 class ForInParameters final {
835  public:
ForInParameters(const FeedbackSource & feedback,ForInMode mode)836   ForInParameters(const FeedbackSource& feedback, ForInMode mode)
837       : feedback_(feedback), mode_(mode) {}
838 
feedback()839   const FeedbackSource& feedback() const { return feedback_; }
mode()840   ForInMode mode() const { return mode_; }
841 
842  private:
843   const FeedbackSource feedback_;
844   const ForInMode mode_;
845 };
846 
847 bool operator==(ForInParameters const&, ForInParameters const&);
848 bool operator!=(ForInParameters const&, ForInParameters const&);
849 size_t hash_value(ForInParameters const&);
850 std::ostream& operator<<(std::ostream&, ForInParameters const&);
851 const ForInParameters& ForInParametersOf(const Operator* op);
852 
853 #if V8_ENABLE_WEBASSEMBLY
854 class JSWasmCallParameters {
855  public:
JSWasmCallParameters(const wasm::WasmModule * module,const wasm::FunctionSig * signature,FeedbackSource const & feedback)856   explicit JSWasmCallParameters(const wasm::WasmModule* module,
857                                 const wasm::FunctionSig* signature,
858                                 FeedbackSource const& feedback)
859       : module_(module), signature_(signature), feedback_(feedback) {
860     DCHECK_NOT_NULL(module);
861     DCHECK_NOT_NULL(signature);
862   }
863 
module()864   const wasm::WasmModule* module() const { return module_; }
signature()865   const wasm::FunctionSig* signature() const { return signature_; }
feedback()866   FeedbackSource const& feedback() const { return feedback_; }
867   int input_count() const;
868   int arity_without_implicit_args() const;
869 
870  private:
871   const wasm::WasmModule* const module_;
872   const wasm::FunctionSig* const signature_;
873   const FeedbackSource feedback_;
874 };
875 
876 JSWasmCallParameters const& JSWasmCallParametersOf(const Operator* op)
877     V8_WARN_UNUSED_RESULT;
878 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
879                                            JSWasmCallParameters const&);
880 size_t hash_value(JSWasmCallParameters const&);
881 bool operator==(JSWasmCallParameters const&, JSWasmCallParameters const&);
882 #endif  // V8_ENABLE_WEBASSEMBLY
883 
884 int RegisterCountOf(Operator const* op) V8_WARN_UNUSED_RESULT;
885 
886 int GeneratorStoreValueCountOf(const Operator* op) V8_WARN_UNUSED_RESULT;
887 int RestoreRegisterIndexOf(const Operator* op) V8_WARN_UNUSED_RESULT;
888 
889 ScopeInfoRef ScopeInfoOf(JSHeapBroker* broker,
890                          const Operator* op) V8_WARN_UNUSED_RESULT;
891 
892 bool operator==(ScopeInfoTinyRef const&, ScopeInfoTinyRef const&);
893 bool operator!=(ScopeInfoTinyRef const&, ScopeInfoTinyRef const&);
894 
895 size_t hash_value(ScopeInfoTinyRef const&);
896 
897 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
898                                            ScopeInfoTinyRef const&);
899 
900 // Interface for building JavaScript-level operators, e.g. directly from the
901 // AST. Most operators have no parameters, thus can be globally shared for all
902 // graphs.
903 class V8_EXPORT_PRIVATE JSOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)904     : public NON_EXPORTED_BASE(ZoneObject) {
905  public:
906   explicit JSOperatorBuilder(Zone* zone);
907   JSOperatorBuilder(const JSOperatorBuilder&) = delete;
908   JSOperatorBuilder& operator=(const JSOperatorBuilder&) = delete;
909 
910   const Operator* Equal(FeedbackSource const& feedback);
911   const Operator* StrictEqual(FeedbackSource const& feedback);
912   const Operator* LessThan(FeedbackSource const& feedback);
913   const Operator* GreaterThan(FeedbackSource const& feedback);
914   const Operator* LessThanOrEqual(FeedbackSource const& feedback);
915   const Operator* GreaterThanOrEqual(FeedbackSource const& feedback);
916 
917   const Operator* BitwiseOr(FeedbackSource const& feedback);
918   const Operator* BitwiseXor(FeedbackSource const& feedback);
919   const Operator* BitwiseAnd(FeedbackSource const& feedback);
920   const Operator* ShiftLeft(FeedbackSource const& feedback);
921   const Operator* ShiftRight(FeedbackSource const& feedback);
922   const Operator* ShiftRightLogical(FeedbackSource const& feedback);
923   const Operator* Add(FeedbackSource const& feedback);
924   const Operator* Subtract(FeedbackSource const& feedback);
925   const Operator* Multiply(FeedbackSource const& feedback);
926   const Operator* Divide(FeedbackSource const& feedback);
927   const Operator* Modulus(FeedbackSource const& feedback);
928   const Operator* Exponentiate(FeedbackSource const& feedback);
929 
930   const Operator* BitwiseNot(FeedbackSource const& feedback);
931   const Operator* Decrement(FeedbackSource const& feedback);
932   const Operator* Increment(FeedbackSource const& feedback);
933   const Operator* Negate(FeedbackSource const& feedback);
934 
935   const Operator* ToLength();
936   const Operator* ToName();
937   const Operator* ToNumber();
938   const Operator* ToNumberConvertBigInt();
939   const Operator* ToNumeric();
940   const Operator* ToObject();
941   const Operator* ToString();
942 
943   const Operator* Create();
944   const Operator* CreateArguments(CreateArgumentsType type);
945   const Operator* CreateArray(size_t arity,
946                               base::Optional<AllocationSiteRef> site);
947   const Operator* CreateArrayIterator(IterationKind);
948   const Operator* CreateAsyncFunctionObject(int register_count);
949   const Operator* CreateCollectionIterator(CollectionKind, IterationKind);
950   const Operator* CreateBoundFunction(size_t arity, const MapRef& map);
951   const Operator* CreateClosure(
952       const SharedFunctionInfoRef& shared_info, const CodeTRef& code,
953       AllocationType allocation = AllocationType::kYoung);
954   const Operator* CreateIterResultObject();
955   const Operator* CreateStringIterator();
956   const Operator* CreateKeyValueArray();
957   const Operator* CreateObject();
958   const Operator* CreatePromise();
959   const Operator* CreateTypedArray();
960   const Operator* CreateLiteralArray(
961       const ArrayBoilerplateDescriptionRef& constant,
962       FeedbackSource const& feedback, int literal_flags,
963       int number_of_elements);
964   const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback);
965   const Operator* CreateArrayFromIterable();
966   const Operator* CreateEmptyLiteralObject();
967   const Operator* CreateLiteralObject(
968       const ObjectBoilerplateDescriptionRef& constant,
969       FeedbackSource const& feedback, int literal_flags,
970       int number_of_properties);
971   const Operator* CloneObject(FeedbackSource const& feedback,
972                               int literal_flags);
973   const Operator* CreateLiteralRegExp(const StringRef& constant_pattern,
974                                       FeedbackSource const& feedback,
975                                       int literal_flags);
976 
977   const Operator* GetTemplateObject(
978       const TemplateObjectDescriptionRef& description,
979       const SharedFunctionInfoRef& shared, FeedbackSource const& feedback);
980 
981   const Operator* CallForwardVarargs(size_t arity, uint32_t start_index);
982   const Operator* Call(
983       size_t arity, CallFrequency const& frequency = CallFrequency(),
984       FeedbackSource const& feedback = FeedbackSource(),
985       ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
986       SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
987       CallFeedbackRelation feedback_relation =
988           CallFeedbackRelation::kUnrelated);
989   const Operator* CallWithArrayLike(
990       CallFrequency const& frequency,
991       const FeedbackSource& feedback = FeedbackSource{},
992       SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
993       CallFeedbackRelation feedback_relation = CallFeedbackRelation::kTarget);
994   const Operator* CallWithSpread(
995       uint32_t arity, CallFrequency const& frequency = CallFrequency(),
996       FeedbackSource const& feedback = FeedbackSource(),
997       SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation,
998       CallFeedbackRelation feedback_relation = CallFeedbackRelation::kTarget);
999   const Operator* CallRuntime(Runtime::FunctionId id);
1000   const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
1001   const Operator* CallRuntime(const Runtime::Function* function, size_t arity);
1002 
1003 #if V8_ENABLE_WEBASSEMBLY
1004   const Operator* CallWasm(const wasm::WasmModule* wasm_module,
1005                            const wasm::FunctionSig* wasm_signature,
1006                            FeedbackSource const& feedback);
1007 #endif  // V8_ENABLE_WEBASSEMBLY
1008 
1009   const Operator* ConstructForwardVarargs(size_t arity, uint32_t start_index);
1010   const Operator* Construct(uint32_t arity,
1011                             CallFrequency const& frequency = CallFrequency(),
1012                             FeedbackSource const& feedback = FeedbackSource());
1013   const Operator* ConstructWithArrayLike(CallFrequency const& frequency,
1014                                          FeedbackSource const& feedback);
1015   const Operator* ConstructWithSpread(
1016       uint32_t arity, CallFrequency const& frequency = CallFrequency(),
1017       FeedbackSource const& feedback = FeedbackSource());
1018 
1019   const Operator* LoadProperty(FeedbackSource const& feedback);
1020   const Operator* LoadNamed(const NameRef& name,
1021                             FeedbackSource const& feedback);
1022   const Operator* LoadNamedFromSuper(const NameRef& name,
1023                                      FeedbackSource const& feedback);
1024 
1025   const Operator* SetKeyedProperty(LanguageMode language_mode,
1026                                    FeedbackSource const& feedback);
1027   const Operator* DefineKeyedOwnProperty(LanguageMode language_mode,
1028                                          FeedbackSource const& feedback);
1029   const Operator* SetNamedProperty(LanguageMode language_mode,
1030                                    const NameRef& name,
1031                                    FeedbackSource const& feedback);
1032 
1033   const Operator* DefineNamedOwnProperty(const NameRef& name,
1034                                          FeedbackSource const& feedback);
1035   const Operator* DefineKeyedOwnPropertyInLiteral(
1036       const FeedbackSource& feedback);
1037   const Operator* StoreInArrayLiteral(const FeedbackSource& feedback);
1038 
1039   const Operator* DeleteProperty();
1040 
1041   const Operator* HasProperty(FeedbackSource const& feedback);
1042 
1043   const Operator* GetSuperConstructor();
1044 
1045   const Operator* CreateGeneratorObject();
1046 
1047   const Operator* LoadGlobal(const NameRef& name,
1048                              const FeedbackSource& feedback,
1049                              TypeofMode typeof_mode = TypeofMode::kNotInside);
1050   const Operator* StoreGlobal(LanguageMode language_mode, const NameRef& name,
1051                               const FeedbackSource& feedback);
1052 
1053   const Operator* HasContextExtension(size_t depth);
1054   const Operator* LoadContext(size_t depth, size_t index, bool immutable);
1055   const Operator* StoreContext(size_t depth, size_t index);
1056 
1057   const Operator* LoadModule(int32_t cell_index);
1058   const Operator* StoreModule(int32_t cell_index);
1059 
1060   const Operator* GetImportMeta();
1061 
1062   const Operator* HasInPrototypeChain();
1063   const Operator* InstanceOf(const FeedbackSource& feedback);
1064   const Operator* OrdinaryHasInstance();
1065 
1066   const Operator* AsyncFunctionEnter();
1067   const Operator* AsyncFunctionReject();
1068   const Operator* AsyncFunctionResolve();
1069 
1070   const Operator* ForInEnumerate();
1071   const Operator* ForInNext(ForInMode mode, const FeedbackSource& feedback);
1072   const Operator* ForInPrepare(ForInMode mode, const FeedbackSource& feedback);
1073 
1074   const Operator* LoadMessage();
1075   const Operator* StoreMessage();
1076 
1077   // Used to implement Ignition's SuspendGenerator bytecode.
1078   const Operator* GeneratorStore(int value_count);
1079 
1080   // Used to implement Ignition's SwitchOnGeneratorState bytecode.
1081   const Operator* GeneratorRestoreContinuation();
1082   const Operator* GeneratorRestoreContext();
1083 
1084   // Used to implement Ignition's ResumeGenerator bytecode.
1085   const Operator* GeneratorRestoreRegister(int index);
1086   const Operator* GeneratorRestoreInputOrDebugPos();
1087 
1088   const Operator* StackCheck(StackCheckKind kind);
1089   const Operator* Debugger();
1090 
1091   const Operator* FulfillPromise();
1092   const Operator* PerformPromiseThen();
1093   const Operator* PromiseResolve();
1094   const Operator* RejectPromise();
1095   const Operator* ResolvePromise();
1096 
1097   const Operator* CreateFunctionContext(const ScopeInfoRef& scope_info,
1098                                         int slot_count, ScopeType scope_type);
1099   const Operator* CreateCatchContext(const ScopeInfoRef& scope_info);
1100   const Operator* CreateWithContext(const ScopeInfoRef& scope_info);
1101   const Operator* CreateBlockContext(const ScopeInfoRef& scpope_info);
1102 
1103   const Operator* ObjectIsArray();
1104   const Operator* ParseInt();
1105   const Operator* RegExpTest();
1106 
1107   const Operator* GetIterator(FeedbackSource const& load_feedback,
1108                               FeedbackSource const& call_feedback);
1109 
1110  private:
1111   Zone* zone() const { return zone_; }
1112 
1113   const JSOperatorGlobalCache& cache_;
1114   Zone* const zone_;
1115 };
1116 
1117 // Node wrappers.
1118 
1119 class JSNodeWrapperBase : public NodeWrapper {
1120  public:
JSNodeWrapperBase(Node * node)1121   explicit constexpr JSNodeWrapperBase(Node* node) : NodeWrapper(node) {}
1122 
1123   // Valid iff this node has a context input.
context()1124   TNode<Object> context() const {
1125     // Could be a Context or NoContextConstant.
1126     return TNode<Object>::UncheckedCast(
1127         NodeProperties::GetContextInput(node()));
1128   }
1129 
1130   // Valid iff this node has exactly one effect input.
effect()1131   Effect effect() const {
1132     DCHECK_EQ(node()->op()->EffectInputCount(), 1);
1133     return Effect{NodeProperties::GetEffectInput(node())};
1134   }
1135 
1136   // Valid iff this node has exactly one control input.
control()1137   Control control() const {
1138     DCHECK_EQ(node()->op()->ControlInputCount(), 1);
1139     return Control{NodeProperties::GetControlInput(node())};
1140   }
1141 
1142   // Valid iff this node has a frame state input.
frame_state()1143   FrameState frame_state() const {
1144     return FrameState{NodeProperties::GetFrameStateInput(node())};
1145   }
1146 };
1147 
1148 #define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
1149   static constexpr int Name##Index() { return TheIndex; }  \
1150   TNode<Type> name() const {                               \
1151     return TNode<Type>::UncheckedCast(                     \
1152         NodeProperties::GetValueInput(node(), TheIndex));  \
1153   }
1154 
1155 class JSUnaryOpNode final : public JSNodeWrapperBase {
1156  public:
JSUnaryOpNode(Node * node)1157   explicit constexpr JSUnaryOpNode(Node* node) : JSNodeWrapperBase(node) {
1158     DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode()));
1159   }
1160 
1161 #define INPUTS(V)            \
1162   V(Value, value, 0, Object) \
1163   V(FeedbackVector, feedback_vector, 1, HeapObject)
1164   INPUTS(DEFINE_INPUT_ACCESSORS)
1165 #undef INPUTS
1166 };
1167 
1168 #define V(JSName, ...) using JSName##Node = JSUnaryOpNode;
JS_UNOP_WITH_FEEDBACK(V)1169 JS_UNOP_WITH_FEEDBACK(V)
1170 #undef V
1171 
1172 class JSBinaryOpNode final : public JSNodeWrapperBase {
1173  public:
1174   explicit constexpr JSBinaryOpNode(Node* node) : JSNodeWrapperBase(node) {
1175     DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode()));
1176   }
1177 
1178   const FeedbackParameter& Parameters() const {
1179     return FeedbackParameterOf(node()->op());
1180   }
1181 
1182 #define INPUTS(V)            \
1183   V(Left, left, 0, Object)   \
1184   V(Right, right, 1, Object) \
1185   V(FeedbackVector, feedback_vector, 2, HeapObject)
1186   INPUTS(DEFINE_INPUT_ACCESSORS)
1187 #undef INPUTS
1188 };
1189 
1190 #define V(JSName, ...) using JSName##Node = JSBinaryOpNode;
JS_BINOP_WITH_FEEDBACK(V)1191 JS_BINOP_WITH_FEEDBACK(V)
1192 #undef V
1193 
1194 class JSGetIteratorNode final : public JSNodeWrapperBase {
1195  public:
1196   explicit constexpr JSGetIteratorNode(Node* node) : JSNodeWrapperBase(node) {
1197     DCHECK_EQ(IrOpcode::kJSGetIterator, node->opcode());
1198   }
1199 
1200   const GetIteratorParameters& Parameters() const {
1201     return GetIteratorParametersOf(node()->op());
1202   }
1203 
1204 #define INPUTS(V)                  \
1205   V(Receiver, receiver, 0, Object) \
1206   V(FeedbackVector, feedback_vector, 1, HeapObject)
1207   INPUTS(DEFINE_INPUT_ACCESSORS)
1208 #undef INPUTS
1209 };
1210 
1211 class JSCloneObjectNode final : public JSNodeWrapperBase {
1212  public:
JSCloneObjectNode(Node * node)1213   explicit constexpr JSCloneObjectNode(Node* node) : JSNodeWrapperBase(node) {
1214     DCHECK_EQ(IrOpcode::kJSCloneObject, node->opcode());
1215   }
1216 
Parameters()1217   const CloneObjectParameters& Parameters() const {
1218     return CloneObjectParametersOf(node()->op());
1219   }
1220 
1221 #define INPUTS(V)              \
1222   V(Source, source, 0, Object) \
1223   V(FeedbackVector, feedback_vector, 1, HeapObject)
1224   INPUTS(DEFINE_INPUT_ACCESSORS)
1225 #undef INPUTS
1226 };
1227 
1228 class JSGetTemplateObjectNode final : public JSNodeWrapperBase {
1229  public:
JSGetTemplateObjectNode(Node * node)1230   explicit constexpr JSGetTemplateObjectNode(Node* node)
1231       : JSNodeWrapperBase(node) {
1232     DCHECK_EQ(IrOpcode::kJSGetTemplateObject, node->opcode());
1233   }
1234 
Parameters()1235   const GetTemplateObjectParameters& Parameters() const {
1236     return GetTemplateObjectParametersOf(node()->op());
1237   }
1238 
1239 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1240   INPUTS(DEFINE_INPUT_ACCESSORS)
1241 #undef INPUTS
1242 };
1243 
1244 class JSCreateLiteralOpNode final : public JSNodeWrapperBase {
1245  public:
JSCreateLiteralOpNode(Node * node)1246   explicit constexpr JSCreateLiteralOpNode(Node* node)
1247       : JSNodeWrapperBase(node) {
1248     DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
1249            node->opcode() == IrOpcode::kJSCreateLiteralObject ||
1250            node->opcode() == IrOpcode::kJSCreateLiteralRegExp);
1251   }
1252 
Parameters()1253   const CreateLiteralParameters& Parameters() const {
1254     return CreateLiteralParametersOf(node()->op());
1255   }
1256 
1257 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1258   INPUTS(DEFINE_INPUT_ACCESSORS)
1259 #undef INPUTS
1260 };
1261 
1262 using JSCreateLiteralArrayNode = JSCreateLiteralOpNode;
1263 using JSCreateLiteralObjectNode = JSCreateLiteralOpNode;
1264 using JSCreateLiteralRegExpNode = JSCreateLiteralOpNode;
1265 
1266 class JSHasPropertyNode final : public JSNodeWrapperBase {
1267  public:
JSHasPropertyNode(Node * node)1268   explicit constexpr JSHasPropertyNode(Node* node) : JSNodeWrapperBase(node) {
1269     DCHECK_EQ(IrOpcode::kJSHasProperty, node->opcode());
1270   }
1271 
Parameters()1272   const PropertyAccess& Parameters() const {
1273     return PropertyAccessOf(node()->op());
1274   }
1275 
1276 #define INPUTS(V)              \
1277   V(Object, object, 0, Object) \
1278   V(Key, key, 1, Object)       \
1279   V(FeedbackVector, feedback_vector, 2, HeapObject)
1280   INPUTS(DEFINE_INPUT_ACCESSORS)
1281 #undef INPUTS
1282 };
1283 
1284 class JSLoadPropertyNode final : public JSNodeWrapperBase {
1285  public:
JSLoadPropertyNode(Node * node)1286   explicit constexpr JSLoadPropertyNode(Node* node) : JSNodeWrapperBase(node) {
1287     DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode());
1288   }
1289 
Parameters()1290   const PropertyAccess& Parameters() const {
1291     return PropertyAccessOf(node()->op());
1292   }
1293 
1294 #define INPUTS(V)              \
1295   V(Object, object, 0, Object) \
1296   V(Key, key, 1, Object)       \
1297   V(FeedbackVector, feedback_vector, 2, HeapObject)
1298   INPUTS(DEFINE_INPUT_ACCESSORS)
1299 #undef INPUTS
1300 };
1301 
1302 class JSSetKeyedPropertyNode final : public JSNodeWrapperBase {
1303  public:
JSSetKeyedPropertyNode(Node * node)1304   explicit constexpr JSSetKeyedPropertyNode(Node* node)
1305       : JSNodeWrapperBase(node) {
1306     DCHECK_EQ(IrOpcode::kJSSetKeyedProperty, node->opcode());
1307   }
1308 
Parameters()1309   const PropertyAccess& Parameters() const {
1310     return PropertyAccessOf(node()->op());
1311   }
1312 
1313 #define INPUTS(V)              \
1314   V(Object, object, 0, Object) \
1315   V(Key, key, 1, Object)       \
1316   V(Value, value, 2, Object)   \
1317   V(FeedbackVector, feedback_vector, 3, HeapObject)
1318   INPUTS(DEFINE_INPUT_ACCESSORS)
1319 #undef INPUTS
1320 };
1321 
1322 class JSDefineKeyedOwnPropertyNode final : public JSNodeWrapperBase {
1323  public:
JSDefineKeyedOwnPropertyNode(Node * node)1324   explicit constexpr JSDefineKeyedOwnPropertyNode(Node* node)
1325       : JSNodeWrapperBase(node) {
1326     DCHECK_EQ(IrOpcode::kJSDefineKeyedOwnProperty, node->opcode());
1327   }
1328 
Parameters()1329   const PropertyAccess& Parameters() const {
1330     return PropertyAccessOf(node()->op());
1331   }
1332 
1333 #define INPUTS(V)              \
1334   V(Object, object, 0, Object) \
1335   V(Key, key, 1, Object)       \
1336   V(Value, value, 2, Object)   \
1337   V(FeedbackVector, feedback_vector, 3, HeapObject)
1338   INPUTS(DEFINE_INPUT_ACCESSORS)
1339 #undef INPUTS
1340 };
1341 
1342 namespace js_node_wrapper_utils {
1343 // Avoids template definitions in the .cc file.
1344 TNode<Oddball> UndefinedConstant(JSGraph* jsgraph);
1345 }  // namespace js_node_wrapper_utils
1346 
1347 class JSCallOrConstructNode : public JSNodeWrapperBase {
1348  public:
JSCallOrConstructNode(Node * node)1349   explicit constexpr JSCallOrConstructNode(Node* node)
1350       : JSNodeWrapperBase(node) {
1351     DCHECK(IsValidNode(node));
1352   }
1353 
1354 #define INPUTS(V)              \
1355   V(Target, target, 0, Object) \
1356   V(ReceiverOrNewTarget, receiver_or_new_target, 1, Object)
1357   INPUTS(DEFINE_INPUT_ACCESSORS)
1358 #undef INPUTS
1359 
1360   // Besides actual arguments, JSCall nodes (and variants) also take the
1361   // following. Note that we rely on the fact that all variants (JSCall,
1362   // JSCallWithArrayLike, JSCallWithSpread, JSConstruct,
1363   // JSConstructWithArrayLike, JSConstructWithSpread, JSWasmCall) have the same
1364   // underlying node layout.
1365   static constexpr int kTargetInputCount = 1;
1366   static constexpr int kReceiverOrNewTargetInputCount = 1;
1367   static constexpr int kFeedbackVectorInputCount = 1;
1368   static constexpr int kExtraInputCount = kTargetInputCount +
1369                                           kReceiverOrNewTargetInputCount +
1370                                           kFeedbackVectorInputCount;
1371   STATIC_ASSERT(kExtraInputCount == CallParameters::kExtraCallInputCount);
1372   STATIC_ASSERT(kExtraInputCount ==
1373                 ConstructParameters::kExtraConstructInputCount);
1374 
1375   // Just for static asserts for spots that rely on node layout.
1376   static constexpr bool kFeedbackVectorIsLastInput = true;
1377 
1378   // Some spots rely on the fact that call and construct variants have the same
1379   // layout.
1380   static constexpr bool kHaveIdenticalLayouts = true;
1381 
1382   // This is the arity fed into Call/ConstructArguments.
ArityForArgc(int parameters)1383   static constexpr int ArityForArgc(int parameters) {
1384     return parameters + kExtraInputCount;
1385   }
1386 
FirstArgumentIndex()1387   static constexpr int FirstArgumentIndex() {
1388     return ReceiverOrNewTargetIndex() + 1;
1389   }
ArgumentIndex(int i)1390   static constexpr int ArgumentIndex(int i) { return FirstArgumentIndex() + i; }
1391 
Argument(int i)1392   TNode<Object> Argument(int i) const {
1393     DCHECK_LT(i, ArgumentCount());
1394     return TNode<Object>::UncheckedCast(
1395         NodeProperties::GetValueInput(node(), ArgumentIndex(i)));
1396   }
LastArgumentIndex()1397   int LastArgumentIndex() const {
1398     DCHECK_GT(ArgumentCount(), 0);
1399     return ArgumentIndex(ArgumentCount() - 1);
1400   }
LastArgument()1401   TNode<Object> LastArgument() const {
1402     DCHECK_GT(ArgumentCount(), 0);
1403     return Argument(ArgumentCount() - 1);
1404   }
ArgumentOr(int i,Node * default_value)1405   TNode<Object> ArgumentOr(int i, Node* default_value) const {
1406     return i < ArgumentCount() ? Argument(i)
1407                                : TNode<Object>::UncheckedCast(default_value);
1408   }
ArgumentOrUndefined(int i,JSGraph * jsgraph)1409   TNode<Object> ArgumentOrUndefined(int i, JSGraph* jsgraph) const {
1410     return ArgumentOr(i, js_node_wrapper_utils::UndefinedConstant(jsgraph));
1411   }
1412   virtual int ArgumentCount() const = 0;
1413 
FeedbackVectorIndexForArgc(int argc)1414   static constexpr int FeedbackVectorIndexForArgc(int argc) {
1415     STATIC_ASSERT(kFeedbackVectorIsLastInput);
1416     return ArgumentIndex(argc - 1) + 1;
1417   }
FeedbackVectorIndex()1418   int FeedbackVectorIndex() const {
1419     return FeedbackVectorIndexForArgc(ArgumentCount());
1420   }
feedback_vector()1421   TNode<HeapObject> feedback_vector() const {
1422     return TNode<HeapObject>::UncheckedCast(
1423         NodeProperties::GetValueInput(node(), FeedbackVectorIndex()));
1424   }
1425 
1426  private:
IsValidNode(Node * node)1427   static constexpr bool IsValidNode(Node* node) {
1428     return node->opcode() == IrOpcode::kJSCall ||
1429            node->opcode() == IrOpcode::kJSCallWithArrayLike ||
1430            node->opcode() == IrOpcode::kJSCallWithSpread ||
1431            node->opcode() == IrOpcode::kJSConstruct ||
1432            node->opcode() == IrOpcode::kJSConstructWithArrayLike ||
1433            node->opcode() == IrOpcode::kJSConstructWithSpread
1434 #if V8_ENABLE_WEBASSEMBLY
1435            || node->opcode() == IrOpcode::kJSWasmCall
1436 #endif     // V8_ENABLE_WEBASSEMBLY
1437         ;  // NOLINT(whitespace/semicolon)
1438   }
1439 };
1440 
1441 template <int kOpcode>
IsExpectedOpcode(int opcode)1442 bool IsExpectedOpcode(int opcode) {
1443   return opcode == kOpcode;
1444 }
1445 
1446 template <int kOpcode1, int kOpcode2, int... kOpcodes>
IsExpectedOpcode(int opcode)1447 bool IsExpectedOpcode(int opcode) {
1448   return opcode == kOpcode1 || IsExpectedOpcode<kOpcode2, kOpcodes...>(opcode);
1449 }
1450 
1451 template <int... kOpcodes>
1452 class JSCallNodeBase final : public JSCallOrConstructNode {
1453  public:
JSCallNodeBase(Node * node)1454   explicit constexpr JSCallNodeBase(Node* node) : JSCallOrConstructNode(node) {
1455     DCHECK(IsExpectedOpcode<kOpcodes...>(node->opcode()));
1456   }
1457 
Parameters()1458   const CallParameters& Parameters() const {
1459     return CallParametersOf(node()->op());
1460   }
1461 
1462 #define INPUTS(V)              \
1463   V(Target, target, 0, Object) \
1464   V(Receiver, receiver, 1, Object)
1465   INPUTS(DEFINE_INPUT_ACCESSORS)
1466 #undef INPUTS
1467 
1468   static constexpr int kReceiverInputCount = 1;
1469   STATIC_ASSERT(kReceiverInputCount ==
1470                 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1471 
ArgumentCount()1472   int ArgumentCount() const override {
1473     // Note: The count reported by this function depends only on the parameter,
1474     // thus adding/removing inputs will not affect it.
1475     return Parameters().arity_without_implicit_args();
1476   }
1477 };
1478 
1479 using JSCallNode = JSCallNodeBase<IrOpcode::kJSCall>;
1480 using JSCallWithSpreadNode = JSCallNodeBase<IrOpcode::kJSCallWithSpread>;
1481 using JSCallWithArrayLikeNode = JSCallNodeBase<IrOpcode::kJSCallWithArrayLike>;
1482 using JSCallWithArrayLikeOrSpreadNode =
1483     JSCallNodeBase<IrOpcode::kJSCallWithArrayLike, IrOpcode::kJSCallWithSpread>;
1484 
1485 #if V8_ENABLE_WEBASSEMBLY
1486 class JSWasmCallNode final : public JSCallOrConstructNode {
1487  public:
JSWasmCallNode(Node * node)1488   explicit constexpr JSWasmCallNode(Node* node) : JSCallOrConstructNode(node) {
1489     DCHECK_EQ(IrOpcode::kJSWasmCall, node->opcode());
1490   }
1491 
Parameters()1492   const JSWasmCallParameters& Parameters() const {
1493     return OpParameter<JSWasmCallParameters>(node()->op());
1494   }
1495 
1496 #define INPUTS(V)              \
1497   V(Target, target, 0, Object) \
1498   V(Receiver, receiver, 1, Object)
1499   INPUTS(DEFINE_INPUT_ACCESSORS)
1500 #undef INPUTS
1501 
1502   static constexpr int kReceiverInputCount = 1;
1503   STATIC_ASSERT(kReceiverInputCount ==
1504                 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1505 
ArgumentCount()1506   int ArgumentCount() const override {
1507     // Note: The count reported by this function depends only on the parameter
1508     // count, thus adding/removing inputs will not affect it.
1509     return Parameters().arity_without_implicit_args();
1510   }
1511 
1512   static Type TypeForWasmReturnType(const wasm::ValueType& type);
1513 };
1514 #endif  // V8_ENABLE_WEBASSEMBLY
1515 
1516 template <int kOpcode>
1517 class JSConstructNodeBase final : public JSCallOrConstructNode {
1518  public:
JSConstructNodeBase(Node * node)1519   explicit constexpr JSConstructNodeBase(Node* node)
1520       : JSCallOrConstructNode(node) {
1521     DCHECK_EQ(kOpcode, node->opcode());
1522   }
1523 
Parameters()1524   const ConstructParameters& Parameters() const {
1525     return ConstructParametersOf(node()->op());
1526   }
1527 
1528 #define INPUTS(V)              \
1529   V(Target, target, 0, Object) \
1530   V(NewTarget, new_target, 1, Object)
1531   INPUTS(DEFINE_INPUT_ACCESSORS)
1532 #undef INPUTS
1533 
1534   static constexpr int kNewTargetInputCount = 1;
1535   STATIC_ASSERT(kNewTargetInputCount ==
1536                 JSCallOrConstructNode::kReceiverOrNewTargetInputCount);
1537 
ArgumentCount()1538   int ArgumentCount() const {
1539     // Note: The count reported by this function depends only on the parameter,
1540     // thus adding/removing inputs will not affect it.
1541     return Parameters().arity_without_implicit_args();
1542   }
1543 };
1544 
1545 using JSConstructNode = JSConstructNodeBase<IrOpcode::kJSConstruct>;
1546 using JSConstructWithSpreadNode =
1547     JSConstructNodeBase<IrOpcode::kJSConstructWithSpread>;
1548 using JSConstructWithArrayLikeNode =
1549     JSConstructNodeBase<IrOpcode::kJSConstructWithArrayLike>;
1550 
1551 class JSLoadNamedNode final : public JSNodeWrapperBase {
1552  public:
JSLoadNamedNode(Node * node)1553   explicit constexpr JSLoadNamedNode(Node* node) : JSNodeWrapperBase(node) {
1554     DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
1555   }
1556 
Parameters()1557   const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1558 
1559 #define INPUTS(V)              \
1560   V(Object, object, 0, Object) \
1561   V(FeedbackVector, feedback_vector, 1, HeapObject)
1562   INPUTS(DEFINE_INPUT_ACCESSORS)
1563 #undef INPUTS
1564 };
1565 
1566 class JSLoadNamedFromSuperNode final : public JSNodeWrapperBase {
1567  public:
JSLoadNamedFromSuperNode(Node * node)1568   explicit constexpr JSLoadNamedFromSuperNode(Node* node)
1569       : JSNodeWrapperBase(node) {
1570     DCHECK_EQ(IrOpcode::kJSLoadNamedFromSuper, node->opcode());
1571   }
1572 
Parameters()1573   const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1574 
1575 #define INPUTS(V)                       \
1576   V(Receiver, receiver, 0, Object)      \
1577   V(HomeObject, home_object, 1, Object) \
1578   V(FeedbackVector, feedback_vector, 2, HeapObject)
1579   INPUTS(DEFINE_INPUT_ACCESSORS)
1580 #undef INPUTS
1581 };
1582 
1583 class JSSetNamedPropertyNode final : public JSNodeWrapperBase {
1584  public:
JSSetNamedPropertyNode(Node * node)1585   explicit constexpr JSSetNamedPropertyNode(Node* node)
1586       : JSNodeWrapperBase(node) {
1587     DCHECK_EQ(IrOpcode::kJSSetNamedProperty, node->opcode());
1588   }
1589 
Parameters()1590   const NamedAccess& Parameters() const { return NamedAccessOf(node()->op()); }
1591 
1592 #define INPUTS(V)              \
1593   V(Object, object, 0, Object) \
1594   V(Value, value, 1, Object)   \
1595   V(FeedbackVector, feedback_vector, 2, HeapObject)
1596   INPUTS(DEFINE_INPUT_ACCESSORS)
1597 #undef INPUTS
1598 };
1599 
1600 class JSDefineNamedOwnPropertyNode final : public JSNodeWrapperBase {
1601  public:
JSDefineNamedOwnPropertyNode(Node * node)1602   explicit constexpr JSDefineNamedOwnPropertyNode(Node* node)
1603       : JSNodeWrapperBase(node) {
1604     DCHECK_EQ(IrOpcode::kJSDefineNamedOwnProperty, node->opcode());
1605   }
1606 
Parameters()1607   const DefineNamedOwnPropertyParameters& Parameters() const {
1608     return DefineNamedOwnPropertyParametersOf(node()->op());
1609   }
1610 
1611 #define INPUTS(V)              \
1612   V(Object, object, 0, Object) \
1613   V(Value, value, 1, Object)   \
1614   V(FeedbackVector, feedback_vector, 2, HeapObject)
1615   INPUTS(DEFINE_INPUT_ACCESSORS)
1616 #undef INPUTS
1617 };
1618 
1619 class JSStoreGlobalNode final : public JSNodeWrapperBase {
1620  public:
JSStoreGlobalNode(Node * node)1621   explicit constexpr JSStoreGlobalNode(Node* node) : JSNodeWrapperBase(node) {
1622     DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
1623   }
1624 
Parameters()1625   const StoreGlobalParameters& Parameters() const {
1626     return StoreGlobalParametersOf(node()->op());
1627   }
1628 
1629 #define INPUTS(V)            \
1630   V(Value, value, 0, Object) \
1631   V(FeedbackVector, feedback_vector, 1, HeapObject)
1632   INPUTS(DEFINE_INPUT_ACCESSORS)
1633 #undef INPUTS
1634 };
1635 
1636 class JSLoadGlobalNode final : public JSNodeWrapperBase {
1637  public:
JSLoadGlobalNode(Node * node)1638   explicit constexpr JSLoadGlobalNode(Node* node) : JSNodeWrapperBase(node) {
1639     DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
1640   }
1641 
Parameters()1642   const LoadGlobalParameters& Parameters() const {
1643     return LoadGlobalParametersOf(node()->op());
1644   }
1645 
1646 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1647   INPUTS(DEFINE_INPUT_ACCESSORS)
1648 #undef INPUTS
1649 };
1650 
1651 class JSCreateEmptyLiteralArrayNode final : public JSNodeWrapperBase {
1652  public:
JSCreateEmptyLiteralArrayNode(Node * node)1653   explicit constexpr JSCreateEmptyLiteralArrayNode(Node* node)
1654       : JSNodeWrapperBase(node) {
1655     DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
1656   }
1657 
Parameters()1658   const FeedbackParameter& Parameters() const {
1659     return FeedbackParameterOf(node()->op());
1660   }
1661 
1662 #define INPUTS(V) V(FeedbackVector, feedback_vector, 0, HeapObject)
1663   INPUTS(DEFINE_INPUT_ACCESSORS)
1664 #undef INPUTS
1665 };
1666 
1667 class JSDefineKeyedOwnPropertyInLiteralNode final : public JSNodeWrapperBase {
1668  public:
JSDefineKeyedOwnPropertyInLiteralNode(Node * node)1669   explicit constexpr JSDefineKeyedOwnPropertyInLiteralNode(Node* node)
1670       : JSNodeWrapperBase(node) {
1671     DCHECK_EQ(IrOpcode::kJSDefineKeyedOwnPropertyInLiteral, node->opcode());
1672   }
1673 
Parameters()1674   const FeedbackParameter& Parameters() const {
1675     return FeedbackParameterOf(node()->op());
1676   }
1677 
1678 #define INPUTS(V)              \
1679   V(Object, object, 0, Object) \
1680   V(Name, name, 1, Object)     \
1681   V(Value, value, 2, Object)   \
1682   V(Flags, flags, 3, Object)   \
1683   V(FeedbackVector, feedback_vector, 4, HeapObject)
1684   INPUTS(DEFINE_INPUT_ACCESSORS)
1685 #undef INPUTS
1686 };
1687 
1688 class JSStoreInArrayLiteralNode final : public JSNodeWrapperBase {
1689  public:
JSStoreInArrayLiteralNode(Node * node)1690   explicit constexpr JSStoreInArrayLiteralNode(Node* node)
1691       : JSNodeWrapperBase(node) {
1692     DCHECK_EQ(IrOpcode::kJSStoreInArrayLiteral, node->opcode());
1693   }
1694 
Parameters()1695   const FeedbackParameter& Parameters() const {
1696     return FeedbackParameterOf(node()->op());
1697   }
1698 
1699 #define INPUTS(V)            \
1700   V(Array, array, 0, Object) \
1701   V(Index, index, 1, Object) \
1702   V(Value, value, 2, Object) \
1703   V(FeedbackVector, feedback_vector, 3, HeapObject)
1704   INPUTS(DEFINE_INPUT_ACCESSORS)
1705 #undef INPUTS
1706 };
1707 
1708 class JSCreateClosureNode final : public JSNodeWrapperBase {
1709  public:
JSCreateClosureNode(Node * node)1710   explicit constexpr JSCreateClosureNode(Node* node) : JSNodeWrapperBase(node) {
1711     DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
1712   }
1713 
Parameters()1714   const CreateClosureParameters& Parameters() const {
1715     return CreateClosureParametersOf(node()->op());
1716   }
1717 
1718 #define INPUTS(V) V(FeedbackCell, feedback_cell, 0, FeedbackCell)
1719   INPUTS(DEFINE_INPUT_ACCESSORS)
1720 #undef INPUTS
1721 
1722   FeedbackCellRef GetFeedbackCellRefChecked(JSHeapBroker* broker) const;
1723 };
1724 
1725 class JSForInPrepareNode final : public JSNodeWrapperBase {
1726  public:
JSForInPrepareNode(Node * node)1727   explicit constexpr JSForInPrepareNode(Node* node) : JSNodeWrapperBase(node) {
1728     DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode());
1729   }
1730 
Parameters()1731   const ForInParameters& Parameters() const {
1732     return ForInParametersOf(node()->op());
1733   }
1734 
1735 #define INPUTS(V)                      \
1736   V(Enumerator, enumerator, 0, Object) \
1737   V(FeedbackVector, feedback_vector, 1, HeapObject)
1738   INPUTS(DEFINE_INPUT_ACCESSORS)
1739 #undef INPUTS
1740 };
1741 
1742 class JSForInNextNode final : public JSNodeWrapperBase {
1743  public:
JSForInNextNode(Node * node)1744   explicit constexpr JSForInNextNode(Node* node) : JSNodeWrapperBase(node) {
1745     DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
1746   }
1747 
Parameters()1748   const ForInParameters& Parameters() const {
1749     return ForInParametersOf(node()->op());
1750   }
1751 
1752 #define INPUTS(V)                       \
1753   V(Receiver, receiver, 0, Object)      \
1754   V(CacheArray, cache_array, 1, Object) \
1755   V(CacheType, cache_type, 2, Object)   \
1756   V(Index, index, 3, Smi)               \
1757   V(FeedbackVector, feedback_vector, 4, HeapObject)
1758   INPUTS(DEFINE_INPUT_ACCESSORS)
1759 #undef INPUTS
1760 };
1761 
1762 #undef DEFINE_INPUT_ACCESSORS
1763 
1764 }  // namespace compiler
1765 }  // namespace internal
1766 }  // namespace v8
1767 
1768 #endif  // V8_COMPILER_JS_OPERATOR_H_
1769