js-operator.cc 36.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/js-operator.h"

#include <limits>

#include "src/base/lazy-instance.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/operator.h"
12 13
#include "src/handles-inl.h"
#include "src/type-feedback-vector.h"
14 15 16 17 18

namespace v8 {
namespace internal {
namespace compiler {

19
VectorSlotPair::VectorSlotPair() {}
20 21 22 23 24 25 26


int VectorSlotPair::index() const {
  return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
}


27
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
28 29
  return lhs.slot() == rhs.slot() &&
         lhs.vector().location() == rhs.vector().location();
30 31 32 33 34 35 36 37 38
}


bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(VectorSlotPair const& p) {
39
  return base::hash_combine(p.slot(), p.vector().location());
40 41 42
}


43 44 45 46 47 48
ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
  DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode());
  return OpParameter<ConvertReceiverMode>(op);
}


49 50 51 52 53 54
ToBooleanHints ToBooleanHintsOf(Operator const* op) {
  DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode());
  return OpParameter<ToBooleanHints>(op);
}


55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
bool operator==(CallConstructParameters const& lhs,
                CallConstructParameters const& rhs) {
  return lhs.arity() == rhs.arity() && lhs.feedback() == rhs.feedback();
}


bool operator!=(CallConstructParameters const& lhs,
                CallConstructParameters const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(CallConstructParameters const& p) {
  return base::hash_combine(p.arity(), p.feedback());
}


std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) {
  return os << p.arity();
}


CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
  DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode());
  return OpParameter<CallConstructParameters>(op);
}


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 90 91 92 93 94
const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
  DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
  return OpParameter<CallFunctionParameters>(op);
}


95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
bool operator==(CallRuntimeParameters const& lhs,
                CallRuntimeParameters const& rhs) {
  return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
}


bool operator!=(CallRuntimeParameters const& lhs,
                CallRuntimeParameters const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(CallRuntimeParameters const& p) {
  return base::hash_combine(p.id(), p.arity());
}


std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
  return os << p.id() << ", " << p.arity();
}


117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
  DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
  return OpParameter<CallRuntimeParameters>(op);
}


ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
    : immutable_(immutable),
      depth_(static_cast<uint16_t>(depth)),
      index_(static_cast<uint32_t>(index)) {
  DCHECK(depth <= std::numeric_limits<uint16_t>::max());
  DCHECK(index <= std::numeric_limits<uint32_t>::max());
}


132
bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
133 134 135 136 137
  return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
         lhs.immutable() == rhs.immutable();
}


138
bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
139 140 141 142
  return !(lhs == rhs);
}


143 144 145 146 147 148 149 150 151 152 153 154
size_t hash_value(ContextAccess const& access) {
  return base::hash_combine(access.depth(), access.index(), access.immutable());
}


std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
  return os << access.depth() << ", " << access.index() << ", "
            << access.immutable();
}


ContextAccess const& ContextAccessOf(Operator const* op) {
155 156 157 158 159 160
  DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
         op->opcode() == IrOpcode::kJSStoreContext);
  return OpParameter<ContextAccess>(op);
}


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 170 171 172
  return !(lhs == rhs);
}


173
size_t hash_value(NamedAccess const& p) {
174 175
  return base::hash_combine(p.name().location(), p.language_mode(),
                            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 185 186 187 188 189 190 191
NamedAccess const& NamedAccessOf(const Operator* op) {
  DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
         op->opcode() == IrOpcode::kJSStoreNamed);
  return OpParameter<NamedAccess>(op);
}


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 198
  return lhs.language_mode() == rhs.language_mode() &&
         lhs.feedback() == rhs.feedback();
199 200 201
}


202
bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
203 204 205 206
  return !(lhs == rhs);
}


207 208 209 210
PropertyAccess const& PropertyAccessOf(const Operator* op) {
  DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
         op->opcode() == IrOpcode::kJSStoreProperty);
  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 220
bool operator==(LoadGlobalParameters const& lhs,
                LoadGlobalParameters const& rhs) {
221 222
  return lhs.name().location() == rhs.name().location() &&
         lhs.feedback() == rhs.feedback() &&
223
         lhs.typeof_mode() == rhs.typeof_mode();
224 225 226 227 228 229 230 231 232 233
}


