Home | History | Annotate | Download | only in compiler
      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 #include "src/compiler/js-operator.h"
      6 
      7 #include <limits>
      8 
      9 #include "src/base/lazy-instance.h"
     10 #include "src/compiler/opcodes.h"
     11 #include "src/compiler/operator.h"
     12 #include "src/handles-inl.h"
     13 #include "src/objects-inl.h"
     14 #include "src/vector-slot-pair.h"
     15 
     16 namespace v8 {
     17 namespace internal {
     18 namespace compiler {
     19 
     20 std::ostream& operator<<(std::ostream& os, CallFrequency f) {
     21   if (f.IsUnknown()) return os << "unknown";
     22   return os << f.value();
     23 }
     24 
     25 CallFrequency CallFrequencyOf(Operator const* op) {
     26   DCHECK(op->opcode() == IrOpcode::kJSCallWithArrayLike ||
     27          op->opcode() == IrOpcode::kJSConstructWithArrayLike);
     28   return OpParameter<CallFrequency>(op);
     29 }
     30 
     31 
     32 std::ostream& operator<<(std::ostream& os,
     33                          ConstructForwardVarargsParameters const& p) {
     34   return os << p.arity() << ", " << p.start_index();
     35 }
     36 
     37 ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf(
     38     Operator const* op) {
     39   DCHECK_EQ(IrOpcode::kJSConstructForwardVarargs, op->opcode());
     40   return OpParameter<ConstructForwardVarargsParameters>(op);
     41 }
     42 
     43 bool operator==(ConstructParameters const& lhs,
     44                 ConstructParameters const& rhs) {
     45   return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() &&
     46          lhs.feedback() == rhs.feedback();
     47 }
     48 
     49 bool operator!=(ConstructParameters const& lhs,
     50                 ConstructParameters const& rhs) {
     51   return !(lhs == rhs);
     52 }
     53 
     54 size_t hash_value(ConstructParameters const& p) {
     55   return base::hash_combine(p.arity(), p.frequency(), p.feedback());
     56 }
     57 
     58 std::ostream& operator<<(std::ostream& os, ConstructParameters const& p) {
     59   return os << p.arity() << ", " << p.frequency();
     60 }
     61 
     62 ConstructParameters const& ConstructParametersOf(Operator const* op) {
     63   DCHECK(op->opcode() == IrOpcode::kJSConstruct ||
     64          op->opcode() == IrOpcode::kJSConstructWithSpread);
     65   return OpParameter<ConstructParameters>(op);
     66 }
     67 
     68 std::ostream& operator<<(std::ostream& os, CallParameters const& p) {
     69   return os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode();
     70 }
     71 
     72 const CallParameters& CallParametersOf(const Operator* op) {
     73   DCHECK(op->opcode() == IrOpcode::kJSCall ||
     74          op->opcode() == IrOpcode::kJSCallWithSpread);
     75   return OpParameter<CallParameters>(op);
     76 }
     77 
     78 std::ostream& operator<<(std::ostream& os,
     79                          CallForwardVarargsParameters const& p) {
     80   return os << p.arity() << ", " << p.start_index();
     81 }
     82 
     83 CallForwardVarargsParameters const& CallForwardVarargsParametersOf(
     84     Operator const* op) {
     85   DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, op->opcode());
     86   return OpParameter<CallForwardVarargsParameters>(op);
     87 }
     88 
     89 
     90 bool operator==(CallRuntimeParameters const& lhs,
     91                 CallRuntimeParameters const& rhs) {
     92   return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
     93 }
     94 
     95 
     96 bool operator!=(CallRuntimeParameters const& lhs,
     97                 CallRuntimeParameters const& rhs) {
     98   return !(lhs == rhs);
     99 }
    100 
    101 
    102 size_t hash_value(CallRuntimeParameters const& p) {
    103   return base::hash_combine(p.id(), p.arity());
    104 }
    105 
    106 
    107 std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
    108   return os << p.id() << ", " << p.arity();
    109 }
    110 
    111 
    112 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
    113   DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
    114   return OpParameter<CallRuntimeParameters>(op);
    115 }
    116 
    117 
    118 ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
    119     : immutable_(immutable),
    120       depth_(static_cast<uint16_t>(depth)),
    121       index_(static_cast<uint32_t>(index)) {
    122   DCHECK(depth <= std::numeric_limits<uint16_t>::max());
    123   DCHECK(index <= std::numeric_limits<uint32_t>::max());
    124 }
    125 
    126 
    127 bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
    128   return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
    129          lhs.immutable() == rhs.immutable();
    130 }
    131 
    132 
    133 bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
    134   return !(lhs == rhs);
    135 }
    136 
    137 
    138 size_t hash_value(ContextAccess const& access) {
    139   return base::hash_combine(access.depth(), access.index(), access.immutable());
    140 }
    141 
    142 
    143 std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
    144   return os << access.depth() << ", " << access.index() << ", "
    145             << access.immutable();
    146 }
    147 
    148 
    149 ContextAccess const& ContextAccessOf(Operator const* op) {
    150   DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
    151          op->opcode() == IrOpcode::kJSStoreContext);
    152   return OpParameter<ContextAccess>(op);
    153 }
    154 
    155 CreateFunctionContextParameters::CreateFunctionContextParameters(
    156     Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type)
    157     : scope_info_(scope_info),
    158       slot_count_(slot_count),
    159       scope_type_(scope_type) {}
    160 
    161 bool operator==(CreateFunctionContextParameters const& lhs,
    162                 CreateFunctionContextParameters const& rhs) {
    163   return lhs.scope_info().location() == rhs.scope_info().location() &&
    164          lhs.slot_count() == rhs.slot_count() &&
    165          lhs.scope_type() == rhs.scope_type();
    166 }
    167 
    168 bool operator!=(CreateFunctionContextParameters const& lhs,
    169                 CreateFunctionContextParameters const& rhs) {
    170   return !(lhs == rhs);
    171 }
    172 
    173 size_t hash_value(CreateFunctionContextParameters const& parameters) {
    174   return base::hash_combine(parameters.scope_info().location(),
    175                             parameters.slot_count(),
    176                             static_cast<int>(parameters.scope_type()));
    177 }
    178 
    179 std::ostream& operator<<(std::ostream& os,
    180                          CreateFunctionContextParameters const& parameters) {
    181   return os << parameters.slot_count() << ", " << parameters.scope_type();
    182 }
    183 
    184 CreateFunctionContextParameters const& CreateFunctionContextParametersOf(
    185     Operator const* op) {
    186   DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, op->opcode());
    187   return OpParameter<CreateFunctionContextParameters>(op);
    188 }
    189 
    190 bool operator==(StoreNamedOwnParameters const& lhs,
    191                 StoreNamedOwnParameters const& rhs) {
    192   return lhs.name().location() == rhs.name().location() &&
    193          lhs.feedback() == rhs.feedback();
    194 }
    195 
    196 bool operator!=(StoreNamedOwnParameters const& lhs,
    197                 StoreNamedOwnParameters const& rhs) {
    198   return !(lhs == rhs);
    199 }
    200 
    201 size_t hash_value(StoreNamedOwnParameters const& p) {
    202   return base::hash_combine(p.name().location(), p.feedback());
    203 }
    204 
    205 std::ostream& operator<<(std::ostream& os, StoreNamedOwnParameters const& p) {
    206   return os << Brief(*p.name());
    207 }
    208 
    209 StoreNamedOwnParameters const& StoreNamedOwnParametersOf(const Operator* op) {
    210   DCHECK_EQ(IrOpcode::kJSStoreNamedOwn, op->opcode());
    211   return OpParameter<StoreNamedOwnParameters>(op);
    212 }
    213 
    214 bool operator==(FeedbackParameter const& lhs, FeedbackParameter const& rhs) {
    215   return lhs.feedback() == rhs.feedback();
    216 }
    217 
    218 bool operator!=(FeedbackParameter const& lhs, FeedbackParameter const& rhs) {
    219   return !(lhs == rhs);
    220 }
    221 
    222 size_t hash_value(FeedbackParameter const& p) {
    223   return base::hash_combine(p.feedback());
    224 }
    225 
    226 std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
    227   return os;
    228 }
    229 
    230 FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
    231   DCHECK(op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
    232          op->opcode() == IrOpcode::kJSInstanceOf ||
    233          op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral ||
    234          op->opcode() == IrOpcode::kJSStoreInArrayLiteral);
    235   return OpParameter<FeedbackParameter>(op);
    236 }
    237 
    238 bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
    239   return lhs.name().location() == rhs.name().location() &&
    240          lhs.language_mode() == rhs.language_mode() &&
    241          lhs.feedback() == rhs.feedback();
    242 }
    243 
    244 
    245 bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
    246   return !(lhs == rhs);
    247 }
    248 
    249 
    250 size_t hash_value(NamedAccess const& p) {
    251   return base::hash_combine(p.name().location(), p.language_mode(),
    252                             p.feedback());
    253 }
    254 
    255 
    256 std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
    257   return os << Brief(*p.name()) << ", " << p.language_mode();
    258 }
    259 
    260 
    261 NamedAccess const& NamedAccessOf(const Operator* op) {
    262   DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
    263          op->opcode() == IrOpcode::kJSStoreNamed);
    264   return OpParameter<NamedAccess>(op);
    265 }
    266 
    267 
    268 std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
    269   return os << p.language_mode();
    270 }
    271 
    272 
    273 bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
    274   return lhs.language_mode() == rhs.language_mode() &&
    275          lhs.feedback() == rhs.feedback();
    276 }
    277 
    278 
    279 bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
    280   return !(lhs == rhs);
    281 }
    282 
    283 
    284 PropertyAccess const& PropertyAccessOf(const Operator* op) {
    285   DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
    286          op->opcode() == IrOpcode::kJSStoreProperty);
    287   return OpParameter<PropertyAccess>(op);
    288 }
    289 
    290 
    291 size_t hash_value(PropertyAccess const& p) {
    292   return base::hash_combine(p.language_mode(), p.feedback());
    293 }
    294 
    295 
    296 bool operator==(LoadGlobalParameters const& lhs,
    297                 LoadGlobalParameters const& rhs) {
    298   return lhs.name().location() == rhs.name().location() &&
    299          lhs.feedback() == rhs.feedback() &&
    300          lhs.typeof_mode() == rhs.typeof_mode();
    301 }
    302 
    303 
    304 bool operator!=(LoadGlobalParameters const& lhs,
    305                 LoadGlobalParameters const& rhs) {
    306   return !(lhs == rhs);
    307 }
    308 
    309 
    310 size_t hash_value(LoadGlobalParameters const& p) {
    311   return base::hash_combine(p.name().location(), p.typeof_mode());
    312 }
    313 
    314 
    315 std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
    316   return os << Brief(*p.name()) << ", " << p.typeof_mode();
    317 }
    318 
    319 
    320 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
    321   DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
    322   return OpParameter<LoadGlobalParameters>(op);
    323 }
    324 
    325 
    326 bool operator==(StoreGlobalParameters const& lhs,
    327                 StoreGlobalParameters const& rhs) {
    328   return lhs.language_mode() == rhs.language_mode() &&
    329          lhs.name().location() == rhs.name().location() &&
    330          lhs.feedback() == rhs.feedback();
    331 }
    332 
    333 
    334 bool operator!=(StoreGlobalParameters const& lhs,
    335                 StoreGlobalParameters const& rhs) {
    336   return !(lhs == rhs);
    337 }
    338 
    339 
    340 size_t hash_value(StoreGlobalParameters const& p) {
    341   return base::hash_combine(p.language_mode(), p.name().location(),
    342                             p.feedback());
    343 }
    344 
    345 
    346 std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
    347   return os << p.language_mode() << ", " << Brief(*p.name());
    348 }
    349 
    350 
    351 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
    352   DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
    353   return OpParameter<StoreGlobalParameters>(op);
    354 }
    355 
    356 
    357 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) {
    358   DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
    359   return OpParameter<CreateArgumentsType>(op);
    360 }
    361 
    362 
    363 bool operator==(CreateArrayParameters const& lhs,
    364                 CreateArrayParameters const& rhs) {
    365   return lhs.arity() == rhs.arity() &&
    366          lhs.site().address() == rhs.site().address();
    367 }
    368 
    369 
    370 bool operator!=(CreateArrayParameters const& lhs,
    371                 CreateArrayParameters const& rhs) {
    372   return !(lhs == rhs);
    373 }
    374 
    375 
    376 size_t hash_value(CreateArrayParameters const& p) {
    377   return base::hash_combine(p.arity(), p.site().address());
    378 }
    379 
    380 
    381 std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
    382   os << p.arity();
    383   Handle<AllocationSite> site;
    384   if (p.site().ToHandle(&site)) os << ", " << Brief(*site);
    385   return os;
    386 }
    387 
    388 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
    389   DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
    390   return OpParameter<CreateArrayParameters>(op);
    391 }
    392 
    393 bool operator==(CreateArrayIteratorParameters const& lhs,
    394                 CreateArrayIteratorParameters const& rhs) {
    395   return lhs.kind() == rhs.kind();
    396 }
    397 
    398 bool operator!=(CreateArrayIteratorParameters const& lhs,
    399                 CreateArrayIteratorParameters const& rhs) {
    400   return !(lhs == rhs);
    401 }
    402 
    403 size_t hash_value(CreateArrayIteratorParameters const& p) {
    404   return static_cast<size_t>(p.kind());
    405 }
    406 
    407 std::ostream& operator<<(std::ostream& os,
    408                          CreateArrayIteratorParameters const& p) {
    409   return os << p.kind();
    410 }
    411 
    412 const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf(
    413     const Operator* op) {
    414   DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, op->opcode());
    415   return OpParameter<CreateArrayIteratorParameters>(op);
    416 }
    417 
    418 bool operator==(CreateCollectionIteratorParameters const& lhs,
    419                 CreateCollectionIteratorParameters const& rhs) {
    420   return lhs.collection_kind() == rhs.collection_kind() &&
    421          lhs.iteration_kind() == rhs.iteration_kind();
    422 }
    423 
    424 bool operator!=(CreateCollectionIteratorParameters const& lhs,
    425                 CreateCollectionIteratorParameters const& rhs) {
    426   return !(lhs == rhs);
    427 }
    428 
    429 size_t hash_value(CreateCollectionIteratorParameters const& p) {
    430   return base::hash_combine(static_cast<size_t>(p.collection_kind()),
    431                             static_cast<size_t>(p.iteration_kind()));
    432 }
    433 
    434 std::ostream& operator<<(std::ostream& os,
    435                          CreateCollectionIteratorParameters const& p) {
    436   return os << p.collection_kind() << " " << p.iteration_kind();
    437 }
    438 
    439 const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf(
    440     const Operator* op) {
    441   DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, op->opcode());
    442   return OpParameter<CreateCollectionIteratorParameters>(op);
    443 }
    444 
    445 bool operator==(CreateBoundFunctionParameters const& lhs,
    446                 CreateBoundFunctionParameters const& rhs) {
    447   return lhs.arity() == rhs.arity() &&
    448          lhs.map().location() == rhs.map().location();
    449 }
    450 
    451 bool operator!=(CreateBoundFunctionParameters const& lhs,
    452                 CreateBoundFunctionParameters const& rhs) {
    453   return !(lhs == rhs);
    454 }
    455 
    456 size_t hash_value(CreateBoundFunctionParameters const& p) {
    457   return base::hash_combine(p.arity(), p.map().location());
    458 }
    459 
    460 std::ostream& operator<<(std::ostream& os,
    461                          CreateBoundFunctionParameters const& p) {
    462   os << p.arity();
    463   if (!p.map().is_null()) os << ", " << Brief(*p.map());
    464   return os;
    465 }
    466 
    467 const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf(
    468     const Operator* op) {
    469   DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, op->opcode());
    470   return OpParameter<CreateBoundFunctionParameters>(op);
    471 }
    472 
    473 bool operator==(CreateClosureParameters const& lhs,
    474                 CreateClosureParameters const& rhs) {
    475   return lhs.pretenure() == rhs.pretenure() &&
    476          lhs.code().location() == rhs.code().location() &&
    477          lhs.feedback_cell().location() == rhs.feedback_cell().location() &&
    478          lhs.shared_info().location() == rhs.shared_info().location();
    479 }
    480 
    481 
    482 bool operator!=(CreateClosureParameters const& lhs,
    483                 CreateClosureParameters const& rhs) {
    484   return !(lhs == rhs);
    485 }
    486 
    487 
    488 size_t hash_value(CreateClosureParameters const& p) {
    489   return base::hash_combine(p.pretenure(), p.shared_info().location(),
    490                             p.feedback_cell().location());
    491 }
    492 
    493 
    494 std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
    495   return os << p.pretenure() << ", " << Brief(*p.shared_info()) << ", "
    496             << Brief(*p.feedback_cell()) << ", " << Brief(*p.code());
    497 }
    498 
    499 
    500 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
    501   DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
    502   return OpParameter<CreateClosureParameters>(op);
    503 }
    504 
    505 
    506 bool operator==(CreateLiteralParameters const& lhs,
    507                 CreateLiteralParameters const& rhs) {
    508   return lhs.constant().location() == rhs.constant().location() &&
    509          lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() &&
    510          lhs.flags() == rhs.flags();
    511 }
    512 
    513 
    514 bool operator!=(CreateLiteralParameters const& lhs,
    515                 CreateLiteralParameters const& rhs) {
    516   return !(lhs == rhs);
    517 }
    518 
    519 
    520 size_t hash_value(CreateLiteralParameters const& p) {
    521   return base::hash_combine(p.constant().location(), p.feedback(), p.length(),
    522                             p.flags());
    523 }
    524 
    525 
    526 std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
    527   return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags();
    528 }
    529 
    530 
    531 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
    532   DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
    533          op->opcode() == IrOpcode::kJSCreateLiteralObject ||
    534          op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
    535   return OpParameter<CreateLiteralParameters>(op);
    536 }
    537 
    538 bool operator==(CloneObjectParameters const& lhs,
    539                 CloneObjectParameters const& rhs) {
    540   return lhs.feedback() == rhs.feedback() && lhs.flags() == rhs.flags();
    541 }
    542 
    543 bool operator!=(CloneObjectParameters const& lhs,
    544                 CloneObjectParameters const& rhs) {
    545   return !(lhs == rhs);
    546 }
    547 
    548 size_t hash_value(CloneObjectParameters const& p) {
    549   return base::hash_combine(p.feedback(), p.flags());
    550 }
    551 
    552 std::ostream& operator<<(std::ostream& os, CloneObjectParameters const& p) {
    553   return os << p.flags();
    554 }
    555 
    556 const CloneObjectParameters& CloneObjectParametersOf(const Operator* op) {
    557   DCHECK(op->opcode() == IrOpcode::kJSCloneObject);
    558   return OpParameter<CloneObjectParameters>(op);
    559 }
    560 
    561 size_t hash_value(ForInMode mode) { return static_cast<uint8_t>(mode); }
    562 
    563 std::ostream& operator<<(std::ostream& os, ForInMode mode) {
    564   switch (mode) {
    565     case ForInMode::kUseEnumCacheKeysAndIndices:
    566       return os << "UseEnumCacheKeysAndIndices";
    567     case ForInMode::kUseEnumCacheKeys:
    568       return os << "UseEnumCacheKeys";
    569     case ForInMode::kGeneric:
    570       return os << "Generic";
    571   }
    572   UNREACHABLE();
    573 }
    574 
    575 ForInMode ForInModeOf(Operator const* op) {
    576   DCHECK(op->opcode() == IrOpcode::kJSForInNext ||
    577          op->opcode() == IrOpcode::kJSForInPrepare);
    578   return OpParameter<ForInMode>(op);
    579 }
    580 
    581 BinaryOperationHint BinaryOperationHintOf(const Operator* op) {
    582   DCHECK_EQ(IrOpcode::kJSAdd, op->opcode());
    583   return OpParameter<BinaryOperationHint>(op);
    584 }
    585 
    586 CompareOperationHint CompareOperationHintOf(const Operator* op) {
    587   DCHECK(op->opcode() == IrOpcode::kJSEqual ||
    588          op->opcode() == IrOpcode::kJSStrictEqual ||
    589          op->opcode() == IrOpcode::kJSLessThan ||
    590          op->opcode() == IrOpcode::kJSGreaterThan ||
    591          op->opcode() == IrOpcode::kJSLessThanOrEqual ||
    592          op->opcode() == IrOpcode::kJSGreaterThanOrEqual);
    593   return OpParameter<CompareOperationHint>(op);
    594 }
    595 
    596 #define CACHED_OP_LIST(V)                                              \
    597   V(BitwiseOr, Operator::kNoProperties, 2, 1)                          \
    598   V(BitwiseXor, Operator::kNoProperties, 2, 1)                         \
    599   V(BitwiseAnd, Operator::kNoProperties, 2, 1)                         \
    600   V(ShiftLeft, Operator::kNoProperties, 2, 1)                          \
    601   V(ShiftRight, Operator::kNoProperties, 2, 1)                         \
    602   V(ShiftRightLogical, Operator::kNoProperties, 2, 1)                  \
    603   V(Subtract, Operator::kNoProperties, 2, 1)                           \
    604   V(Multiply, Operator::kNoProperties, 2, 1)                           \
    605   V(Divide, Operator::kNoProperties, 2, 1)                             \
    606   V(Modulus, Operator::kNoProperties, 2, 1)                            \
    607   V(Exponentiate, Operator::kNoProperties, 2, 1)                       \
    608   V(BitwiseNot, Operator::kNoProperties, 1, 1)                         \
    609   V(Decrement, Operator::kNoProperties, 1, 1)                          \
    610   V(Increment, Operator::kNoProperties, 1, 1)                          \
    611   V(Negate, Operator::kNoProperties, 1, 1)                             \
    612   V(ToInteger, Operator::kNoProperties, 1, 1)                          \
    613   V(ToLength, Operator::kNoProperties, 1, 1)                           \
    614   V(ToName, Operator::kNoProperties, 1, 1)                             \
    615   V(ToNumber, Operator::kNoProperties, 1, 1)                           \
    616   V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1)              \
    617   V(ToNumeric, Operator::kNoProperties, 1, 1)                          \
    618   V(ToObject, Operator::kFoldable, 1, 1)                               \
    619   V(ToString, Operator::kNoProperties, 1, 1)                           \
    620   V(Create, Operator::kNoProperties, 2, 1)                             \
    621   V(CreateIterResultObject, Operator::kEliminatable, 2, 1)             \
    622   V(CreateStringIterator, Operator::kEliminatable, 1, 1)               \
    623   V(CreateKeyValueArray, Operator::kEliminatable, 2, 1)                \
    624   V(CreatePromise, Operator::kEliminatable, 0, 1)                      \
    625   V(CreateTypedArray, Operator::kNoProperties, 5, 1)                   \
    626   V(CreateObject, Operator::kNoProperties, 1, 1)                       \
    627   V(ObjectIsArray, Operator::kNoProperties, 1, 1)                      \
    628   V(HasProperty, Operator::kNoProperties, 2, 1)                        \
    629   V(HasInPrototypeChain, Operator::kNoProperties, 2, 1)                \
    630   V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1)                \
    631   V(ForInEnumerate, Operator::kNoProperties, 1, 1)                     \
    632   V(LoadMessage, Operator::kNoThrow | Operator::kNoWrite, 0, 1)        \
    633   V(StoreMessage, Operator::kNoRead | Operator::kNoThrow, 1, 0)        \
    634   V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1)            \
    635   V(GeneratorRestoreContext, Operator::kNoThrow, 1, 1)                 \
    636   V(GeneratorRestoreInputOrDebugPos, Operator::kNoThrow, 1, 1)         \
    637   V(StackCheck, Operator::kNoWrite, 0, 0)                              \
    638   V(Debugger, Operator::kNoProperties, 0, 0)                           \
    639   V(FulfillPromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1)     \
    640   V(PerformPromiseThen, Operator::kNoDeopt | Operator::kNoThrow, 4, 1) \
    641   V(PromiseResolve, Operator::kNoProperties, 2, 1)                     \
    642   V(RejectPromise, Operator::kNoDeopt | Operator::kNoThrow, 3, 1)      \
    643   V(ResolvePromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1)     \
    644   V(GetSuperConstructor, Operator::kNoWrite, 1, 1)                     \
    645   V(ParseInt, Operator::kNoProperties, 2, 1)                           \
    646   V(RegExpTest, Operator::kNoProperties, 2, 1)
    647 
    648 #define BINARY_OP_LIST(V) V(Add)
    649 
    650 #define COMPARE_OP_LIST(V)                    \
    651   V(Equal, Operator::kNoProperties)           \
    652   V(StrictEqual, Operator::kPure)             \
    653   V(LessThan, Operator::kNoProperties)        \
    654   V(GreaterThan, Operator::kNoProperties)     \
    655   V(LessThanOrEqual, Operator::kNoProperties) \
    656   V(GreaterThanOrEqual, Operator::kNoProperties)
    657 
    658 struct JSOperatorGlobalCache final {
    659 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \
    660   struct Name##Operator final : public Operator {                          \
    661     Name##Operator()                                                       \
    662         : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,            \
    663                    value_input_count, Operator::ZeroIfPure(properties),    \
    664                    Operator::ZeroIfEliminatable(properties),               \
    665                    value_output_count, Operator::ZeroIfPure(properties),   \
    666                    Operator::ZeroIfNoThrow(properties)) {}                 \
    667   };                                                                       \
    668   Name##Operator k##Name##Operator;
    669   CACHED_OP_LIST(CACHED_OP)
    670 #undef CACHED_OP
    671 
    672 #define BINARY_OP(Name)                                                       \
    673   template <BinaryOperationHint kHint>                                        \
    674   struct Name##Operator final : public Operator1<BinaryOperationHint> {       \
    675     Name##Operator()                                                          \
    676         : Operator1<BinaryOperationHint>(IrOpcode::kJS##Name,                 \
    677                                          Operator::kNoProperties, "JS" #Name, \
    678                                          2, 1, 1, 1, 1, 2, kHint) {}          \
    679   };                                                                          \
    680   Name##Operator<BinaryOperationHint::kNone> k##Name##NoneOperator;           \
    681   Name##Operator<BinaryOperationHint::kSignedSmall>                           \
    682       k##Name##SignedSmallOperator;                                           \
    683   Name##Operator<BinaryOperationHint::kSignedSmallInputs>                     \
    684       k##Name##SignedSmallInputsOperator;                                     \
    685   Name##Operator<BinaryOperationHint::kSigned32> k##Name##Signed32Operator;   \
    686   Name##Operator<BinaryOperationHint::kNumber> k##Name##NumberOperator;       \
    687   Name##Operator<BinaryOperationHint::kNumberOrOddball>                       \
    688       k##Name##NumberOrOddballOperator;                                       \
    689   Name##Operator<BinaryOperationHint::kString> k##Name##StringOperator;       \
    690   Name##Operator<BinaryOperationHint::kBigInt> k##Name##BigIntOperator;       \
    691   Name##Operator<BinaryOperationHint::kAny> k##Name##AnyOperator;
    692   BINARY_OP_LIST(BINARY_OP)
    693 #undef BINARY_OP
    694 
    695 #define COMPARE_OP(Name, properties)                                         \
    696   template <CompareOperationHint kHint>                                      \
    697   struct Name##Operator final : public Operator1<CompareOperationHint> {     \
    698     Name##Operator()                                                         \
    699         : Operator1<CompareOperationHint>(                                   \
    700               IrOpcode::kJS##Name, properties, "JS" #Name, 2, 1, 1, 1, 1,    \
    701               Operator::ZeroIfNoThrow(properties), kHint) {}                 \
    702   };                                                                         \
    703   Name##Operator<CompareOperationHint::kNone> k##Name##NoneOperator;         \
    704   Name##Operator<CompareOperationHint::kSignedSmall>                         \
    705       k##Name##SignedSmallOperator;                                          \
    706   Name##Operator<CompareOperationHint::kNumber> k##Name##NumberOperator;     \
    707   Name##Operator<CompareOperationHint::kNumberOrOddball>                     \
    708       k##Name##NumberOrOddballOperator;                                      \
    709   Name##Operator<CompareOperationHint::kInternalizedString>                  \
    710       k##Name##InternalizedStringOperator;                                   \
    711   Name##Operator<CompareOperationHint::kString> k##Name##StringOperator;     \
    712   Name##Operator<CompareOperationHint::kSymbol> k##Name##SymbolOperator;     \
    713   Name##Operator<CompareOperationHint::kBigInt> k##Name##BigIntOperator;     \
    714   Name##Operator<CompareOperationHint::kReceiver> k##Name##ReceiverOperator; \
    715   Name##Operator<CompareOperationHint::kAny> k##Name##AnyOperator;
    716   COMPARE_OP_LIST(COMPARE_OP)
    717 #undef COMPARE_OP
    718 };
    719 
    720 static base::LazyInstance<JSOperatorGlobalCache>::type kJSOperatorGlobalCache =
    721     LAZY_INSTANCE_INITIALIZER;
    722 
    723 JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
    724     : cache_(kJSOperatorGlobalCache.Get()), zone_(zone) {}
    725 
    726 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \
    727   const Operator* JSOperatorBuilder::Name() {                              \
    728     return &cache_.k##Name##Operator;                                      \
    729   }
    730 CACHED_OP_LIST(CACHED_OP)
    731 #undef CACHED_OP
    732 
    733 #define BINARY_OP(Name)                                               \
    734   const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \
    735     switch (hint) {                                                   \
    736       case BinaryOperationHint::kNone:                                \
    737         return &cache_.k##Name##NoneOperator;                         \
    738       case BinaryOperationHint::kSignedSmall:                         \
    739         return &cache_.k##Name##SignedSmallOperator;                  \
    740       case BinaryOperationHint::kSignedSmallInputs:                   \
    741         return &cache_.k##Name##SignedSmallInputsOperator;            \
    742       case BinaryOperationHint::kSigned32:                            \
    743         return &cache_.k##Name##Signed32Operator;                     \
    744       case BinaryOperationHint::kNumber:                              \
    745         return &cache_.k##Name##NumberOperator;                       \
    746       case BinaryOperationHint::kNumberOrOddball:                     \
    747         return &cache_.k##Name##NumberOrOddballOperator;              \
    748       case BinaryOperationHint::kString:                              \
    749         return &cache_.k##Name##StringOperator;                       \
    750       case BinaryOperationHint::kBigInt:                              \
    751         return &cache_.k##Name##BigIntOperator;                       \
    752       case BinaryOperationHint::kAny:                                 \
    753         return &cache_.k##Name##AnyOperator;                          \
    754     }                                                                 \
    755     UNREACHABLE();                                                    \
    756     return nullptr;                                                   \
    757   }
    758 BINARY_OP_LIST(BINARY_OP)
    759 #undef BINARY_OP
    760 
    761 #define COMPARE_OP(Name, ...)                                          \
    762   const Operator* JSOperatorBuilder::Name(CompareOperationHint hint) { \
    763     switch (hint) {                                                    \
    764       case CompareOperationHint::kNone:                                \
    765         return &cache_.k##Name##NoneOperator;                          \
    766       case CompareOperationHint::kSignedSmall:                         \
    767         return &cache_.k##Name##SignedSmallOperator;                   \
    768       case CompareOperationHint::kNumber:                              \
    769         return &cache_.k##Name##NumberOperator;                        \
    770       case CompareOperationHint::kNumberOrOddball:                     \
    771         return &cache_.k##Name##NumberOrOddballOperator;               \
    772       case CompareOperationHint::kInternalizedString:                  \
    773         return &cache_.k##Name##InternalizedStringOperator;            \
    774       case CompareOperationHint::kString:                              \
    775         return &cache_.k##Name##StringOperator;                        \
    776       case CompareOperationHint::kSymbol:                              \
    777         return &cache_.k##Name##SymbolOperator;                        \
    778       case CompareOperationHint::kBigInt:                              \
    779         return &cache_.k##Name##BigIntOperator;                        \
    780       case CompareOperationHint::kReceiver:                            \
    781         return &cache_.k##Name##ReceiverOperator;                      \
    782       case CompareOperationHint::kAny:                                 \
    783         return &cache_.k##Name##AnyOperator;                           \
    784     }                                                                  \
    785     UNREACHABLE();                                                     \
    786     return nullptr;                                                    \
    787   }
    788 COMPARE_OP_LIST(COMPARE_OP)
    789 #undef COMPARE_OP
    790 
    791 const Operator* JSOperatorBuilder::StoreDataPropertyInLiteral(
    792     const VectorSlotPair& feedback) {
    793   FeedbackParameter parameters(feedback);
    794   return new (zone()) Operator1<FeedbackParameter>(  // --
    795       IrOpcode::kJSStoreDataPropertyInLiteral,
    796       Operator::kNoThrow,              // opcode
    797       "JSStoreDataPropertyInLiteral",  // name
    798       4, 1, 1, 0, 1, 0,                // counts
    799       parameters);                     // parameter
    800 }
    801 
    802 const Operator* JSOperatorBuilder::StoreInArrayLiteral(
    803     const VectorSlotPair& feedback) {
    804   FeedbackParameter parameters(feedback);
    805   return new (zone()) Operator1<FeedbackParameter>(  // --
    806       IrOpcode::kJSStoreInArrayLiteral,
    807       Operator::kNoThrow,       // opcode
    808       "JSStoreInArrayLiteral",  // name
    809       3, 1, 1, 0, 1, 0,         // counts
    810       parameters);              // parameter
    811 }
    812 
    813 const Operator* JSOperatorBuilder::CallForwardVarargs(size_t arity,
    814                                                       uint32_t start_index) {
    815   CallForwardVarargsParameters parameters(arity, start_index);
    816   return new (zone()) Operator1<CallForwardVarargsParameters>(   // --
    817       IrOpcode::kJSCallForwardVarargs, Operator::kNoProperties,  // opcode
    818       "JSCallForwardVarargs",                                    // name
    819       parameters.arity(), 1, 1, 1, 1, 2,                         // counts
    820       parameters);                                               // parameter
    821 }
    822 
    823 const Operator* JSOperatorBuilder::Call(size_t arity,
    824                                         CallFrequency const& frequency,
    825                                         VectorSlotPair const& feedback,
    826                                         ConvertReceiverMode convert_mode,
    827                                         SpeculationMode speculation_mode) {
    828   DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
    829                  feedback.IsValid());
    830   CallParameters parameters(arity, frequency, feedback, convert_mode,
    831                             speculation_mode);
    832   return new (zone()) Operator1<CallParameters>(   // --
    833       IrOpcode::kJSCall, Operator::kNoProperties,  // opcode
    834       "JSCall",                                    // name
    835       parameters.arity(), 1, 1, 1, 1, 2,           // inputs/outputs
    836       parameters);                                 // parameter
    837 }
    838 
    839 const Operator* JSOperatorBuilder::CallWithArrayLike(CallFrequency frequency) {
    840   return new (zone()) Operator1<CallFrequency>(                 // --
    841       IrOpcode::kJSCallWithArrayLike, Operator::kNoProperties,  // opcode
    842       "JSCallWithArrayLike",                                    // name
    843       3, 1, 1, 1, 1, 2,                                         // counts
    844       frequency);                                               // parameter
    845 }
    846 
    847 const Operator* JSOperatorBuilder::CallWithSpread(
    848     uint32_t arity, CallFrequency const& frequency,
    849     VectorSlotPair const& feedback, SpeculationMode speculation_mode) {
    850   DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation,
    851                  feedback.IsValid());
    852   CallParameters parameters(arity, frequency, feedback,
    853                             ConvertReceiverMode::kAny, speculation_mode);
    854   return new (zone()) Operator1<CallParameters>(             // --
    855       IrOpcode::kJSCallWithSpread, Operator::kNoProperties,  // opcode
    856       "JSCallWithSpread",                                    // name
    857       parameters.arity(), 1, 1, 1, 1, 2,                     // counts
    858       parameters);                                           // parameter
    859 }
    860 
    861 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) {
    862   const Runtime::Function* f = Runtime::FunctionForId(id);
    863   return CallRuntime(f, f->nargs);
    864 }
    865 
    866 
    867 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
    868                                                size_t arity) {
    869   const Runtime::Function* f = Runtime::FunctionForId(id);
    870   return CallRuntime(f, arity);
    871 }
    872 
    873 
    874 const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f,
    875                                                size_t arity) {
    876   CallRuntimeParameters parameters(f->function_id, arity);
    877   DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
    878   return new (zone()) Operator1<CallRuntimeParameters>(   // --
    879       IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
    880       "JSCallRuntime",                                    // name
    881       parameters.arity(), 1, 1, f->result_size, 1, 2,     // inputs/outputs
    882       parameters);                                        // parameter
    883 }
    884 
    885 const Operator* JSOperatorBuilder::ConstructForwardVarargs(
    886     size_t arity, uint32_t start_index) {
    887   ConstructForwardVarargsParameters parameters(arity, start_index);
    888   return new (zone()) Operator1<ConstructForwardVarargsParameters>(   // --
    889       IrOpcode::kJSConstructForwardVarargs, Operator::kNoProperties,  // opcode
    890       "JSConstructForwardVarargs",                                    // name
    891       parameters.arity(), 1, 1, 1, 1, 2,                              // counts
    892       parameters);  // parameter
    893 }
    894 
    895 const Operator* JSOperatorBuilder::Construct(uint32_t arity,
    896                                              CallFrequency frequency,
    897                                              VectorSlotPair const& feedback) {
    898   ConstructParameters parameters(arity, frequency, feedback);
    899   return new (zone()) Operator1<ConstructParameters>(   // --
    900       IrOpcode::kJSConstruct, Operator::kNoProperties,  // opcode
    901       "JSConstruct",                                    // name
    902       parameters.arity(), 1, 1, 1, 1, 2,                // counts
    903       parameters);                                      // parameter
    904 }
    905 
    906 const Operator* JSOperatorBuilder::ConstructWithArrayLike(
    907     CallFrequency frequency) {
    908   return new (zone()) Operator1<CallFrequency>(  // --
    909       IrOpcode::kJSConstructWithArrayLike,       // opcode
    910       Operator::kNoProperties,                   // properties
    911       "JSConstructWithArrayLike",                // name
    912       3, 1, 1, 1, 1, 2,                          // counts
    913       frequency);                                // parameter
    914 }
    915 
    916 const Operator* JSOperatorBuilder::ConstructWithSpread(
    917     uint32_t arity, CallFrequency frequency, VectorSlotPair const& feedback) {
    918   ConstructParameters parameters(arity, frequency, feedback);
    919   return new (zone()) Operator1<ConstructParameters>(             // --
    920       IrOpcode::kJSConstructWithSpread, Operator::kNoProperties,  // opcode
    921       "JSConstructWithSpread",                                    // name
    922       parameters.arity(), 1, 1, 1, 1, 2,                          // counts
    923       parameters);                                                // parameter
    924 }
    925 
    926 const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name,
    927                                              const VectorSlotPair& feedback) {
    928   NamedAccess access(LanguageMode::kSloppy, name, feedback);
    929   return new (zone()) Operator1<NamedAccess>(           // --
    930       IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
    931       "JSLoadNamed",                                    // name
    932       1, 1, 1, 1, 1, 2,                                 // counts
    933       access);                                          // parameter
    934 }
    935 
    936 const Operator* JSOperatorBuilder::LoadProperty(
    937     VectorSlotPair const& feedback) {
    938   PropertyAccess access(LanguageMode::kSloppy, feedback);
    939   return new (zone()) Operator1<PropertyAccess>(           // --
    940       IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
    941       "JSLoadProperty",                                    // name
    942       2, 1, 1, 1, 1, 2,                                    // counts
    943       access);                                             // parameter
    944 }
    945 
    946 const Operator* JSOperatorBuilder::InstanceOf(VectorSlotPair const& feedback) {
    947   FeedbackParameter parameter(feedback);
    948   return new (zone()) Operator1<FeedbackParameter>(      // --
    949       IrOpcode::kJSInstanceOf, Operator::kNoProperties,  // opcode
    950       "JSInstanceOf",                                    // name
    951       2, 1, 1, 1, 1, 2,                                  // counts
    952       parameter);                                        // parameter
    953 }
    954 
    955 const Operator* JSOperatorBuilder::ForInNext(ForInMode mode) {
    956   return new (zone()) Operator1<ForInMode>(             // --
    957       IrOpcode::kJSForInNext, Operator::kNoProperties,  // opcode
    958       "JSForInNext",                                    // name
    959       4, 1, 1, 1, 1, 2,                                 // counts
    960       mode);                                            // parameter
    961 }
    962 
    963 const Operator* JSOperatorBuilder::ForInPrepare(ForInMode mode) {
    964   return new (zone()) Operator1<ForInMode>(     // --
    965       IrOpcode::kJSForInPrepare,                // opcode
    966       Operator::kNoWrite | Operator::kNoThrow,  // flags
    967       "JSForInPrepare",                         // name
    968       1, 1, 1, 3, 1, 1,                         // counts
    969       mode);                                    // parameter
    970 }
    971 
    972 const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
    973   return new (zone()) Operator1<int>(                   // --
    974       IrOpcode::kJSGeneratorStore, Operator::kNoThrow,  // opcode
    975       "JSGeneratorStore",                               // name
    976       3 + register_count, 1, 1, 0, 1, 0,                // counts
    977       register_count);                                  // parameter
    978 }
    979 
    980 int GeneratorStoreValueCountOf(const Operator* op) {
    981   DCHECK_EQ(IrOpcode::kJSGeneratorStore, op->opcode());
    982   return OpParameter<int>(op);
    983 }
    984 
    985 const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) {
    986   return new (zone()) Operator1<int>(                             // --
    987       IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow,  // opcode
    988       "JSGeneratorRestoreRegister",                               // name
    989       1, 1, 1, 1, 1, 0,                                           // counts
    990       index);                                                     // parameter
    991 }
    992 
    993 int RestoreRegisterIndexOf(const Operator* op) {
    994   DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, op->opcode());
    995   return OpParameter<int>(op);
    996 }
    997 
    998 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
    999                                               Handle<Name> name,
   1000                                               VectorSlotPair const& feedback) {
   1001   NamedAccess access(language_mode, name, feedback);
   1002   return new (zone()) Operator1<NamedAccess>(            // --
   1003       IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
   1004       "JSStoreNamed",                                    // name
   1005       2, 1, 1, 0, 1, 2,                                  // counts
   1006       access);                                           // parameter
   1007 }
   1008 
   1009 
   1010 const Operator* JSOperatorBuilder::StoreProperty(
   1011     LanguageMode language_mode, VectorSlotPair const& feedback) {
   1012   PropertyAccess access(language_mode, feedback);
   1013   return new (zone()) Operator1<PropertyAccess>(            // --
   1014       IrOpcode::kJSStoreProperty, Operator::kNoProperties,  // opcode
   1015       "JSStoreProperty",                                    // name
   1016       3, 1, 1, 0, 1, 2,                                     // counts
   1017       access);                                              // parameter
   1018 }
   1019 
   1020 const Operator* JSOperatorBuilder::StoreNamedOwn(
   1021     Handle<Name> name, VectorSlotPair const& feedback) {
   1022   StoreNamedOwnParameters parameters(name, feedback);
   1023   return new (zone()) Operator1<StoreNamedOwnParameters>(   // --
   1024       IrOpcode::kJSStoreNamedOwn, Operator::kNoProperties,  // opcode
   1025       "JSStoreNamedOwn",                                    // name
   1026       2, 1, 1, 0, 1, 2,                                     // counts
   1027       parameters);                                          // parameter
   1028 }
   1029 
   1030 const Operator* JSOperatorBuilder::DeleteProperty() {
   1031   return new (zone()) Operator(                              // --
   1032       IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
   1033       "JSDeleteProperty",                                    // name
   1034       3, 1, 1, 1, 1, 2);                                     // counts
   1035 }
   1036 
   1037 const Operator* JSOperatorBuilder::CreateGeneratorObject() {
   1038   return new (zone()) Operator(                                     // --
   1039       IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable,  // opcode
   1040       "JSCreateGeneratorObject",                                    // name
   1041       2, 1, 1, 1, 1, 0);                                            // counts
   1042 }
   1043 
   1044 const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
   1045                                               const VectorSlotPair& feedback,
   1046                                               TypeofMode typeof_mode) {
   1047   LoadGlobalParameters parameters(name, feedback, typeof_mode);
   1048   return new (zone()) Operator1<LoadGlobalParameters>(   // --
   1049       IrOpcode::kJSLoadGlobal, Operator::kNoProperties,  // opcode
   1050       "JSLoadGlobal",                                    // name
   1051       0, 1, 1, 1, 1, 2,                                  // counts
   1052       parameters);                                       // parameter
   1053 }
   1054 
   1055 
   1056 const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
   1057                                                const Handle<Name>& name,
   1058                                                const VectorSlotPair& feedback) {
   1059   StoreGlobalParameters parameters(language_mode, feedback, name);
   1060   return new (zone()) Operator1<StoreGlobalParameters>(   // --
   1061       IrOpcode::kJSStoreGlobal, Operator::kNoProperties,  // opcode
   1062       "JSStoreGlobal",                                    // name
   1063       1, 1, 1, 0, 1, 2,                                   // counts
   1064       parameters);                                        // parameter
   1065 }
   1066 
   1067 
   1068 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
   1069                                                bool immutable) {
   1070   ContextAccess access(depth, index, immutable);
   1071   return new (zone()) Operator1<ContextAccess>(  // --
   1072       IrOpcode::kJSLoadContext,                  // opcode
   1073       Operator::kNoWrite | Operator::kNoThrow,   // flags
   1074       "JSLoadContext",                           // name
   1075       0, 1, 0, 1, 1, 0,                          // counts
   1076       access);                                   // parameter
   1077 }
   1078 
   1079 
   1080 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
   1081   ContextAccess access(depth, index, false);
   1082   return new (zone()) Operator1<ContextAccess>(  // --
   1083       IrOpcode::kJSStoreContext,                 // opcode
   1084       Operator::kNoRead | Operator::kNoThrow,    // flags
   1085       "JSStoreContext",                          // name
   1086       1, 1, 1, 0, 1, 0,                          // counts
   1087       access);                                   // parameter
   1088 }
   1089 
   1090 const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) {
   1091   return new (zone()) Operator1<int32_t>(       // --
   1092       IrOpcode::kJSLoadModule,                  // opcode
   1093       Operator::kNoWrite | Operator::kNoThrow,  // flags
   1094       "JSLoadModule",                           // name
   1095       1, 1, 1, 1, 1, 0,                         // counts
   1096       cell_index);                              // parameter
   1097 }
   1098 
   1099 const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) {
   1100   return new (zone()) Operator1<int32_t>(      // --
   1101       IrOpcode::kJSStoreModule,                // opcode
   1102       Operator::kNoRead | Operator::kNoThrow,  // flags
   1103       "JSStoreModule",                         // name
   1104       2, 1, 1, 0, 1, 0,                        // counts
   1105       cell_index);                             // parameter
   1106 }
   1107 
   1108 const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
   1109   return new (zone()) Operator1<CreateArgumentsType>(         // --
   1110       IrOpcode::kJSCreateArguments, Operator::kEliminatable,  // opcode
   1111       "JSCreateArguments",                                    // name
   1112       1, 1, 0, 1, 1, 0,                                       // counts
   1113       type);                                                  // parameter
   1114 }
   1115 
   1116 const Operator* JSOperatorBuilder::CreateArray(
   1117     size_t arity, MaybeHandle<AllocationSite> site) {
   1118   // constructor, new_target, arg1, ..., argN
   1119   int const value_input_count = static_cast<int>(arity) + 2;
   1120   CreateArrayParameters parameters(arity, site);
   1121   return new (zone()) Operator1<CreateArrayParameters>(   // --
   1122       IrOpcode::kJSCreateArray, Operator::kNoProperties,  // opcode
   1123       "JSCreateArray",                                    // name
   1124       value_input_count, 1, 1, 1, 1, 2,                   // counts
   1125       parameters);                                        // parameter
   1126 }
   1127 
   1128 const Operator* JSOperatorBuilder::CreateArrayIterator(IterationKind kind) {
   1129   CreateArrayIteratorParameters parameters(kind);
   1130   return new (zone()) Operator1<CreateArrayIteratorParameters>(   // --
   1131       IrOpcode::kJSCreateArrayIterator, Operator::kEliminatable,  // opcode
   1132       "JSCreateArrayIterator",                                    // name
   1133       1, 1, 1, 1, 1, 0,                                           // counts
   1134       parameters);                                                // parameter
   1135 }
   1136 
   1137 const Operator* JSOperatorBuilder::CreateCollectionIterator(
   1138     CollectionKind collection_kind, IterationKind iteration_kind) {
   1139   CreateCollectionIteratorParameters parameters(collection_kind,
   1140                                                 iteration_kind);
   1141   return new (zone()) Operator1<CreateCollectionIteratorParameters>(
   1142       IrOpcode::kJSCreateCollectionIterator, Operator::kEliminatable,
   1143       "JSCreateCollectionIterator", 1, 1, 1, 1, 1, 0, parameters);
   1144 }
   1145 
   1146 const Operator* JSOperatorBuilder::CreateBoundFunction(size_t arity,
   1147                                                        Handle<Map> map) {
   1148   // bound_target_function, bound_this, arg1, ..., argN
   1149   int const value_input_count = static_cast<int>(arity) + 2;
   1150   CreateBoundFunctionParameters parameters(arity, map);
   1151   return new (zone()) Operator1<CreateBoundFunctionParameters>(   // --
   1152       IrOpcode::kJSCreateBoundFunction, Operator::kEliminatable,  // opcode
   1153       "JSCreateBoundFunction",                                    // name
   1154       value_input_count, 1, 1, 1, 1, 0,                           // counts
   1155       parameters);                                                // parameter
   1156 }
   1157 
   1158 const Operator* JSOperatorBuilder::CreateClosure(
   1159     Handle<SharedFunctionInfo> shared_info, Handle<FeedbackCell> feedback_cell,
   1160     Handle<Code> code, PretenureFlag pretenure) {
   1161   CreateClosureParameters parameters(shared_info, feedback_cell, code,
   1162                                      pretenure);
   1163   return new (zone()) Operator1<CreateClosureParameters>(   // --
   1164       IrOpcode::kJSCreateClosure, Operator::kEliminatable,  // opcode
   1165       "JSCreateClosure",                                    // name
   1166       0, 1, 1, 1, 1, 0,                                     // counts
   1167       parameters);                                          // parameter
   1168 }
   1169 
   1170 const Operator* JSOperatorBuilder::CreateLiteralArray(
   1171     Handle<ArrayBoilerplateDescription> description,
   1172     VectorSlotPair const& feedback, int literal_flags, int number_of_elements) {
   1173   CreateLiteralParameters parameters(description, feedback, number_of_elements,
   1174                                      literal_flags);
   1175   return new (zone()) Operator1<CreateLiteralParameters>(  // --
   1176       IrOpcode::kJSCreateLiteralArray,                     // opcode
   1177       Operator::kNoProperties,                             // properties
   1178       "JSCreateLiteralArray",                              // name
   1179       0, 1, 1, 1, 1, 2,                                    // counts
   1180       parameters);                                         // parameter
   1181 }
   1182 
   1183 const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
   1184     VectorSlotPair const& feedback) {
   1185   FeedbackParameter parameters(feedback);
   1186   return new (zone()) Operator1<FeedbackParameter>(  // --
   1187       IrOpcode::kJSCreateEmptyLiteralArray,          // opcode
   1188       Operator::kEliminatable,                       // properties
   1189       "JSCreateEmptyLiteralArray",                   // name
   1190       0, 1, 1, 1, 1, 0,                              // counts
   1191       parameters);                                   // parameter
   1192 }
   1193 
   1194 const Operator* JSOperatorBuilder::CreateLiteralObject(
   1195     Handle<ObjectBoilerplateDescription> constant_properties,
   1196     VectorSlotPair const& feedback, int literal_flags,
   1197     int number_of_properties) {
   1198   CreateLiteralParameters parameters(constant_properties, feedback,
   1199                                      number_of_properties, literal_flags);
   1200   return new (zone()) Operator1<CreateLiteralParameters>(  // --
   1201       IrOpcode::kJSCreateLiteralObject,                    // opcode
   1202       Operator::kNoProperties,                             // properties
   1203       "JSCreateLiteralObject",                             // name
   1204       0, 1, 1, 1, 1, 2,                                    // counts
   1205       parameters);                                         // parameter
   1206 }
   1207 
   1208 const Operator* JSOperatorBuilder::CloneObject(VectorSlotPair const& feedback,
   1209                                                int literal_flags) {
   1210   CloneObjectParameters parameters(feedback, literal_flags);
   1211   return new (zone()) Operator1<CloneObjectParameters>(  // --
   1212       IrOpcode::kJSCloneObject,                          // opcode
   1213       Operator::kNoProperties,                           // properties
   1214       "JSCloneObject",                                   // name
   1215       1, 1, 1, 1, 1, 2,                                  // counts
   1216       parameters);                                       // parameter
   1217 }
   1218 
   1219 const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() {
   1220   return new (zone()) Operator(               // --
   1221       IrOpcode::kJSCreateEmptyLiteralObject,  // opcode
   1222       Operator::kNoProperties,                // properties
   1223       "JSCreateEmptyLiteralObject",           // name
   1224       1, 1, 1, 1, 1, 2);                      // counts
   1225 }
   1226 
   1227 const Operator* JSOperatorBuilder::CreateLiteralRegExp(
   1228     Handle<String> constant_pattern, VectorSlotPair const& feedback,
   1229     int literal_flags) {
   1230   CreateLiteralParameters parameters(constant_pattern, feedback, -1,
   1231                                      literal_flags);
   1232   return new (zone()) Operator1<CreateLiteralParameters>(  // --
   1233       IrOpcode::kJSCreateLiteralRegExp,                    // opcode
   1234       Operator::kNoProperties,                             // properties
   1235       "JSCreateLiteralRegExp",                             // name
   1236       0, 1, 1, 1, 1, 2,                                    // counts
   1237       parameters);                                         // parameter
   1238 }
   1239 
   1240 const Operator* JSOperatorBuilder::CreateFunctionContext(
   1241     Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type) {
   1242   CreateFunctionContextParameters parameters(scope_info, slot_count,
   1243                                              scope_type);
   1244   return new (zone()) Operator1<CreateFunctionContextParameters>(   // --
   1245       IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties,  // opcode
   1246       "JSCreateFunctionContext",                                    // name
   1247       0, 1, 1, 1, 1, 2,                                             // counts
   1248       parameters);                                                  // parameter
   1249 }
   1250 
   1251 const Operator* JSOperatorBuilder::CreateCatchContext(
   1252     const Handle<ScopeInfo>& scope_info) {
   1253   return new (zone()) Operator1<Handle<ScopeInfo>>(
   1254       IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
   1255       "JSCreateCatchContext",                                    // name
   1256       1, 1, 1, 1, 1, 2,                                          // counts
   1257       scope_info);                                               // parameter
   1258 }
   1259 
   1260 const Operator* JSOperatorBuilder::CreateWithContext(
   1261     const Handle<ScopeInfo>& scope_info) {
   1262   return new (zone()) Operator1<Handle<ScopeInfo>>(
   1263       IrOpcode::kJSCreateWithContext, Operator::kNoProperties,  // opcode
   1264       "JSCreateWithContext",                                    // name
   1265       1, 1, 1, 1, 1, 2,                                         // counts
   1266       scope_info);                                              // parameter
   1267 }
   1268 
   1269 const Operator* JSOperatorBuilder::CreateBlockContext(
   1270     const Handle<ScopeInfo>& scope_info) {
   1271   return new (zone()) Operator1<Handle<ScopeInfo>>(              // --
   1272       IrOpcode::kJSCreateBlockContext, Operator::kNoProperties,  // opcode
   1273       "JSCreateBlockContext",                                    // name
   1274       0, 1, 1, 1, 1, 2,                                          // counts
   1275       scope_info);                                               // parameter
   1276 }
   1277 
   1278 Handle<ScopeInfo> ScopeInfoOf(const Operator* op) {
   1279   DCHECK(IrOpcode::kJSCreateBlockContext == op->opcode() ||
   1280          IrOpcode::kJSCreateWithContext == op->opcode() ||
   1281          IrOpcode::kJSCreateCatchContext == op->opcode());
   1282   return OpParameter<Handle<ScopeInfo>>(op);
   1283 }
   1284 
   1285 #undef BINARY_OP_LIST
   1286 #undef CACHED_OP_LIST
   1287 #undef COMPARE_OP_LIST
   1288 
   1289 }  // namespace compiler
   1290 }  // namespace internal
   1291 }  // namespace v8
   1292