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