bool operator!=(LoadGlobalParameters const& lhs,
                LoadGlobalParameters const& rhs) {
  return !(lhs == rhs);
}


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 246 247 248 249 250 251
  return OpParameter<LoadGlobalParameters>(op);
}


bool operator==(StoreGlobalParameters const& lhs,
                StoreGlobalParameters const& rhs) {
  return lhs.language_mode() == rhs.language_mode() &&
252
         lhs.name().location() == rhs.name().location() &&
253
         lhs.feedback() == rhs.feedback();
254 255 256 257 258 259 260 261 262 263
}


bool operator!=(StoreGlobalParameters const& lhs,
                StoreGlobalParameters const& rhs) {
  return !(lhs == rhs);
}


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 275 276
}


const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
  DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
  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 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
bool operator==(CreateArrayParameters const& lhs,
                CreateArrayParameters const& rhs) {
  return lhs.arity() == rhs.arity() &&
         lhs.site().location() == rhs.site().location();
}


bool operator!=(CreateArrayParameters const& lhs,
                CreateArrayParameters const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(CreateArrayParameters const& p) {
  return base::hash_combine(p.arity(), p.site().location());
}


std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
  os << p.arity();
  if (!p.site().is_null()) os << ", " << Brief(*p.site());
  return os;
}


const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
  DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
  return OpParameter<CreateArrayParameters>(op);
}


317 318 319
bool operator==(CreateClosureParameters const& lhs,
                CreateClosureParameters const& rhs) {
  return lhs.pretenure() == rhs.pretenure() &&
320
         lhs.shared_info().location() == rhs.shared_info().location();
321 322 323 324 325 326 327 328 329 330
}


bool operator!=(CreateClosureParameters const& lhs,
                CreateClosureParameters const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(CreateClosureParameters const& p) {
331
  return base::hash_combine(p.pretenure(), p.shared_info().location());
332 333 334 335 336 337 338 339 340 341 342 343 344 345
}


std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
  return os << p.pretenure() << ", " << Brief(*p.shared_info());
}


const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
  DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
  return OpParameter<CreateClosureParameters>(op);
}


346 347
bool operator==(CreateLiteralParameters const& lhs,
                CreateLiteralParameters const& rhs) {
348
  return lhs.constant().location() == rhs.constant().location() &&
349 350
         lhs.length() == rhs.length() && lhs.flags() == rhs.flags() &&
         lhs.index() == rhs.index();
351 352 353 354 355 356 357 358 359 360
}


bool operator!=(CreateLiteralParameters const& lhs,
                CreateLiteralParameters const& rhs) {
  return !(lhs == rhs);
}


size_t hash_value(CreateLiteralParameters const& p) {
361 362
  return base::hash_combine(p.constant().location(), p.length(), p.flags(),
                            p.index());
363 364 365 366
}


std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
367 368
  return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags()
            << ", " << p.index();
369 370 371 372 373
}


const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
  DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
374 375
         op->opcode() == IrOpcode::kJSCreateLiteralObject ||
         op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
376 377 378
  return OpParameter<CreateLiteralParameters>(op);
}

379
const BinaryOperationHints& BinaryOperationHintsOf(const Operator* op) {
380 381 382 383 384 385 386 387 388 389 390
  DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
         op->opcode() == IrOpcode::kJSBitwiseXor ||
         op->opcode() == IrOpcode::kJSBitwiseAnd ||
         op->opcode() == IrOpcode::kJSShiftLeft ||
         op->opcode() == IrOpcode::kJSShiftRight ||
         op->opcode() == IrOpcode::kJSShiftRightLogical ||
         op->opcode() == IrOpcode::kJSAdd ||
         op->opcode() == IrOpcode::kJSSubtract ||
         op->opcode() == IrOpcode::kJSMultiply ||
         op->opcode() == IrOpcode::kJSDivide ||
         op->opcode() == IrOpcode::kJSModulus);
391 392 393
  return OpParameter<BinaryOperationHints>(op);
}

