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