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