394 395 396 397 398 399 400 401 402 403 404 405
const CompareOperationHints& CompareOperationHintsOf(const Operator* op) {
  DCHECK(op->opcode() == IrOpcode::kJSEqual ||
         op->opcode() == IrOpcode::kJSNotEqual ||
         op->opcode() == IrOpcode::kJSStrictEqual ||
         op->opcode() == IrOpcode::kJSStrictNotEqual ||
         op->opcode() == IrOpcode::kJSLessThan ||
         op->opcode() == IrOpcode::kJSGreaterThan ||
         op->opcode() == IrOpcode::kJSLessThanOrEqual ||
         op->opcode() == IrOpcode::kJSGreaterThanOrEqual);
  return OpParameter<CompareOperationHints>(op);
}

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
#define CACHED_OP_LIST(V)                                   \
  V(ToInteger, Operator::kNoProperties, 1, 1)               \
  V(ToLength, Operator::kNoProperties, 1, 1)                \
  V(ToName, Operator::kNoProperties, 1, 1)                  \
  V(ToNumber, Operator::kNoProperties, 1, 1)                \
  V(ToObject, Operator::kFoldable, 1, 1)                    \
  V(ToString, Operator::kNoProperties, 1, 1)                \
  V(Create, Operator::kEliminatable, 2, 1)                  \
  V(CreateIterResultObject, Operator::kEliminatable, 2, 1)  \
  V(HasProperty, Operator::kNoProperties, 2, 1)             \
  V(TypeOf, Operator::kPure, 1, 1)                          \
  V(InstanceOf, Operator::kNoProperties, 2, 1)              \
  V(ForInDone, Operator::kPure, 2, 1)                       \
  V(ForInNext, Operator::kNoProperties, 4, 1)               \
  V(ForInPrepare, Operator::kNoProperties, 1, 3)            \
  V(ForInStep, Operator::kPure, 1, 1)                       \
  V(LoadMessage, Operator::kNoThrow, 0, 1)                  \
  V(StoreMessage, Operator::kNoThrow, 1, 0)                 \
  V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \
  V(StackCheck, Operator::kNoProperties, 0, 0)              \
  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 433 434
    Name##Operator()                                                     \
        : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,          \
                   value_input_count, Operator::ZeroIfPure(properties),  \
435 436
                   Operator::ZeroIfEliminatable(properties),             \
                   value_output_count, Operator::ZeroIfPure(properties), \
437
                   Operator::ZeroIfNoThrow(properties)) {}               \
438
  };                                                                     \
439
  Name##Operator k##Name##Operator;
440 441
  CACHED_OP_LIST(CACHED)
#undef CACHED
442 443 444
};


445
static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
446 447 448 449
    LAZY_INSTANCE_INITIALIZER;


JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
450
    : cache_(kCache.Get()), zone_(zone) {}
451 452


453 454 455 456 457 458
#define CACHED(Name, properties, value_input_count, value_output_count) \
  const Operator* JSOperatorBuilder::Name() {                           \
    return &cache_.k##Name##Operator;                                   \
  }
CACHED_OP_LIST(CACHED)
#undef CACHED
459

460
const Operator* JSOperatorBuilder::BitwiseOr(BinaryOperationHints hints) {
461
  // TODO(turbofan): Cache most important versions of this operator.
462 463 464 465 466
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSBitwiseOr, Operator::kNoProperties,  // opcode
      "JSBitwiseOr",                                    // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
467 468
}

