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/type-feedback-vector.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 VectorSlotPair::VectorSlotPair() {}
     20 
     21 
     22 int VectorSlotPair::index() const {
     23   return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
     24 }
     25 
     26 
     27 bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
     28   return lhs.slot() == rhs.slot() &&
     29          lhs.vector().location() == rhs.vector().location();
     30 }
     31 
     32 
     33 bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
     34   return !(lhs == rhs);
     35 }
     36 
     37 
     38 size_t hash_value(VectorSlotPair const& p) {
     39   return base::hash_combine(p.slot(), p.vector().location());
     40 }
     41 
     42 
     43 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
     44   DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode());
     45   return OpParameter<ConvertReceiverMode>(op);
     46 }
     47 
     48 
     49 ToBooleanHints ToBooleanHintsOf(Operator const* op) {
     50   DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode());
     51   return OpParameter<ToBooleanHints>(op);
     52 }
     53 
     54 
     55 bool operator==(CallConstructParameters const& lhs,
     56                 CallConstructParameters const& rhs) {
     57   return lhs.arity() == rhs.arity() && lhs.feedback() == rhs.feedback();
     58 }
     59 
     60 
     61 bool operator!=(CallConstructParameters const& lhs,
     62                 CallConstructParameters const& rhs) {
     63   return !(lhs == rhs);
     64 }
     65 
     66 
     67 size_t hash_value(CallConstructParameters const& p) {
     68   return base::hash_combine(p.arity(), p.feedback());
     69 }
     70 
     71 
     72 std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) {
     73   return os << p.arity();
     74 }
     75 
     76 
     77 CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
     78   DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode());
     79   return OpParameter<CallConstructParameters>(op);
     80 }
     81 
     82 
     83 std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
     84   os << p.arity() << ", " << p.convert_mode() << ", " << p.tail_call_mode();
     85   return os;
     86 }
     87 
     88 
     89 const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
     90   DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
     91   return OpParameter<CallFunctionParameters>(op);
     92 }
     93 
     94 
     95 bool operator==(CallRuntimeParameters const& lhs,
     96                 CallRuntimeParameters const& rhs) {
     97   return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
     98 }
     99 
    100 
    101 bool operator!=(CallRuntimeParameters const& lhs,
    102                 CallRuntimeParameters const& rhs) {
    103   return !(lhs == rhs);
    104 }
    105 
    106 
    107 size_t hash_value(CallRuntimeParameters const& p) {
    108   return base::hash_combine(p.id(), p.arity());
    109 }
    110 
    111 
    112 std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
    113   return os << p.id() << ", " << p.arity();
    114 }
    115 
    116 
    117 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
    118   DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
    119   return OpParameter<CallRuntimeParameters>(op);
    120 }
    121 
    122 
    123 ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
    124     : immutable_(immutable),
    125       depth_(static_cast<uint16_t>(depth)),
    126       index_(static_cast<uint32_t>(index)) {
    127   DCHECK(depth <= std::numeric_limits<uint16_t>::max());
    128   DCHECK(index <= std::numeric_limits<uint32_t>::max());
    129 }
    130 
    131 
    132 bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
    133   return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
    134          lhs.immutable() == rhs.immutable();
    135 }
    136 
    137 
    138 bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
    139   return !(lhs == rhs);
    140 }
    141 
    142 
    143 size_t hash_value(ContextAccess const& access) {
    144   return base::hash_combine(access.depth(), access.index(), access.immutable());
    145 }
    146 
    147 
    148 std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
    149   return os << access.depth() << ", " << access.index() << ", "
    150             << access.immutable();
    151 }
    152 
    153 
    154 ContextAccess const& ContextAccessOf(Operator const* op) {
    155   DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
    156          op->opcode() == IrOpcode::kJSStoreContext);
    157   return OpParameter<ContextAccess>(op);
    158 }
    159 
    160 
    161 bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
    162   return lhs.name().location() == rhs.name().location() &&
    163          lhs.language_mode() == rhs.language_mode() &&
    164          lhs.feedback() == rhs.feedback();
    165 }
    166 
    167 
    168 bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
    169   return !(lhs == rhs);
    170 }
    171 
    172 
    173 size_t hash_value(NamedAccess const& p) {
    174   return base::hash_combine(p.name().location(), p.language_mode(),
    175                             p.feedback());
    176 }
    177 
    178 
    179 std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
    180   return os << Brief(*p.name()) << ", " << p.language_mode();
    181 }
    182 
    183 
    184 NamedAccess const& NamedAccessOf(const Operator* op) {
    185   DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
    186          op->opcode() == IrOpcode::kJSStoreNamed);
    187   return OpParameter<NamedAccess>(op);
    188 }
    189 
    190 
    191 std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
    192   return os << p.language_mode();
    193 }
    194 
    195 
    196 bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
    197   return lhs.language_mode() == rhs.language_mode() &&
    198          lhs.feedback() == rhs.feedback();
    199 }
    200 
    201 
    202 bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
    203   return !(lhs == rhs);
    204 }
    205 
    206 
    207 PropertyAccess const& PropertyAccessOf(const Operator* op) {
    208   DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
    209          op->opcode() == IrOpcode::kJSStoreProperty);
    210   return OpParameter<PropertyAccess>(op);
    211 }
    212 
    213 
    214 size_t hash_value(PropertyAccess const& p) {
    215   return base::hash_combine(p.language_mode(), p.feedback());
    216 }
    217 
    218 
    219 bool operator==(LoadGlobalParameters const& lhs,
    220                 LoadGlobalParameters const& rhs) {
    221   return lhs.name().location() == rhs.name().location() &&
    222          lhs.feedback() == rhs.feedback() &&
    223          lhs.typeof_mode() == rhs.typeof_mode();
    224 }
    225 
    226 
    227 bool operator!=(LoadGlobalParameters const& lhs,
    228                 LoadGlobalParameters const& rhs) {
    229   return !(lhs == rhs);
    230 }
    231 
    232 
    233 size_t hash_value(LoadGlobalParameters const& p) {
    234   return base::hash_combine(p.name().location(), p.typeof_mode());
    235 }
    236 
    237 
    238 std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
    239   return os << Brief(*p.name()) << ", " << p.typeof_mode();
    240 }
    241 
    242 
    243 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
    244   DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
    245   return OpParameter<LoadGlobalParameters>(op);
    246 }
    247 
    248 
    249 bool operator==(StoreGlobalParameters const& lhs,
    250                 StoreGlobalParameters const& rhs) {
    251   return lhs.language_mode() == rhs.language_mode() &&
    252          lhs.name().location() == rhs.name().location() &&
    253          lhs.feedback() == rhs.feedback();
    254 }
    255 
    256 
    257 bool operator!=(StoreGlobalParameters const& lhs,
    258                 StoreGlobalParameters const& rhs) {
    259   return !(lhs == rhs);
    260 }
    261 
    262 
    263 size_t hash_value(StoreGlobalParameters const& p) {
    264   return base::hash_combine(p.language_mode(), p.name().location(),
    265                             p.feedback());
    266 }
    267 
    268 
    269 std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
    270   return os << p.language_mode() << ", " << Brief(*p.name());
    271 }
    272 
    273 
    274 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
    275   DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
    276   return OpParameter<StoreGlobalParameters>(op);
    277 }
    278 
    279 
    280 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) {
    281   DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
    282   return OpParameter<CreateArgumentsType>(op);
    283 }
    284 
    285 
    286 bool operator==(CreateArrayParameters const& lhs,
    287                 CreateArrayParameters const& rhs) {
    288   return lhs.arity() == rhs.arity() &&
    289          lhs.site().location() == rhs.site().location();
    290 }
    291 
    292 
    293 bool operator!=(CreateArrayParameters const& lhs,
    294                 CreateArrayParameters const& rhs) {
    295   return !(lhs == rhs);
    296 }
    297 
    298 
    299 size_t hash_value(CreateArrayParameters const& p) {
    300   return base::hash_combine(p.arity(), p.site().location());
    301 }
    302 
    303 
    304 std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
    305   os << p.arity();
    306   if (!p.site().is_null()) os << ", " << Brief(*p.site());
    307   return os;
    308 }
    309 
    310 
    311 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
    312   DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
    313   return OpParameter<CreateArrayParameters>(op);
    314 }
    315 
    316 
    317 bool operator==(CreateClosureParameters const& lhs,
    318                 CreateClosureParameters const& rhs) {
    319   return lhs.pretenure() == rhs.pretenure() &&
    320          lhs.shared_info().location() == rhs.shared_info().location();
    321 }
    322 
    323 
    324 bool operator!=(CreateClosureParameters const& lhs,
    325                 CreateClosureParameters const& rhs) {
    326   return !(lhs == rhs);
    327 }
    328 
    329 
    330 size_t hash_value(CreateClosureParameters const& p) {
    331   return base::hash_combine(p.pretenure(), p.shared_info().location());
    332 }
    333 
    334 
    335 std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
    336   return os << p.pretenure() << ", " << Brief(*p.shared_info());
    337 }
    338 
    339 
    340 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
    341   DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
    342   return OpParameter<CreateClosureParameters>(op);
    343 }
    344 
    345 
    346 bool operator==(CreateLiteralParameters const& lhs,
    347                 CreateLiteralParameters const& rhs) {
    348   return lhs.constant().location() == rhs.constant().location() &&
    349          lhs.length() == rhs.length() && lhs.flags() == rhs.flags() &&
    350          lhs.index() == rhs.index();
    351 }
    352 
    353 
    354 bool operator!=(CreateLiteralParameters const& lhs,
    355                 CreateLiteralParameters const& rhs) {
    356   return !(lhs == rhs);
    357 }
    358 
    359 
    360 size_t hash_value(CreateLiteralParameters const& p) {
    361   return base::hash_combine(p.constant().location(), p.length(), p.flags(),
    362                             p.index());
    363 }
    364 
    365 
    366 std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
    367   return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags()
    368             << ", " << p.index();
    369 }
    370 
    371 
    372 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
    373   DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
    374          op->opcode() == IrOpcode::kJSCreateLiteralObject ||
    375          op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
    376   return OpParameter<CreateLiteralParameters>(op);
    377 }
    378 
    379 const BinaryOperationHints& BinaryOperationHintsOf(const Operator* op) {
    380   DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
    381          op->opcode() == IrOpcode::kJSBitwiseXor ||
    382          op->opcode() == IrOpcode::kJSBitwiseAnd ||
    383          op->opcode() == IrOpcode::kJSShiftLeft ||
    384          op->opcode() == IrOpcode::kJSShiftRight ||
    385          op->opcode() == IrOpcode::kJSShiftRightLogical ||
    386          op->opcode() == IrOpcode::kJSAdd ||
    387          op->opcode() == IrOpcode::kJSSubtract ||
    388          op->opcode() == IrOpcode::kJSMultiply ||
    389          op->opcode() == IrOpcode::kJSDivide ||
    390          op->opcode() == IrOpcode::kJSModulus);
    391   return OpParameter<BinaryOperationHints>(op);
    392 }
    393 
    394 const CompareOperationHints& CompareOperationHintsOf(const Operator* op) {
    395   DCHECK(op->opcode() == IrOpcode::kJSEqual ||
    396          op->opcode() == IrOpcode::kJSNotEqual ||
    397          op->opcode() == IrOpcode::kJSStrictEqual ||
    398          op->opcode() == IrOpcode::kJSStrictNotEqual ||
    399          op->opcode() == IrOpcode::kJSLessThan ||
    400          op->opcode() == IrOpcode::kJSGreaterThan ||
    401          op->opcode() == IrOpcode::kJSLessThanOrEqual ||
    402          op->opcode() == IrOpcode::kJSGreaterThanOrEqual);
    403   return OpParameter<CompareOperationHints>(op);
    404 }
    405 
    406 #define CACHED_OP_LIST(V)                                   \
    407   V(ToInteger, Operator::kNoProperties, 1, 1)               \
    408   V(ToLength, Operator::kNoProperties, 1, 1)                \
    409   V(ToName, Operator::kNoProperties, 1, 1)                  \
    410   V(ToNumber, Operator::kNoProperties, 1, 1)                \
    411   V(ToObject, Operator::kFoldable, 1, 1)                    \
    412   V(ToString, Operator::kNoProperties, 1, 1)                \
    413   V(Create, Operator::kEliminatable, 2, 1)                  \
    414   V(CreateIterResultObject, Operator::kEliminatable, 2, 1)  \
    415   V(HasProperty, Operator::kNoProperties, 2, 1)             \
    416   V(TypeOf, Operator::kPure, 1, 1)                          \
    417   V(InstanceOf, Operator::kNoProperties, 2, 1)              \
    418   V(ForInDone, Operator::kPure, 2, 1)                       \
    419   V(ForInNext, Operator::kNoProperties, 4, 1)               \
    420   V(ForInPrepare, Operator::kNoProperties, 1, 3)            \
    421   V(ForInStep, Operator::kPure, 1, 1)                       \
    422   V(LoadMessage, Operator::kNoThrow, 0, 1)                  \
    423   V(StoreMessage, Operator::kNoThrow, 1, 0)                 \
    424   V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
    425   V(StackCheck, Operator::kNoProperties, 0, 0)              \
    426   V(CreateWithContext, Operator::kNoProperties, 2, 1)       \
    427   V(CreateModuleContext, Operator::kNoProperties, 2, 1)
    428 
    429 struct JSOperatorGlobalCache final {
    430 #define CACHED(Name, properties, value_input_count, value_output_count)  \
    431   struct Name##Operator final : public Operator {                        \
    432     Name##Operator()                                                     \
    433         : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,          \
    434                    value_input_count, Operator::ZeroIfPure(properties),  \
    435                    Operator::ZeroIfEliminatable(properties),             \
    436                    value_output_count, Operator::ZeroIfPure(properties), \
    437                    Operator::ZeroIfNoThrow(properties)) {}               \
    438   };                                                                     \
    439   Name##Operator k##Name##Operator;
    440   CACHED_OP_LIST(CACHED)
    441 #undef CACHED
    442 };
    443 
    444 
    445 static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
    446     LAZY_INSTANCE_INITIALIZER;
    447 
    448 
    449 JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
    450     : cache_(kCache.Get()), zone_(zone) {}
    451 
    452 
    453 #define CACHED(Name, properties, value_input_count, value_output_count) \
    454   const Operator* JSOperatorBuilder::Name() {                           \
    455     return &cache_.k##Name##Operator;                                   \
    456   }
    457 CACHED_OP_LIST(CACHED)
    458 #undef CACHED
    459 
    460 const Operator* JSOperatorBuilder::BitwiseOr(BinaryOperationHints hints) {
    461   // TODO(turbofan): Cache most important versions of this operator.
    462   return new (zone()) Operator1<BinaryOperationHints>(  //--
    463       IrOpcode::kJSBitwiseOr, Operator::kNoProperties,  // opcode
    464       "JSBitwiseOr",                                    // name
    465       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    466       hints);                                           // parameter
    467 }
    468 
    469 const Operator* JSOperatorBuilder::BitwiseXor(BinaryOperationHints hints) {
    470   // TODO(turbofan): Cache most important versions of this operator.
    471   return new (zone()) Operator1<BinaryOperationHints>(   //--
    472       IrOpcode::kJSBitwiseXor, Operator::kNoProperties,  // opcode
    473       "JSBitwiseXor",                                    // name
    474       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    475       hints);                                            // parameter
    476 }
    477 
    478 const Operator* JSOperatorBuilder::BitwiseAnd(BinaryOperationHints hints) {
    479   // TODO(turbofan): Cache most important versions of this operator.
    480   return new (zone()) Operator1<BinaryOperationHints>(   //--
    481       IrOpcode::kJSBitwiseAnd, Operator::kNoProperties,  // opcode
    482       "JSBitwiseAnd",                                    // name
    483       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    484       hints);                                            // parameter
    485 }
    486 
    487 const Operator* JSOperatorBuilder::ShiftLeft(BinaryOperationHints hints) {
    488   // TODO(turbofan): Cache most important versions of this operator.
    489   return new (zone()) Operator1<BinaryOperationHints>(  //--
    490       IrOpcode::kJSShiftLeft, Operator::kNoProperties,  // opcode
    491       "JSShiftLeft",                                    // name
    492       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    493       hints);                                           // parameter
    494 }
    495 
    496 const Operator* JSOperatorBuilder::ShiftRight(BinaryOperationHints hints) {
    497   // TODO(turbofan): Cache most important versions of this operator.
    498   return new (zone()) Operator1<BinaryOperationHints>(   //--
    499       IrOpcode::kJSShiftRight, Operator::kNoProperties,  // opcode
    500       "JSShiftRight",                                    // name
    501       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    502       hints);                                            // parameter
    503 }
    504 
    505 const Operator* JSOperatorBuilder::ShiftRightLogical(
    506     BinaryOperationHints hints) {
    507   // TODO(turbofan): Cache most important versions of this operator.
    508   return new (zone()) Operator1<BinaryOperationHints>(          //--
    509       IrOpcode::kJSShiftRightLogical, Operator::kNoProperties,  // opcode
    510       "JSShiftRightLogical",                                    // name
    511       2, 1, 1, 1, 1, 2,  // inputs/outputs
    512       hints);            // parameter
    513 }
    514 
    515 const Operator* JSOperatorBuilder::Add(BinaryOperationHints hints) {
    516   // TODO(turbofan): Cache most important versions of this operator.
    517   return new (zone()) Operator1<BinaryOperationHints>(  //--
    518       IrOpcode::kJSAdd, Operator::kNoProperties,        // opcode
    519       "JSAdd",                                          // name
    520       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    521       hints);                                           // parameter
    522 }
    523 
    524 const Operator* JSOperatorBuilder::Subtract(BinaryOperationHints hints) {
    525   // TODO(turbofan): Cache most important versions of this operator.
    526   return new (zone()) Operator1<BinaryOperationHints>(  //--
    527       IrOpcode::kJSSubtract, Operator::kNoProperties,   // opcode
    528       "JSSubtract",                                     // name
    529       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    530       hints);                                           // parameter
    531 }
    532 
    533 const Operator* JSOperatorBuilder::Multiply(BinaryOperationHints hints) {
    534   // TODO(turbofan): Cache most important versions of this operator.
    535   return new (zone()) Operator1<BinaryOperationHints>(  //--
    536       IrOpcode::kJSMultiply, Operator::kNoProperties,   // opcode
    537       "JSMultiply",                                     // name
    538       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    539       hints);                                           // parameter
    540 }
    541 
    542 const Operator* JSOperatorBuilder::Divide(BinaryOperationHints hints) {
    543   // TODO(turbofan): Cache most important versions of this operator.
    544   return new (zone()) Operator1<BinaryOperationHints>(  //--
    545       IrOpcode::kJSDivide, Operator::kNoProperties,     // opcode
    546       "JSDivide",                                       // name
    547       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    548       hints);                                           // parameter
    549 }
    550 
    551 const Operator* JSOperatorBuilder::Modulus(BinaryOperationHints hints) {
    552   // TODO(turbofan): Cache most important versions of this operator.
    553   return new (zone()) Operator1<BinaryOperationHints>(  //--
    554       IrOpcode::kJSModulus, Operator::kNoProperties,    // opcode
    555       "JSModulus",                                      // name
    556       2, 1, 1, 1, 1, 2,                                 // inputs/outputs
    557       hints);                                           // parameter
    558 }
    559 
    560 const Operator* JSOperatorBuilder::Equal(CompareOperationHints hints) {
    561   // TODO(turbofan): Cache most important versions of this operator.
    562   return new (zone()) Operator1<CompareOperationHints>(  //--
    563       IrOpcode::kJSEqual, Operator::kNoProperties,       // opcode
    564       "JSEqual",                                         // name
    565       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    566       hints);                                            // parameter
    567 }
    568 
    569 const Operator* JSOperatorBuilder::NotEqual(CompareOperationHints hints) {
    570   // TODO(turbofan): Cache most important versions of this operator.
    571   return new (zone()) Operator1<CompareOperationHints>(  //--
    572       IrOpcode::kJSNotEqual, Operator::kNoProperties,    // opcode
    573       "JSNotEqual",                                      // name
    574       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    575       hints);                                            // parameter
    576 }
    577 
    578 const Operator* JSOperatorBuilder::StrictEqual(CompareOperationHints hints) {
    579   // TODO(turbofan): Cache most important versions of this operator.
    580   return new (zone()) Operator1<CompareOperationHints>(  //--
    581       IrOpcode::kJSStrictEqual, Operator::kPure,         // opcode
    582       "JSStrictEqual",                                   // name
    583       2, 0, 0, 1, 0, 0,                                  // inputs/outputs
    584       hints);                                            // parameter
    585 }
    586 
    587 const Operator* JSOperatorBuilder::StrictNotEqual(CompareOperationHints hints) {
    588   // TODO(turbofan): Cache most important versions of this operator.
    589   return new (zone()) Operator1<CompareOperationHints>(  //--
    590       IrOpcode::kJSStrictNotEqual, Operator::kPure,      // opcode
    591       "JSStrictNotEqual",                                // name
    592       2, 0, 0, 1, 0, 0,                                  // inputs/outputs
    593       hints);                                            // parameter
    594 }
    595 
    596 const Operator* JSOperatorBuilder::LessThan(CompareOperationHints hints) {
    597   // TODO(turbofan): Cache most important versions of this operator.
    598   return new (zone()) Operator1<CompareOperationHints>(  //--
    599       IrOpcode::kJSLessThan, Operator::kNoProperties,    // opcode
    600       "JSLessThan",                                      // name
    601       2, 1, 1, 1, 1, 2,                                  // inputs/outputs
    602       hints);                                            // parameter
    603 }
    604 
    605 const Operator* JSOperatorBuilder::GreaterThan(CompareOperationHints hints) {
    606   // TODO(turbofan): Cache most important versions of this operator.
    607   return new (zone()) Operator1<CompareOperationHints>(   //--
    608       IrOpcode::kJSGreaterThan, Operator::kNoProperties,  // opcode
    609       "JSGreaterThan",                                    // name
    610       2, 1, 1, 1, 1, 2,                                   // inputs/outputs
    611       hints);                                             // parameter
    612 }
    613 
    614 const Operator* JSOperatorBuilder::LessThanOrEqual(
    615     CompareOperationHints hints) {
    616   // TODO(turbofan): Cache most important versions of this operator.
    617   return new (zone()) Operator1<CompareOperationHints>(       //--
    618       IrOpcode::kJSLessThanOrEqual, Operator::kNoProperties,  // opcode
    619       "JSLessThanOrEqual",                                    // name
    620       2, 1, 1, 1, 1, 2,                                       // inputs/outputs
    621       hints);                                                 // parameter
    622 }
    623 
    624 const Operator* JSOperatorBuilder::GreaterThanOrEqual(
    625     CompareOperationHints hints) {
    626   // TODO(turbofan): Cache most important versions of this operator.
    627   return new (zone()) Operator1<CompareOperationHints>(          //--
    628       IrOpcode::kJSGreaterThanOrEqual, Operator::kNoProperties,  // opcode
    629       "JSGreaterThanOrEqual",                                    // name
    630       2, 1, 1, 1, 1, 2,  // inputs/outputs
    631       hints);            // parameter
    632 }
    633 
    634 const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
    635   // TODO(turbofan): Cache most important versions of this operator.
    636   return new (zone()) Operator1<ToBooleanHints>(  //--
    637       IrOpcode::kJSToBoolean, Operator::kPure,    // opcode
    638       "JSToBoolean",                              // name
    639       1, 0, 0, 1, 0, 0,                           // inputs/outputs
    640       hints);                                     // parameter
    641 }
    642 
    643 const Operator* JSOperatorBuilder::CallFunction(
    644     size_t arity, VectorSlotPair const& feedback,
    645     ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
    646   CallFunctionParameters parameters(arity, feedback, tail_call_mode,
    647                                     convert_mode);
    648   return new (zone()) Operator1<CallFunctionParameters>(   // --
    649       IrOpcode::kJSCallFunction, Operator::kNoProperties,  // opcode
    650       "JSCallFunction",                                    // name
    651       parameters.arity(), 1, 1, 1, 1, 2,                   // inputs/outputs
    652       parameters);                                         // parameter
    653 }
    654 
    655 
    656 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) {
    657   const Runtime::Function* f = Runtime::FunctionForId(id);
    658   return CallRuntime(f, f->nargs);
    659 }
    660 
    661 
    662 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
    663                                                size_t arity) {
    664   const Runtime::Function* f = Runtime::FunctionForId(id);
    665   return CallRuntime(f, arity);
    666 }
    667 
    668 
    669 const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f,
    670                                                size_t arity) {
    671   CallRuntimeParameters parameters(f->function_id, arity);
    672   DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
    673   return new (zone()) Operator1<CallRuntimeParameters>(   // --
    674       IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
    675       "JSCallRuntime",                                    // name
    676       parameters.arity(), 1, 1, f->result_size, 1, 2,     // inputs/outputs
    677       parameters);                                        // parameter
    678 }
    679 
    680 
    681 const Operator* JSOperatorBuilder::CallConstruct(
    682     size_t arity, VectorSlotPair const& feedback) {
    683   CallConstructParameters parameters(arity, feedback);
    684   return new (zone()) Operator1<CallConstructParameters>(   // --
    685       IrOpcode::kJSCallConstruct, Operator::kNoProperties,  // opcode
    686       "JSCallConstruct",                                    // name
    687       parameters.arity(), 1, 1, 1, 1, 2,                    // counts
    688       parameters);                                          // parameter
    689 }
    690 
    691 
    692 const Operator* JSOperatorBuilder::ConvertReceiver(
    693     ConvertReceiverMode convert_mode) {
    694   return new (zone()) Operator1<ConvertReceiverMode>(    // --
    695       IrOpcode::kJSConvertReceiver, Operator::kNoThrow,  // opcode
    696       "JSConvertReceiver",                               // name
    697       1, 1, 1, 1, 1, 0,                                  // counts
    698       convert_mode);                                     // parameter
    699 }
    700 
    701 const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name,
    702                                              const VectorSlotPair& feedback) {
    703   NamedAccess access(SLOPPY, name, feedback);
    704   return new (zone()) Operator1<NamedAccess>(           // --
    705       IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
    706       "JSLoadNamed",                                    // name
    707       2, 1, 1, 1, 1, 2,                                 // counts
    708       access);                                          // parameter
    709 }
    710 
    711 const Operator* JSOperatorBuilder::LoadProperty(
    712     VectorSlotPair const& feedback) {
    713   PropertyAccess access(SLOPPY, feedback);
    714   return new (zone()) Operator1<PropertyAccess>(           // --
    715       IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
    716       "JSLoadProperty",                                    // name
    717       3, 1, 1, 1, 1, 2,                                    // counts
    718       access);                                             // parameter
    719 }
    720 
    721 const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
    722   return new (zone()) Operator1<int>(                   // --
    723       IrOpcode::kJSGeneratorStore, Operator::kNoThrow,  // opcode
    724       "JSGeneratorStore",                               // name
    725       3 + register_count, 1, 1, 0, 1, 0,                // counts
    726       register_count);                                  // parameter
    727 }
    728 
    729 const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) {
    730   return new (zone()) Operator1<int>(                             // --
    731       IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow,  // opcode
    732       "JSGeneratorRestoreRegister",                               // name
    733       1, 1, 1, 1, 1, 0,                                           // counts
    734       index);                                                     // parameter
    735 }
    736 
    737 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
    738                                               Handle<Name> name,
    739                                               VectorSlotPair const& feedback) {
    740   NamedAccess access(language_mode, name, feedback);
    741   return new (zone()) Operator1<NamedAccess>(            // --
    742       IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
    743       "JSStoreNamed",                                    // name
    744       3, 1, 1, 0, 1, 2,                                  // counts
    745       access);                                           // parameter
    746 }
    747 
    748 
    749 const Operator* JSOperatorBuilder::StoreProperty(
    750     LanguageMode language_mode, VectorSlotPair const& feedback) {
    751   PropertyAccess access(language_mode, feedback);
    752   return new (zone()) Operator1<PropertyAccess>(            // --
    753       IrOpcode::kJSStoreProperty, Operator::kNoProperties,  // opcode
    754       "JSStoreProperty",                                    // name
    755       4, 1, 1, 0, 1, 2,                                     // counts
    756       access);                                              // parameter
    757 }
    758 
    759 
    760 const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
    761   return new (zone()) Operator1<LanguageMode>(               // --
    762       IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
    763       "JSDeleteProperty",                                    // name
    764       2, 1, 1, 1, 1, 2,                                      // counts
    765       language_mode);                                        // parameter
    766 }
    767 
    768 
    769 const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
    770                                               const VectorSlotPair& feedback,
    771                                               TypeofMode typeof_mode) {
    772   LoadGlobalParameters parameters(name, feedback, typeof_mode);
    773   return new (zone()) Operator1<LoadGlobalParameters>(   // --
    774       IrOpcode::kJSLoadGlobal, Operator::kNoProperties,  // opcode
    775       "JSLoadGlobal",                                    // name
    776       1, 1, 1, 1, 1, 2,                                  // counts
    777       parameters);                                       // parameter
    778 }
    779 
    780 
    781 const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
    782                                                const Handle<Name>& name,
    783                                                const VectorSlotPair& feedback) {
    784   StoreGlobalParameters parameters(language_mode, feedback, name);
    785   return new (zone()) Operator1<StoreGlobalParameters>(   // --
    786       IrOpcode::kJSStoreGlobal, Operator::kNoProperties,  // opcode
    787       "JSStoreGlobal",                                    // name
    788       2, 1, 1, 0, 1, 2,                                   // counts
    789       parameters);                                        // parameter
    790 }
    791 
    792 
    793 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
    794                                                bool immutable) {
    795   ContextAccess access(depth, index, immutable);
    796   return new (zone()) Operator1<ContextAccess>(  // --
    797       IrOpcode::kJSLoadContext,                  // opcode
    798       Operator::kNoWrite | Operator::kNoThrow,   // flags
    799       "JSLoadContext",                           // name
    800       1, 1, 0, 1, 1, 0,                          // counts
    801       access);                                   // parameter
    802 }
    803 
    804 
    805 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
    806   ContextAccess access(depth, index, false);
    807   return new (zone()) Operator1<ContextAccess>(  // --
    808       IrOpcode::kJSStoreContext,                 // opcode
    809       Operator::kNoRead | Operator::kNoThrow,    // flags
    810       "JSStoreContext",                          // name
    811       2, 1, 1, 0, 1, 0,                          // counts
    812       access);                                   // parameter
    813 }
    814 
    815 
    816 const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
    817   return new (zone()) Operator1<CreateArgumentsType>(         // --
    818       IrOpcode::kJSCreateArguments, Operator::kEliminatable,  // opcode
    819       "JSCreateArguments",                                    // name
    820       1, 1, 0, 1, 1, 0,                                       // counts
    821       type);                                                  // parameter
    822 }
    823 
    824 
    825 const Operator* JSOperatorBuilder::CreateArray(size_t arity,
    826                                                Handle<AllocationSite> site) {
    827   // constructor, new_target, arg1, ..., argN
    828   int const value_input_count = static_cast<int>(arity) + 2;
    829   CreateArrayParameters parameters(arity, site);
    830   return new (zone()) Operator1<CreateArrayParameters>(   // --
    831       IrOpcode::kJSCreateArray, Operator::kNoProperties,  // opcode
    832       "JSCreateArray",                                    // name
    833       value_input_count, 1, 1, 1, 1, 2,                   // counts
    834       parameters);                                        // parameter
    835 }
    836 
    837 
    838 const Operator* JSOperatorBuilder::CreateClosure(
    839     Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) {
    840   CreateClosureParameters parameters(shared_info, pretenure);
    841   return new (zone()) Operator1<CreateClosureParameters>(  // --
    842       IrOpcode::kJSCreateClosure, Operator::kNoThrow,      // opcode
    843       "JSCreateClosure",                                   // name
    844       0, 1, 1, 1, 1, 0,                                    // counts
    845       parameters);                                         // parameter
    846 }
    847 
    848 const Operator* JSOperatorBuilder::CreateLiteralArray(
    849     Handle<FixedArray> constant_elements, int literal_flags, int literal_index,
    850     int number_of_elements) {
    851   CreateLiteralParameters parameters(constant_elements, number_of_elements,
    852                                      literal_flags, literal_index);
    853   return new (zone()) Operator1<CreateLiteralParameters>(        // --
    854       IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties,  // opcode
    855       "JSCreateLiteralArray",                                    // name
    856       1, 1, 1, 1, 1, 2,                                          // counts
    857       parameters);                                               // parameter
    858 }
    859 
    860 const Operator* JSOperatorBuilder::CreateLiteralObject(
    861     Handle<FixedArray> constant_properties, int literal_flags,
    862     int literal_index, int number_of_properties) {
    863   CreateLiteralParameters parameters(constant_properties, number_of_properties,
    864                                      literal_flags, literal_index);
    865   return new (zone()) Operator1<CreateLiteralParameters>(         // --
    866       IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties,  // opcode
    867       "JSCreateLiteralObject",                                    // name
    868       1, 1, 1, 1, 1, 2,                                           // counts
    869       parameters);                                                // parameter
    870 }
    871 
    872 
    873 const Operator* JSOperatorBuilder::CreateLiteralRegExp(
    874     Handle<String> constant_pattern, int literal_flags, int literal_index) {
    875   CreateLiteralParameters parameters(constant_pattern, -1, literal_flags,
    876                                      literal_index);
    877   return new (zone()) Operator1<CreateLiteralParameters>(         // --
    878       IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties,  // opcode
    879       "JSCreateLiteralRegExp",                                    // name
    880       1, 1, 1, 1, 1, 2,                                           // counts
    881       parameters);                                                // parameter
    882 }
    883 
    884 
    885 const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) {
    886   return new (zone()) Operator1<int>(                               // --
    887       IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties,  // opcode
    888       "JSCreateFunctionContext",                                    // name
    889       1, 1, 1, 1, 1, 2,                                             // counts
    890       slot_count);                                                  // parameter
    891 }
    892 
    893 
    894 const Operator* JSOperatorBuilder::CreateCatchContext(
    895     const Handle<String>& name) {
    896   return new (zone()) Operator1<Handle<String>>(                 // --
    897       IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
    898       "JSCreateCatchContext",                                    // name
    899       2, 1, 1, 1, 1, 2,                                          // counts
    900       name);                                                     // parameter
    901 }
    902 
    903 
    904 const Operator* JSOperatorBuilder::CreateBlockContext(
    905     const Handle<ScopeInfo>& scpope_info) {
    906   return new (zone()) Operator1<Handle<ScopeInfo>>(              // --
    907       IrOpcode::kJSCreateBlockContext, Operator::kNoProperties,  // opcode
    908       "JSCreateBlockContext",                                    // name
    909       1, 1, 1, 1, 1, 2,                                          // counts
    910       scpope_info);                                              // parameter
    911 }
    912 
    913 
    914 const Operator* JSOperatorBuilder::CreateScriptContext(
    915     const Handle<ScopeInfo>& scpope_info) {
    916   return new (zone()) Operator1<Handle<ScopeInfo>>(               // --
    917       IrOpcode::kJSCreateScriptContext, Operator::kNoProperties,  // opcode
    918       "JSCreateScriptContext",                                    // name
    919       1, 1, 1, 1, 1, 2,                                           // counts
    920       scpope_info);                                               // parameter
    921 }
    922 
    923 }  // namespace compiler
    924 }  // namespace internal
    925 }  // namespace v8
    926