469
const Operator* JSOperatorBuilder::BitwiseXor(BinaryOperationHints hints) {
470
  // TODO(turbofan): Cache most important versions of this operator.
471 472 473 474 475
  return new (zone()) Operator1<BinaryOperationHints>(   //--
      IrOpcode::kJSBitwiseXor, Operator::kNoProperties,  // opcode
      "JSBitwiseXor",                                    // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      hints);                                            // parameter
476 477
}

478
const Operator* JSOperatorBuilder::BitwiseAnd(BinaryOperationHints hints) {
479
  // TODO(turbofan): Cache most important versions of this operator.
480 481 482 483 484
  return new (zone()) Operator1<BinaryOperationHints>(   //--
      IrOpcode::kJSBitwiseAnd, Operator::kNoProperties,  // opcode
      "JSBitwiseAnd",                                    // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      hints);                                            // parameter
485 486
}

487
const Operator* JSOperatorBuilder::ShiftLeft(BinaryOperationHints hints) {
488
  // TODO(turbofan): Cache most important versions of this operator.
489 490 491 492 493
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSShiftLeft, Operator::kNoProperties,  // opcode
      "JSShiftLeft",                                    // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
494 495
}

496
const Operator* JSOperatorBuilder::ShiftRight(BinaryOperationHints hints) {
497
  // TODO(turbofan): Cache most important versions of this operator.
498 499 500 501 502
  return new (zone()) Operator1<BinaryOperationHints>(   //--
      IrOpcode::kJSShiftRight, Operator::kNoProperties,  // opcode
      "JSShiftRight",                                    // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      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 510 511
      IrOpcode::kJSShiftRightLogical, Operator::kNoProperties,  // opcode
      "JSShiftRightLogical",                                    // name
      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 518 519 520 521
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSAdd, Operator::kNoProperties,        // opcode
      "JSAdd",                                          // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
522 523
}

524
const Operator* JSOperatorBuilder::Subtract(BinaryOperationHints hints) {
525
  // TODO(turbofan): Cache most important versions of this operator.
526 527 528 529 530
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSSubtract, Operator::kNoProperties,   // opcode
      "JSSubtract",                                     // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
531 532
}

533
const Operator* JSOperatorBuilder::Multiply(BinaryOperationHints hints) {
534
  // TODO(turbofan): Cache most important versions of this operator.
535 536 537 538 539
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSMultiply, Operator::kNoProperties,   // opcode
      "JSMultiply",                                     // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
540 541
}

542
const Operator* JSOperatorBuilder::Divide(BinaryOperationHints hints) {
543
  // TODO(turbofan): Cache most important versions of this operator.
544 545 546 547 548
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSDivide, Operator::kNoProperties,     // opcode
      "JSDivide",                                       // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
549 550
}

551
const Operator* JSOperatorBuilder::Modulus(BinaryOperationHints hints) {
552
  // TODO(turbofan): Cache most important versions of this operator.
553 554 555 556 557
  return new (zone()) Operator1<BinaryOperationHints>(  //--
      IrOpcode::kJSModulus, Operator::kNoProperties,    // opcode
      "JSModulus",                                      // name
      2, 1, 1, 1, 1, 2,                                 // inputs/outputs
      hints);                                           // parameter
558 559
}

560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
const Operator* JSOperatorBuilder::Equal(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(  //--
      IrOpcode::kJSEqual, Operator::kNoProperties,       // opcode
      "JSEqual",                                         // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      hints);                                            // parameter
}

const Operator* JSOperatorBuilder::NotEqual(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(  //--
      IrOpcode::kJSNotEqual, Operator::kNoProperties,    // opcode
      "JSNotEqual",                                      // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      hints);                                            // parameter
}

const Operator* JSOperatorBuilder::StrictEqual(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(  //--
      IrOpcode::kJSStrictEqual, Operator::kPure,         // opcode
      "JSStrictEqual",                                   // name
      2, 0, 0, 1, 0, 0,                                  // inputs/outputs
      hints);                                            // parameter
}

const Operator* JSOperatorBuilder::StrictNotEqual(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(  //--
      IrOpcode::kJSStrictNotEqual, Operator::kPure,      // opcode
      "JSStrictNotEqual",                                // name
      2, 0, 0, 1, 0, 0,                                  // inputs/outputs
      hints);                                            // parameter
}

const Operator* JSOperatorBuilder::LessThan(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(  //--
      IrOpcode::kJSLessThan, Operator::kNoProperties,    // opcode
      "JSLessThan",                                      // name
      2, 1, 1, 1, 1, 2,                                  // inputs/outputs
      hints);                                            // parameter
}

const Operator* JSOperatorBuilder::GreaterThan(CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(   //--
      IrOpcode::kJSGreaterThan, Operator::kNoProperties,  // opcode
      "JSGreaterThan",                                    // name
      2, 1, 1, 1, 1, 2,                                   // inputs/outputs
      hints);                                             // parameter
}

const Operator* JSOperatorBuilder::LessThanOrEqual(
    CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(       //--
      IrOpcode::kJSLessThanOrEqual, Operator::kNoProperties,  // opcode
      "JSLessThanOrEqual",                                    // name
      2, 1, 1, 1, 1, 2,                                       // inputs/outputs
      hints);                                                 // parameter
}

const Operator* JSOperatorBuilder::GreaterThanOrEqual(
    CompareOperationHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
  return new (zone()) Operator1<CompareOperationHints>(          //--
      IrOpcode::kJSGreaterThanOrEqual, Operator::kNoProperties,  // opcode
      "JSGreaterThanOrEqual",                                    // name
      2, 1, 1, 1, 1, 2,  // inputs/outputs
      hints);            // parameter
}
633

634 635
const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
  // TODO(turbofan): Cache most important versions of this operator.
636 637 638 639 640
  return new (zone()) Operator1<ToBooleanHints>(  //--
      IrOpcode::kJSToBoolean, Operator::kPure,    // opcode
      "JSToBoolean",                              // name
      1, 0, 0, 1, 0, 0,                           // inputs/outputs
      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 647
  CallFunctionParameters parameters(arity, feedback, tail_call_mode,
                                    convert_mode);
648 649 650
  return new (zone()) Operator1<CallFunctionParameters>(   // --
      IrOpcode::kJSCallFunction, Operator::kNoProperties,  // opcode
      "JSCallFunction",                                    // name
651
      parameters.arity(), 1, 1, 1, 1, 2,                   // inputs/outputs
652
      parameters);                                         // parameter
653 654 655
}


656 657 658 659 660 661
const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) {
  const Runtime::Function* f = Runtime::FunctionForId(id);
  return CallRuntime(f, f->nargs);
}


662 663
const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
                                               size_t arity) {
664 665 666 667 668 669 670 671
  const Runtime::Function* f = Runtime::FunctionForId(id);
  return CallRuntime(f, arity);
}


const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f,
                                               size_t arity) {
  CallRuntimeParameters parameters(f->function_id, arity);
672 673 674 675
  DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
  return new (zone()) Operator1<CallRuntimeParameters>(   // --
      IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
      "JSCallRuntime",                                    // name
676
      parameters.arity(), 1, 1, f->result_size, 1, 2,     // inputs/outputs
677
      parameters);                                        // parameter
678 679 680
}


681 682 683 684
const Operator* JSOperatorBuilder::CallConstruct(
    size_t arity, VectorSlotPair const& feedback) {
  CallConstructParameters parameters(arity, feedback);
  return new (zone()) Operator1<CallConstructParameters>(   // --
685 686
      IrOpcode::kJSCallConstruct, Operator::kNoProperties,  // opcode
      "JSCallConstruct",                                    // name
687 688
      parameters.arity(), 1, 1, 1, 1, 2,                    // counts
      parameters);                                          // parameter
689 690 691
}


692 693 694 695 696 697 698 699 700
const Operator* JSOperatorBuilder::ConvertReceiver(
    ConvertReceiverMode convert_mode) {
  return new (zone()) Operator1<ConvertReceiverMode>(    // --
      IrOpcode::kJSConvertReceiver, Operator::kNoThrow,  // opcode
      "JSConvertReceiver",                               // name
      1, 1, 1, 1, 1, 0,                                  // counts
      convert_mode);                                     // parameter
}

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 706
      IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
      "JSLoadNamed",                                    // name
707
      2, 1, 1, 1, 1, 2,                                 // counts
708
      access);                                          // parameter
709 710
}

711
const Operator* JSOperatorBuilder::LoadProperty(
712 713
    VectorSlotPair const& feedback) {
  PropertyAccess access(SLOPPY, feedback);
714
  return new (zone()) Operator1<PropertyAccess>(           // --
715 716
      IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
      "JSLoadProperty",                                    // name
717
      3, 1, 1, 1, 1, 2,                                    // counts
718
      access);                                             // parameter
719 720
}

721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
const Operator* JSOperatorBuilder::GeneratorStore(int register_count) {
  return new (zone()) Operator1<int>(                   // --
      IrOpcode::kJSGeneratorStore, Operator::kNoThrow,  // opcode
      "JSGeneratorStore",                               // name
      2 + register_count, 1, 1, 0, 1, 0,                // counts
      register_count);                                  // parameter
}

const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) {
  return new (zone()) Operator1<int>(                             // --
      IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow,  // opcode
      "JSGeneratorRestoreRegister",                               // name
      1, 1, 1, 1, 1, 0,                                           // counts
      index);                                                     // parameter
}
736

737
const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
738 739 740 741
                                              Handle<Name> name,
                                              VectorSlotPair const& feedback) {
  NamedAccess access(language_mode, name, feedback);
  return new (zone()) Operator1<NamedAccess>(            // --
742 743
      IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
      "JSStoreNamed",                                    // name
744
      3, 1, 1, 0, 1, 2,                                  // counts
745
      access);                                           // parameter
746 747 748
}


749
const Operator* JSOperatorBuilder::StoreProperty(
750 751 752
    LanguageMode language_mode, VectorSlotPair const& feedback) {
  PropertyAccess access(language_mode, feedback);
  return new (zone()) Operator1<PropertyAccess>(            // --
753 754
      IrOpcode::kJSStoreProperty, Operator::kNoProperties,  // opcode
      "JSStoreProperty",                                    // name
755
      4, 1, 1, 0, 1, 2,                                     // counts
756
      access);                                              // parameter
757 758 759
}


760 761
const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
  return new (zone()) Operator1<LanguageMode>(               // --
762 763
      IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
      "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 772
                                              TypeofMode typeof_mode) {
  LoadGlobalParameters parameters(name, feedback, typeof_mode);
773
  return new (zone()) Operator1<LoadGlobalParameters>(   // --
774 775
      IrOpcode::kJSLoadGlobal, Operator::kNoProperties,  // opcode
      "JSLoadGlobal",                                    // name
776
      1, 1, 1, 1, 1, 2,                                  // counts
777 778 779 780 781
      parameters);                                       // parameter
}


const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
782
                                               const Handle<Name>& name,
783 784
                                               const VectorSlotPair& feedback) {
  StoreGlobalParameters parameters(language_mode, feedback, name);
785
  return new (zone()) Operator1<StoreGlobalParameters>(   // --
786 787
      IrOpcode::kJSStoreGlobal, Operator::kNoProperties,  // opcode
      "JSStoreGlobal",                                    // name
788
      2, 1, 1, 0, 1, 2,                                   // counts
789 790 791 792
      parameters);                                        // parameter
}


793 794 795
const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
                                               bool immutable) {
  ContextAccess access(depth, index, immutable);
796 797 798 799 800 801
  return new (zone()) Operator1<ContextAccess>(  // --
      IrOpcode::kJSLoadContext,                  // opcode
      Operator::kNoWrite | Operator::kNoThrow,   // flags
      "JSLoadContext",                           // name
      1, 1, 0, 1, 1, 0,                          // counts
      access);                                   // parameter
802 803 804 805 806
}


const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
  ContextAccess access(depth, index, false);
807 808 809 810 811 812
  return new (zone()) Operator1<ContextAccess>(  // --
      IrOpcode::kJSStoreContext,                 // opcode
      Operator::kNoRead | Operator::kNoThrow,    // flags
      "JSStoreContext",                          // name
      2, 1, 1, 0, 1, 0,                          // counts
      access);                                   // parameter
813 814 815
}


816
const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
817 818 819 820 821
  return new (zone()) Operator1<CreateArgumentsType>(         // --
      IrOpcode::kJSCreateArguments, Operator::kEliminatable,  // opcode
      "JSCreateArguments",                                    // name
      1, 1, 0, 1, 1, 0,                                       // counts
      type);                                                  // parameter
822
}
823 824


825 826 827 828 829 830 831 832 833 834 835 836 837
const Operator* JSOperatorBuilder::CreateArray(size_t arity,
                                               Handle<AllocationSite> site) {
  // constructor, new_target, arg1, ..., argN
  int const value_input_count = static_cast<int>(arity) + 2;
  CreateArrayParameters parameters(arity, site);
  return new (zone()) Operator1<CreateArrayParameters>(   // --
      IrOpcode::kJSCreateArray, Operator::kNoProperties,  // opcode
      "JSCreateArray",                                    // name
      value_input_count, 1, 1, 1, 1, 2,                   // counts
      parameters);                                        // parameter
}


838 839 840 841 842 843
const Operator* JSOperatorBuilder::CreateClosure(
    Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) {
  CreateClosureParameters parameters(shared_info, pretenure);
  return new (zone()) Operator1<CreateClosureParameters>(  // --
      IrOpcode::kJSCreateClosure, Operator::kNoThrow,      // opcode
      "JSCreateClosure",                                   // name
844
      0, 1, 1, 1, 1, 0,                                    // counts
845 846 847
      parameters);                                         // parameter
}

848
const Operator* JSOperatorBuilder::CreateLiteralArray(
849 850 851 852
    Handle<FixedArray> constant_elements, int literal_flags, int literal_index,
    int number_of_elements) {
  CreateLiteralParameters parameters(constant_elements, number_of_elements,
                                     literal_flags, literal_index);
853
  return new (zone()) Operator1<CreateLiteralParameters>(        // --
854 855
      IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties,  // opcode
      "JSCreateLiteralArray",                                    // name
856 857
      1, 1, 1, 1, 1, 2,                                          // counts
      parameters);                                               // parameter
858 859
}

860 861
const Operator* JSOperatorBuilder::CreateLiteralObject(
    Handle<FixedArray> constant_properties, int literal_flags,
862 863 864
    int literal_index, int number_of_properties) {
  CreateLiteralParameters parameters(constant_properties, number_of_properties,
                                     literal_flags, literal_index);
865
  return new (zone()) Operator1<CreateLiteralParameters>(         // --
866 867
      IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties,  // opcode
      "JSCreateLiteralObject",                                    // name
868
      1, 1, 1, 1, 1, 2,                                           // counts
869 870 871 872 873 874
      parameters);                                                // parameter
}


const Operator* JSOperatorBuilder::CreateLiteralRegExp(
    Handle<String> constant_pattern, int literal_flags, int literal_index) {
875
  CreateLiteralParameters parameters(constant_pattern, -1, literal_flags,
876 877 878 879 880
                                     literal_index);
  return new (zone()) Operator1<CreateLiteralParameters>(         // --
      IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties,  // opcode
      "JSCreateLiteralRegExp",                                    // name
      1, 1, 1, 1, 1, 2,                                           // counts
881
      parameters);                                                // parameter
882 883 884
}


885 886 887 888 889 890 891 892 893
const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) {
  return new (zone()) Operator1<int>(                               // --
      IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties,  // opcode
      "JSCreateFunctionContext",                                    // name
      1, 1, 1, 1, 1, 2,                                             // counts
      slot_count);                                                  // parameter
}


894
const Operator* JSOperatorBuilder::CreateCatchContext(
895
    const Handle<String>& name) {
896
  return new (zone()) Operator1<Handle<String>>(                 // --
897 898
      IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
      "JSCreateCatchContext",                                    // name
899
      2, 1, 1, 1, 1, 2,                                          // counts
900
      name);                                                     // parameter
901 902
}

903 904 905

const Operator* JSOperatorBuilder::CreateBlockContext(
    const Handle<ScopeInfo>& scpope_info) {
906
  return new (zone()) Operator1<Handle<ScopeInfo>>(              // --
907 908 909 910 911 912 913 914 915
      IrOpcode::kJSCreateBlockContext, Operator::kNoProperties,  // opcode
      "JSCreateBlockContext",                                    // name
      1, 1, 1, 1, 1, 2,                                          // counts
      scpope_info);                                              // parameter
}


const Operator* JSOperatorBuilder::CreateScriptContext(
    const Handle<ScopeInfo>& scpope_info) {
916
  return new (zone()) Operator1<Handle<ScopeInfo>>(               // --
917 918 919 920 921 922
      IrOpcode::kJSCreateScriptContext, Operator::kNoProperties,  // opcode
      "JSCreateScriptContext",                                    // name
      1, 1, 1, 1, 1, 2,                                           // counts
      scpope_info);                                               // parameter
}

923 924 925
}  // namespace compiler
}  // namespace internal
}  // namespace v8