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/js-graph.h" 11#include "src/compiler/js-heap-broker.h" 12#include "src/compiler/node-matchers.h" 13#include "src/compiler/operator.h" 14#include "src/handles/handles-inl.h" 15#include "src/objects/objects-inl.h" 16#include "src/objects/template-objects.h" 17 18namespace v8 { 19namespace internal { 20namespace compiler { 21 22namespace { 23 24// Returns properties for the given binary op. 25constexpr Operator::Properties BinopProperties(Operator::Opcode opcode) { 26 DCHECK(JSOperator::IsBinaryWithFeedback(opcode)); 27 return opcode == IrOpcode::kJSStrictEqual ? Operator::kPure 28 : Operator::kNoProperties; 29} 30 31template <class T> 32Address AddressOrNull(base::Optional<T> ref) { 33 if (!ref.has_value()) return kNullAddress; 34 return ref->object().address(); 35} 36 37} // namespace 38 39namespace js_node_wrapper_utils { 40 41TNode<Oddball> UndefinedConstant(JSGraph* jsgraph) { 42 return TNode<Oddball>::UncheckedCast(jsgraph->UndefinedConstant()); 43} 44 45} // namespace js_node_wrapper_utils 46 47FeedbackCellRef JSCreateClosureNode::GetFeedbackCellRefChecked( 48 JSHeapBroker* broker) const { 49 HeapObjectMatcher m(feedback_cell()); 50 CHECK(m.HasResolvedValue()); 51 return MakeRef(broker, Handle<FeedbackCell>::cast(m.ResolvedValue())); 52} 53 54std::ostream& operator<<(std::ostream& os, CallFrequency const& f) { 55 if (f.IsUnknown()) return os << "unknown"; 56 return os << f.value(); 57} 58 59std::ostream& operator<<(std::ostream& os, 60 ConstructForwardVarargsParameters const& p) { 61 return os << p.arity() << ", " << p.start_index(); 62} 63 64ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf( 65 Operator const* op) { 66 DCHECK_EQ(IrOpcode::kJSConstructForwardVarargs, op->opcode()); 67 return OpParameter<ConstructForwardVarargsParameters>(op); 68} 69 70bool operator==(ConstructParameters const& lhs, 71 ConstructParameters const& rhs) { 72 return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() && 73 lhs.feedback() == rhs.feedback(); 74} 75 76bool operator!=(ConstructParameters const& lhs, 77 ConstructParameters const& rhs) { 78 return !(lhs == rhs); 79} 80 81size_t hash_value(ConstructParameters const& p) { 82 return base::hash_combine(p.arity(), p.frequency(), 83 FeedbackSource::Hash()(p.feedback())); 84} 85 86std::ostream& operator<<(std::ostream& os, ConstructParameters const& p) { 87 return os << p.arity() << ", " << p.frequency(); 88} 89 90ConstructParameters const& ConstructParametersOf(Operator const* op) { 91 DCHECK(op->opcode() == IrOpcode::kJSConstruct || 92 op->opcode() == IrOpcode::kJSConstructWithArrayLike || 93 op->opcode() == IrOpcode::kJSConstructWithSpread); 94 return OpParameter<ConstructParameters>(op); 95} 96 97std::ostream& operator<<(std::ostream& os, CallParameters const& p) { 98 return os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode() 99 << ", " << p.speculation_mode() << ", " << p.feedback_relation(); 100} 101 102const CallParameters& CallParametersOf(const Operator* op) { 103 DCHECK(op->opcode() == IrOpcode::kJSCall || 104 op->opcode() == IrOpcode::kJSCallWithArrayLike || 105 op->opcode() == IrOpcode::kJSCallWithSpread); 106 return OpParameter<CallParameters>(op); 107} 108 109std::ostream& operator<<(std::ostream& os, 110 CallForwardVarargsParameters const& p) { 111 return os << p.arity() << ", " << p.start_index(); 112} 113 114CallForwardVarargsParameters const& CallForwardVarargsParametersOf( 115 Operator const* op) { 116 DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, op->opcode()); 117 return OpParameter<CallForwardVarargsParameters>(op); 118} 119 120 121bool operator==(CallRuntimeParameters const& lhs, 122 CallRuntimeParameters const& rhs) { 123 return lhs.id() == rhs.id() && lhs.arity() == rhs.arity(); 124} 125 126 127bool operator!=(CallRuntimeParameters const& lhs, 128 CallRuntimeParameters const& rhs) { 129 return !(lhs == rhs); 130} 131 132 133size_t hash_value(CallRuntimeParameters const& p) { 134 return base::hash_combine(p.id(), p.arity()); 135} 136 137 138std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) { 139 return os << p.id() << ", " << p.arity(); 140} 141 142 143const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) { 144 DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode()); 145 return OpParameter<CallRuntimeParameters>(op); 146} 147 148 149ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable) 150 : immutable_(immutable), 151 depth_(static_cast<uint16_t>(depth)), 152 index_(static_cast<uint32_t>(index)) { 153 DCHECK(depth <= std::numeric_limits<uint16_t>::max()); 154 DCHECK(index <= std::numeric_limits<uint32_t>::max()); 155} 156 157 158bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) { 159 return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() && 160 lhs.immutable() == rhs.immutable(); 161} 162 163 164bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) { 165 return !(lhs == rhs); 166} 167 168 169size_t hash_value(ContextAccess const& access) { 170 return base::hash_combine(access.depth(), access.index(), access.immutable()); 171} 172 173 174std::ostream& operator<<(std::ostream& os, ContextAccess const& access) { 175 return os << access.depth() << ", " << access.index() << ", " 176 << access.immutable(); 177} 178 179 180ContextAccess const& ContextAccessOf(Operator const* op) { 181 DCHECK(op->opcode() == IrOpcode::kJSLoadContext || 182 op->opcode() == IrOpcode::kJSStoreContext); 183 return OpParameter<ContextAccess>(op); 184} 185 186bool operator==(CreateFunctionContextParameters const& lhs, 187 CreateFunctionContextParameters const& rhs) { 188 return lhs.scope_info_.object().location() == 189 rhs.scope_info_.object().location() && 190 lhs.slot_count() == rhs.slot_count() && 191 lhs.scope_type() == rhs.scope_type(); 192} 193 194bool operator!=(CreateFunctionContextParameters const& lhs, 195 CreateFunctionContextParameters const& rhs) { 196 return !(lhs == rhs); 197} 198 199size_t hash_value(CreateFunctionContextParameters const& parameters) { 200 return base::hash_combine(parameters.scope_info_.object().location(), 201 parameters.slot_count(), 202 static_cast<int>(parameters.scope_type())); 203} 204 205std::ostream& operator<<(std::ostream& os, 206 CreateFunctionContextParameters const& parameters) { 207 return os << parameters.slot_count() << ", " << parameters.scope_type(); 208} 209 210CreateFunctionContextParameters const& CreateFunctionContextParametersOf( 211 Operator const* op) { 212 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, op->opcode()); 213 return OpParameter<CreateFunctionContextParameters>(op); 214} 215 216bool operator==(DefineNamedOwnPropertyParameters const& lhs, 217 DefineNamedOwnPropertyParameters const& rhs) { 218 return lhs.name_.object().location() == rhs.name_.object().location() && 219 lhs.feedback() == rhs.feedback(); 220} 221 222bool operator!=(DefineNamedOwnPropertyParameters const& lhs, 223 DefineNamedOwnPropertyParameters const& rhs) { 224 return !(lhs == rhs); 225} 226 227size_t hash_value(DefineNamedOwnPropertyParameters const& p) { 228 return base::hash_combine(p.name_.object().location(), 229 FeedbackSource::Hash()(p.feedback())); 230} 231 232std::ostream& operator<<(std::ostream& os, 233 DefineNamedOwnPropertyParameters const& p) { 234 return os << Brief(*p.name_.object()); 235} 236 237DefineNamedOwnPropertyParameters const& DefineNamedOwnPropertyParametersOf( 238 const Operator* op) { 239 DCHECK_EQ(IrOpcode::kJSDefineNamedOwnProperty, op->opcode()); 240 return OpParameter<DefineNamedOwnPropertyParameters>(op); 241} 242 243bool operator==(FeedbackParameter const& lhs, FeedbackParameter const& rhs) { 244 return lhs.feedback() == rhs.feedback(); 245} 246 247bool operator!=(FeedbackParameter const& lhs, FeedbackParameter const& rhs) { 248 return !(lhs == rhs); 249} 250 251size_t hash_value(FeedbackParameter const& p) { 252 return FeedbackSource::Hash()(p.feedback()); 253} 254 255std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) { 256 return os << p.feedback(); 257} 258 259FeedbackParameter const& FeedbackParameterOf(const Operator* op) { 260 DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()) || 261 JSOperator::IsBinaryWithFeedback(op->opcode()) || 262 op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray || 263 op->opcode() == IrOpcode::kJSInstanceOf || 264 op->opcode() == IrOpcode::kJSDefineKeyedOwnPropertyInLiteral || 265 op->opcode() == IrOpcode::kJSStoreInArrayLiteral); 266 return OpParameter<FeedbackParameter>(op); 267} 268 269bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) { 270 return lhs.name_.object().location() == rhs.name_.object().location() && 271 lhs.language_mode() == rhs.language_mode() && 272 lhs.feedback() == rhs.feedback(); 273} 274 275 276bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) { 277 return !(lhs == rhs); 278} 279 280 281size_t hash_value(NamedAccess const& p) { 282 return base::hash_combine(p.name_.object().location(), p.language_mode(), 283 FeedbackSource::Hash()(p.feedback())); 284} 285 286 287std::ostream& operator<<(std::ostream& os, NamedAccess const& p) { 288 return os << Brief(*p.name_.object()) << ", " << p.language_mode(); 289} 290 291 292NamedAccess const& NamedAccessOf(const Operator* op) { 293 DCHECK(op->opcode() == IrOpcode::kJSLoadNamed || 294 op->opcode() == IrOpcode::kJSLoadNamedFromSuper || 295 op->opcode() == IrOpcode::kJSSetNamedProperty); 296 return OpParameter<NamedAccess>(op); 297} 298 299 300std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) { 301 return os << p.language_mode() << ", " << p.feedback(); 302} 303 304 305bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) { 306 return lhs.language_mode() == rhs.language_mode() && 307 lhs.feedback() == rhs.feedback(); 308} 309 310 311bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) { 312 return !(lhs == rhs); 313} 314 315 316PropertyAccess const& PropertyAccessOf(const Operator* op) { 317 DCHECK(op->opcode() == IrOpcode::kJSHasProperty || 318 op->opcode() == IrOpcode::kJSLoadProperty || 319 op->opcode() == IrOpcode::kJSSetKeyedProperty || 320 op->opcode() == IrOpcode::kJSDefineKeyedOwnProperty); 321 return OpParameter<PropertyAccess>(op); 322} 323 324 325size_t hash_value(PropertyAccess const& p) { 326 return base::hash_combine(p.language_mode(), 327 FeedbackSource::Hash()(p.feedback())); 328} 329 330 331bool operator==(LoadGlobalParameters const& lhs, 332 LoadGlobalParameters const& rhs) { 333 return lhs.name_.object().location() == rhs.name_.object().location() && 334 lhs.feedback() == rhs.feedback() && 335 lhs.typeof_mode() == rhs.typeof_mode(); 336} 337 338 339bool operator!=(LoadGlobalParameters const& lhs, 340 LoadGlobalParameters const& rhs) { 341 return !(lhs == rhs); 342} 343 344 345size_t hash_value(LoadGlobalParameters const& p) { 346 return base::hash_combine(p.name_.object().location(), 347 static_cast<int>(p.typeof_mode())); 348} 349 350 351std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) { 352 return os << Brief(*p.name_.object()) << ", " 353 << static_cast<int>(p.typeof_mode()); 354} 355 356 357const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) { 358 DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode()); 359 return OpParameter<LoadGlobalParameters>(op); 360} 361 362 363bool operator==(StoreGlobalParameters const& lhs, 364 StoreGlobalParameters const& rhs) { 365 return lhs.language_mode() == rhs.language_mode() && 366 lhs.name_.object().location() == rhs.name_.object().location() && 367 lhs.feedback() == rhs.feedback(); 368} 369 370 371bool operator!=(StoreGlobalParameters const& lhs, 372 StoreGlobalParameters const& rhs) { 373 return !(lhs == rhs); 374} 375 376 377size_t hash_value(StoreGlobalParameters const& p) { 378 return base::hash_combine(p.language_mode(), p.name_.object().location(), 379 FeedbackSource::Hash()(p.feedback())); 380} 381 382 383std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) { 384 return os << p.language_mode() << ", " << Brief(*p.name_.object()); 385} 386 387 388const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) { 389 DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode()); 390 return OpParameter<StoreGlobalParameters>(op); 391} 392 393 394CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) { 395 DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode()); 396 return OpParameter<CreateArgumentsType>(op); 397} 398 399bool operator==(CreateArrayParameters const& lhs, 400 CreateArrayParameters const& rhs) { 401 return lhs.arity() == rhs.arity() && 402 AddressOrNull(lhs.site_) == AddressOrNull(rhs.site_); 403} 404 405 406bool operator!=(CreateArrayParameters const& lhs, 407 CreateArrayParameters const& rhs) { 408 return !(lhs == rhs); 409} 410 411 412size_t hash_value(CreateArrayParameters const& p) { 413 return base::hash_combine(p.arity(), AddressOrNull(p.site_)); 414} 415 416 417std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) { 418 os << p.arity(); 419 if (p.site_.has_value()) { 420 os << ", " << Brief(*p.site_->object()); 421 } 422 return os; 423} 424 425const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) { 426 DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode()); 427 return OpParameter<CreateArrayParameters>(op); 428} 429 430bool operator==(CreateArrayIteratorParameters const& lhs, 431 CreateArrayIteratorParameters const& rhs) { 432 return lhs.kind() == rhs.kind(); 433} 434 435bool operator!=(CreateArrayIteratorParameters const& lhs, 436 CreateArrayIteratorParameters const& rhs) { 437 return !(lhs == rhs); 438} 439 440size_t hash_value(CreateArrayIteratorParameters const& p) { 441 return static_cast<size_t>(p.kind()); 442} 443 444std::ostream& operator<<(std::ostream& os, 445 CreateArrayIteratorParameters const& p) { 446 return os << p.kind(); 447} 448 449const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf( 450 const Operator* op) { 451 DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, op->opcode()); 452 return OpParameter<CreateArrayIteratorParameters>(op); 453} 454 455bool operator==(CreateCollectionIteratorParameters const& lhs, 456 CreateCollectionIteratorParameters const& rhs) { 457 return lhs.collection_kind() == rhs.collection_kind() && 458 lhs.iteration_kind() == rhs.iteration_kind(); 459} 460 461bool operator!=(CreateCollectionIteratorParameters const& lhs, 462 CreateCollectionIteratorParameters const& rhs) { 463 return !(lhs == rhs); 464} 465 466size_t hash_value(CreateCollectionIteratorParameters const& p) { 467 return base::hash_combine(static_cast<size_t>(p.collection_kind()), 468 static_cast<size_t>(p.iteration_kind())); 469} 470 471std::ostream& operator<<(std::ostream& os, 472 CreateCollectionIteratorParameters const& p) { 473 return os << p.collection_kind() << ", " << p.iteration_kind(); 474} 475 476const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf( 477 const Operator* op) { 478 DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, op->opcode()); 479 return OpParameter<CreateCollectionIteratorParameters>(op); 480} 481 482bool operator==(CreateBoundFunctionParameters const& lhs, 483 CreateBoundFunctionParameters const& rhs) { 484 return lhs.arity() == rhs.arity() && 485 lhs.map_.object().location() == rhs.map_.object().location(); 486} 487 488bool operator!=(CreateBoundFunctionParameters const& lhs, 489 CreateBoundFunctionParameters const& rhs) { 490 return !(lhs == rhs); 491} 492 493size_t hash_value(CreateBoundFunctionParameters const& p) { 494 return base::hash_combine(p.arity(), p.map_.object().location()); 495} 496 497std::ostream& operator<<(std::ostream& os, 498 CreateBoundFunctionParameters const& p) { 499 os << p.arity(); 500 if (!p.map_.object().is_null()) os << ", " << Brief(*p.map_.object()); 501 return os; 502} 503 504const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf( 505 const Operator* op) { 506 DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, op->opcode()); 507 return OpParameter<CreateBoundFunctionParameters>(op); 508} 509 510bool operator==(GetTemplateObjectParameters const& lhs, 511 GetTemplateObjectParameters const& rhs) { 512 return lhs.description_.object().location() == 513 rhs.description_.object().location() && 514 lhs.shared_.object().location() == rhs.shared_.object().location() && 515 lhs.feedback() == rhs.feedback(); 516} 517 518bool operator!=(GetTemplateObjectParameters const& lhs, 519 GetTemplateObjectParameters const& rhs) { 520 return !(lhs == rhs); 521} 522 523size_t hash_value(GetTemplateObjectParameters const& p) { 524 return base::hash_combine(p.description_.object().location(), 525 p.shared_.object().location(), 526 FeedbackSource::Hash()(p.feedback())); 527} 528 529std::ostream& operator<<(std::ostream& os, 530 GetTemplateObjectParameters const& p) { 531 return os << Brief(*p.description_.object()) << ", " 532 << Brief(*p.shared_.object()); 533} 534 535const GetTemplateObjectParameters& GetTemplateObjectParametersOf( 536 const Operator* op) { 537 DCHECK(op->opcode() == IrOpcode::kJSGetTemplateObject); 538 return OpParameter<GetTemplateObjectParameters>(op); 539} 540 541bool operator==(CreateClosureParameters const& lhs, 542 CreateClosureParameters const& rhs) { 543 return lhs.allocation() == rhs.allocation() && 544 lhs.code_.object().location() == rhs.code_.object().location() && 545 lhs.shared_info_.object().location() == 546 rhs.shared_info_.object().location(); 547} 548 549 550bool operator!=(CreateClosureParameters const& lhs, 551 CreateClosureParameters const& rhs) { 552 return !(lhs == rhs); 553} 554 555 556size_t hash_value(CreateClosureParameters const& p) { 557 return base::hash_combine(p.allocation(), p.code_.object().location(), 558 p.shared_info_.object().location()); 559} 560 561 562std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) { 563 return os << p.allocation() << ", " << Brief(*p.shared_info_.object()) << ", " 564 << Brief(*p.code_.object()); 565} 566 567 568const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) { 569 DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode()); 570 return OpParameter<CreateClosureParameters>(op); 571} 572 573 574bool operator==(CreateLiteralParameters const& lhs, 575 CreateLiteralParameters const& rhs) { 576 return lhs.constant_.object().location() == 577 rhs.constant_.object().location() && 578 lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() && 579 lhs.flags() == rhs.flags(); 580} 581 582 583bool operator!=(CreateLiteralParameters const& lhs, 584 CreateLiteralParameters const& rhs) { 585 return !(lhs == rhs); 586} 587 588 589size_t hash_value(CreateLiteralParameters const& p) { 590 return base::hash_combine(p.constant_.object().location(), 591 FeedbackSource::Hash()(p.feedback()), p.length(), 592 p.flags()); 593} 594 595 596std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) { 597 return os << Brief(*p.constant_.object()) << ", " << p.length() << ", " 598 << p.flags(); 599} 600 601 602const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) { 603 DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray || 604 op->opcode() == IrOpcode::kJSCreateLiteralObject || 605 op->opcode() == IrOpcode::kJSCreateLiteralRegExp); 606 return OpParameter<CreateLiteralParameters>(op); 607} 608 609bool operator==(CloneObjectParameters const& lhs, 610 CloneObjectParameters const& rhs) { 611 return lhs.feedback() == rhs.feedback() && lhs.flags() == rhs.flags(); 612} 613 614bool operator!=(CloneObjectParameters const& lhs, 615 CloneObjectParameters const& rhs) { 616 return !(lhs == rhs); 617} 618 619size_t hash_value(CloneObjectParameters const& p) { 620 return base::hash_combine(FeedbackSource::Hash()(p.feedback()), p.flags()); 621} 622 623std::ostream& operator<<(std::ostream& os, CloneObjectParameters const& p) { 624 return os << p.flags(); 625} 626 627const CloneObjectParameters& CloneObjectParametersOf(const Operator* op) { 628 DCHECK(op->opcode() == IrOpcode::kJSCloneObject); 629 return OpParameter<CloneObjectParameters>(op); 630} 631 632std::ostream& operator<<(std::ostream& os, GetIteratorParameters const& p) { 633 return os << p.loadFeedback() << ", " << p.callFeedback(); 634} 635 636bool operator==(GetIteratorParameters const& lhs, 637 GetIteratorParameters const& rhs) { 638 return lhs.loadFeedback() == rhs.loadFeedback() && 639 lhs.callFeedback() == rhs.callFeedback(); 640} 641 642bool operator!=(GetIteratorParameters const& lhs, 643 GetIteratorParameters const& rhs) { 644 return !(lhs == rhs); 645} 646 647GetIteratorParameters const& GetIteratorParametersOf(const Operator* op) { 648 DCHECK(op->opcode() == IrOpcode::kJSGetIterator); 649 return OpParameter<GetIteratorParameters>(op); 650} 651 652size_t hash_value(GetIteratorParameters const& p) { 653 return base::hash_combine(FeedbackSource::Hash()(p.loadFeedback()), 654 FeedbackSource::Hash()(p.callFeedback())); 655} 656 657size_t hash_value(ForInMode const& mode) { return static_cast<uint8_t>(mode); } 658 659std::ostream& operator<<(std::ostream& os, ForInMode const& mode) { 660 switch (mode) { 661 case ForInMode::kUseEnumCacheKeysAndIndices: 662 return os << "UseEnumCacheKeysAndIndices"; 663 case ForInMode::kUseEnumCacheKeys: 664 return os << "UseEnumCacheKeys"; 665 case ForInMode::kGeneric: 666 return os << "Generic"; 667 } 668 UNREACHABLE(); 669} 670 671bool operator==(ForInParameters const& lhs, ForInParameters const& rhs) { 672 return lhs.feedback() == rhs.feedback() && lhs.mode() == rhs.mode(); 673} 674 675bool operator!=(ForInParameters const& lhs, ForInParameters const& rhs) { 676 return !(lhs == rhs); 677} 678 679size_t hash_value(ForInParameters const& p) { 680 return base::hash_combine(FeedbackSource::Hash()(p.feedback()), p.mode()); 681} 682 683std::ostream& operator<<(std::ostream& os, ForInParameters const& p) { 684 return os << p.feedback() << ", " << p.mode(); 685} 686 687ForInParameters const& ForInParametersOf(const Operator* op) { 688 DCHECK(op->opcode() == IrOpcode::kJSForInNext || 689 op->opcode() == IrOpcode::kJSForInPrepare); 690 return OpParameter<ForInParameters>(op); 691} 692 693#if V8_ENABLE_WEBASSEMBLY 694JSWasmCallParameters const& JSWasmCallParametersOf(const Operator* op) { 695 DCHECK_EQ(IrOpcode::kJSWasmCall, op->opcode()); 696 return OpParameter<JSWasmCallParameters>(op); 697} 698 699std::ostream& operator<<(std::ostream& os, JSWasmCallParameters const& p) { 700 return os << p.module() << ", " << p.signature() << ", " << p.feedback(); 701} 702 703size_t hash_value(JSWasmCallParameters const& p) { 704 return base::hash_combine(p.module(), p.signature(), 705 FeedbackSource::Hash()(p.feedback())); 706} 707 708bool operator==(JSWasmCallParameters const& lhs, 709 JSWasmCallParameters const& rhs) { 710 return lhs.module() == rhs.module() && lhs.signature() == rhs.signature() && 711 lhs.feedback() == rhs.feedback(); 712} 713 714int JSWasmCallParameters::arity_without_implicit_args() const { 715 return static_cast<int>(signature_->parameter_count()); 716} 717 718int JSWasmCallParameters::input_count() const { 719 return static_cast<int>(signature_->parameter_count()) + 720 JSWasmCallNode::kExtraInputCount; 721} 722 723// static 724Type JSWasmCallNode::TypeForWasmReturnType(const wasm::ValueType& type) { 725 switch (type.kind()) { 726 case wasm::kI32: 727 return Type::Signed32(); 728 case wasm::kI64: 729 return Type::BigInt(); 730 case wasm::kF32: 731 case wasm::kF64: 732 return Type::Number(); 733 default: 734 UNREACHABLE(); 735 } 736} 737#endif // V8_ENABLE_WEBASSEMBLY 738 739#define CACHED_OP_LIST(V) \ 740 V(ToLength, Operator::kNoProperties, 1, 1) \ 741 V(ToName, Operator::kNoProperties, 1, 1) \ 742 V(ToNumber, Operator::kNoProperties, 1, 1) \ 743 V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1) \ 744 V(ToNumeric, Operator::kNoProperties, 1, 1) \ 745 V(ToObject, Operator::kFoldable, 1, 1) \ 746 V(ToString, Operator::kNoProperties, 1, 1) \ 747 V(Create, Operator::kNoProperties, 2, 1) \ 748 V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \ 749 V(CreateStringIterator, Operator::kEliminatable, 1, 1) \ 750 V(CreateKeyValueArray, Operator::kEliminatable, 2, 1) \ 751 V(CreatePromise, Operator::kEliminatable, 0, 1) \ 752 V(CreateTypedArray, Operator::kNoProperties, 5, 1) \ 753 V(CreateObject, Operator::kNoProperties, 1, 1) \ 754 V(ObjectIsArray, Operator::kNoProperties, 1, 1) \ 755 V(HasInPrototypeChain, Operator::kNoProperties, 2, 1) \ 756 V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1) \ 757 V(ForInEnumerate, Operator::kNoProperties, 1, 1) \ 758 V(AsyncFunctionEnter, Operator::kNoProperties, 2, 1) \ 759 V(AsyncFunctionReject, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 760 V(AsyncFunctionResolve, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 761 V(LoadMessage, Operator::kNoThrow | Operator::kNoWrite, 0, 1) \ 762 V(StoreMessage, Operator::kNoRead | Operator::kNoThrow, 1, 0) \ 763 V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \ 764 V(GeneratorRestoreContext, Operator::kNoThrow, 1, 1) \ 765 V(GeneratorRestoreInputOrDebugPos, Operator::kNoThrow, 1, 1) \ 766 V(Debugger, Operator::kNoProperties, 0, 0) \ 767 V(FulfillPromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 768 V(PerformPromiseThen, Operator::kNoDeopt | Operator::kNoThrow, 4, 1) \ 769 V(PromiseResolve, Operator::kNoProperties, 2, 1) \ 770 V(RejectPromise, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \ 771 V(ResolvePromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 772 V(GetSuperConstructor, Operator::kNoWrite | Operator::kNoThrow, 1, 1) \ 773 V(ParseInt, Operator::kNoProperties, 2, 1) \ 774 V(RegExpTest, Operator::kNoProperties, 2, 1) 775 776struct JSOperatorGlobalCache final { 777#define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 778 struct Name##Operator final : public Operator { \ 779 Name##Operator() \ 780 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ 781 value_input_count, Operator::ZeroIfPure(properties), \ 782 Operator::ZeroIfEliminatable(properties), \ 783 value_output_count, Operator::ZeroIfPure(properties), \ 784 Operator::ZeroIfNoThrow(properties)) {} \ 785 }; \ 786 Name##Operator k##Name##Operator; 787 CACHED_OP_LIST(CACHED_OP) 788#undef CACHED_OP 789}; 790 791namespace { 792DEFINE_LAZY_LEAKY_OBJECT_GETTER(JSOperatorGlobalCache, GetJSOperatorGlobalCache) 793} // namespace 794 795JSOperatorBuilder::JSOperatorBuilder(Zone* zone) 796 : cache_(*GetJSOperatorGlobalCache()), zone_(zone) {} 797 798#define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 799 const Operator* JSOperatorBuilder::Name() { \ 800 return &cache_.k##Name##Operator; \ 801 } 802CACHED_OP_LIST(CACHED_OP) 803#undef CACHED_OP 804 805#define UNARY_OP(JSName, Name) \ 806 const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \ 807 FeedbackParameter parameters(feedback); \ 808 return zone()->New<Operator1<FeedbackParameter>>( \ 809 IrOpcode::k##JSName, Operator::kNoProperties, #JSName, 2, 1, 1, 1, 1, \ 810 2, parameters); \ 811 } 812JS_UNOP_WITH_FEEDBACK(UNARY_OP) 813#undef UNARY_OP 814 815#define BINARY_OP(JSName, Name) \ 816 const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \ 817 static constexpr auto kProperties = BinopProperties(IrOpcode::k##JSName); \ 818 FeedbackParameter parameters(feedback); \ 819 return zone()->New<Operator1<FeedbackParameter>>( \ 820 IrOpcode::k##JSName, kProperties, #JSName, 3, 1, 1, 1, 1, \ 821 Operator::ZeroIfNoThrow(kProperties), parameters); \ 822 } 823JS_BINOP_WITH_FEEDBACK(BINARY_OP) 824#undef BINARY_OP 825 826const Operator* JSOperatorBuilder::DefineKeyedOwnPropertyInLiteral( 827 const FeedbackSource& feedback) { 828 static constexpr int kObject = 1; 829 static constexpr int kName = 1; 830 static constexpr int kValue = 1; 831 static constexpr int kFlags = 1; 832 static constexpr int kFeedbackVector = 1; 833 static constexpr int kArity = 834 kObject + kName + kValue + kFlags + kFeedbackVector; 835 FeedbackParameter parameters(feedback); 836 return zone()->New<Operator1<FeedbackParameter>>( // -- 837 IrOpcode::kJSDefineKeyedOwnPropertyInLiteral, 838 Operator::kNoThrow, // opcode 839 "JSDefineKeyedOwnPropertyInLiteral", // name 840 kArity, 1, 1, 0, 1, 1, // counts 841 parameters); // parameter 842} 843 844const Operator* JSOperatorBuilder::StoreInArrayLiteral( 845 const FeedbackSource& feedback) { 846 static constexpr int kArray = 1; 847 static constexpr int kIndex = 1; 848 static constexpr int kValue = 1; 849 static constexpr int kFeedbackVector = 1; 850 static constexpr int kArity = kArray + kIndex + kValue + kFeedbackVector; 851 FeedbackParameter parameters(feedback); 852 return zone()->New<Operator1<FeedbackParameter>>( // -- 853 IrOpcode::kJSStoreInArrayLiteral, 854 Operator::kNoThrow, // opcode 855 "JSStoreInArrayLiteral", // name 856 kArity, 1, 1, 0, 1, 1, // counts 857 parameters); // parameter 858} 859 860const Operator* JSOperatorBuilder::CallForwardVarargs(size_t arity, 861 uint32_t start_index) { 862 CallForwardVarargsParameters parameters(arity, start_index); 863 return zone()->New<Operator1<CallForwardVarargsParameters>>( // -- 864 IrOpcode::kJSCallForwardVarargs, Operator::kNoProperties, // opcode 865 "JSCallForwardVarargs", // name 866 parameters.arity(), 1, 1, 1, 1, 2, // counts 867 parameters); // parameter 868} 869 870const Operator* JSOperatorBuilder::Call( 871 size_t arity, CallFrequency const& frequency, 872 FeedbackSource const& feedback, ConvertReceiverMode convert_mode, 873 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation) { 874 CallParameters parameters(arity, frequency, feedback, convert_mode, 875 speculation_mode, feedback_relation); 876 return zone()->New<Operator1<CallParameters>>( // -- 877 IrOpcode::kJSCall, Operator::kNoProperties, // opcode 878 "JSCall", // name 879 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs 880 parameters); // parameter 881} 882 883const Operator* JSOperatorBuilder::CallWithArrayLike( 884 const CallFrequency& frequency, const FeedbackSource& feedback, 885 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation) { 886 static constexpr int kTheArrayLikeObject = 1; 887 CallParameters parameters( 888 JSCallWithArrayLikeNode::ArityForArgc(kTheArrayLikeObject), frequency, 889 feedback, ConvertReceiverMode::kAny, speculation_mode, feedback_relation); 890 return zone()->New<Operator1<CallParameters>>( // -- 891 IrOpcode::kJSCallWithArrayLike, Operator::kNoProperties, // opcode 892 "JSCallWithArrayLike", // name 893 parameters.arity(), 1, 1, 1, 1, 2, // counts 894 parameters); // parameter 895} 896 897const Operator* JSOperatorBuilder::CallWithSpread( 898 uint32_t arity, CallFrequency const& frequency, 899 FeedbackSource const& feedback, SpeculationMode speculation_mode, 900 CallFeedbackRelation feedback_relation) { 901 DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation, 902 feedback.IsValid()); 903 CallParameters parameters(arity, frequency, feedback, 904 ConvertReceiverMode::kAny, speculation_mode, 905 feedback_relation); 906 return zone()->New<Operator1<CallParameters>>( // -- 907 IrOpcode::kJSCallWithSpread, Operator::kNoProperties, // opcode 908 "JSCallWithSpread", // name 909 parameters.arity(), 1, 1, 1, 1, 2, // counts 910 parameters); // parameter 911} 912 913const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) { 914 const Runtime::Function* f = Runtime::FunctionForId(id); 915 return CallRuntime(f, f->nargs); 916} 917 918 919const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, 920 size_t arity) { 921 const Runtime::Function* f = Runtime::FunctionForId(id); 922 return CallRuntime(f, arity); 923} 924 925 926const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f, 927 size_t arity) { 928 CallRuntimeParameters parameters(f->function_id, arity); 929 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); 930 return zone()->New<Operator1<CallRuntimeParameters>>( // -- 931 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode 932 "JSCallRuntime", // name 933 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs 934 parameters); // parameter 935} 936 937#if V8_ENABLE_WEBASSEMBLY 938const Operator* JSOperatorBuilder::CallWasm( 939 const wasm::WasmModule* wasm_module, 940 const wasm::FunctionSig* wasm_signature, FeedbackSource const& feedback) { 941 JSWasmCallParameters parameters(wasm_module, wasm_signature, feedback); 942 return zone()->New<Operator1<JSWasmCallParameters>>( 943 IrOpcode::kJSWasmCall, Operator::kNoProperties, // opcode 944 "JSWasmCall", // name 945 parameters.input_count(), 1, 1, 1, 1, 2, // inputs/outputs 946 parameters); // parameter 947} 948#endif // V8_ENABLE_WEBASSEMBLY 949 950const Operator* JSOperatorBuilder::ConstructForwardVarargs( 951 size_t arity, uint32_t start_index) { 952 ConstructForwardVarargsParameters parameters(arity, start_index); 953 return zone()->New<Operator1<ConstructForwardVarargsParameters>>( // -- 954 IrOpcode::kJSConstructForwardVarargs, Operator::kNoProperties, // opcode 955 "JSConstructForwardVarargs", // name 956 parameters.arity(), 1, 1, 1, 1, 2, // counts 957 parameters); // parameter 958} 959 960// Note: frequency is taken by reference to work around a GCC bug 961// on AIX (v8:8193). 962const Operator* JSOperatorBuilder::Construct(uint32_t arity, 963 CallFrequency const& frequency, 964 FeedbackSource const& feedback) { 965 ConstructParameters parameters(arity, frequency, feedback); 966 return zone()->New<Operator1<ConstructParameters>>( // -- 967 IrOpcode::kJSConstruct, Operator::kNoProperties, // opcode 968 "JSConstruct", // name 969 parameters.arity(), 1, 1, 1, 1, 2, // counts 970 parameters); // parameter 971} 972 973const Operator* JSOperatorBuilder::ConstructWithArrayLike( 974 CallFrequency const& frequency, FeedbackSource const& feedback) { 975 static constexpr int kTheArrayLikeObject = 1; 976 ConstructParameters parameters( 977 JSConstructWithArrayLikeNode::ArityForArgc(kTheArrayLikeObject), 978 frequency, feedback); 979 return zone()->New<Operator1<ConstructParameters>>( // -- 980 IrOpcode::kJSConstructWithArrayLike, // opcode 981 Operator::kNoProperties, // properties 982 "JSConstructWithArrayLike", // name 983 parameters.arity(), 1, 1, 1, 1, 2, // counts 984 parameters); // parameter 985} 986 987const Operator* JSOperatorBuilder::ConstructWithSpread( 988 uint32_t arity, CallFrequency const& frequency, 989 FeedbackSource const& feedback) { 990 ConstructParameters parameters(arity, frequency, feedback); 991 return zone()->New<Operator1<ConstructParameters>>( // -- 992 IrOpcode::kJSConstructWithSpread, Operator::kNoProperties, // opcode 993 "JSConstructWithSpread", // name 994 parameters.arity(), 1, 1, 1, 1, 2, // counts 995 parameters); // parameter 996} 997 998const Operator* JSOperatorBuilder::LoadNamed(const NameRef& name, 999 const FeedbackSource& feedback) { 1000 static constexpr int kObject = 1; 1001 static constexpr int kFeedbackVector = 1; 1002 static constexpr int kArity = kObject + kFeedbackVector; 1003 NamedAccess access(LanguageMode::kSloppy, name, feedback); 1004 return zone()->New<Operator1<NamedAccess>>( // -- 1005 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode 1006 "JSLoadNamed", // name 1007 kArity, 1, 1, 1, 1, 2, // counts 1008 access); // parameter 1009} 1010 1011const Operator* JSOperatorBuilder::LoadNamedFromSuper( 1012 const NameRef& name, const FeedbackSource& feedback) { 1013 static constexpr int kReceiver = 1; 1014 static constexpr int kHomeObject = 1; 1015 static constexpr int kFeedbackVector = 1; 1016 static constexpr int kArity = kReceiver + kHomeObject + kFeedbackVector; 1017 NamedAccess access(LanguageMode::kSloppy, name, feedback); 1018 return zone()->New<Operator1<NamedAccess>>( // -- 1019 IrOpcode::kJSLoadNamedFromSuper, Operator::kNoProperties, // opcode 1020 "JSLoadNamedFromSuper", // name 1021 kArity, 1, 1, 1, 1, 2, // counts 1022 access); // parameter 1023} 1024 1025const Operator* JSOperatorBuilder::LoadProperty( 1026 FeedbackSource const& feedback) { 1027 PropertyAccess access(LanguageMode::kSloppy, feedback); 1028 return zone()->New<Operator1<PropertyAccess>>( // -- 1029 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode 1030 "JSLoadProperty", // name 1031 3, 1, 1, 1, 1, 2, // counts 1032 access); // parameter 1033} 1034 1035const Operator* JSOperatorBuilder::GetIterator( 1036 FeedbackSource const& load_feedback, FeedbackSource const& call_feedback) { 1037 GetIteratorParameters access(load_feedback, call_feedback); 1038 return zone()->New<Operator1<GetIteratorParameters>>( // -- 1039 IrOpcode::kJSGetIterator, Operator::kNoProperties, // opcode 1040 "JSGetIterator", // name 1041 2, 1, 1, 1, 1, 2, // counts 1042 access); // parameter 1043} 1044 1045const Operator* JSOperatorBuilder::HasProperty(FeedbackSource const& feedback) { 1046 PropertyAccess access(LanguageMode::kSloppy, feedback); 1047 return zone()->New<Operator1<PropertyAccess>>( // -- 1048 IrOpcode::kJSHasProperty, Operator::kNoProperties, // opcode 1049 "JSHasProperty", // name 1050 3, 1, 1, 1, 1, 2, // counts 1051 access); // parameter 1052} 1053 1054const Operator* JSOperatorBuilder::ForInNext(ForInMode mode, 1055 const FeedbackSource& feedback) { 1056 return zone()->New<Operator1<ForInParameters>>( // -- 1057 IrOpcode::kJSForInNext, Operator::kNoProperties, // opcode 1058 "JSForInNext", // name 1059 5, 1, 1, 1, 1, 2, // counts 1060 ForInParameters{feedback, mode}); // parameter 1061} 1062 1063const Operator* JSOperatorBuilder::ForInPrepare( 1064 ForInMode mode, const FeedbackSource& feedback) { 1065 return zone()->New<Operator1<ForInParameters>>( // -- 1066 IrOpcode::kJSForInPrepare, // opcode 1067 Operator::kNoWrite | Operator::kNoThrow, // flags 1068 "JSForInPrepare", // name 1069 2, 1, 1, 3, 1, 1, // counts 1070 ForInParameters{feedback, mode}); // parameter 1071} 1072 1073const Operator* JSOperatorBuilder::GeneratorStore(int register_count) { 1074 return zone()->New<Operator1<int>>( // -- 1075 IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode 1076 "JSGeneratorStore", // name 1077 3 + register_count, 1, 1, 0, 1, 0, // counts 1078 register_count); // parameter 1079} 1080 1081int RegisterCountOf(Operator const* op) { 1082 DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, op->opcode()); 1083 return OpParameter<int>(op); 1084} 1085 1086int GeneratorStoreValueCountOf(const Operator* op) { 1087 DCHECK_EQ(IrOpcode::kJSGeneratorStore, op->opcode()); 1088 return OpParameter<int>(op); 1089} 1090 1091const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) { 1092 return zone()->New<Operator1<int>>( // -- 1093 IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow, // opcode 1094 "JSGeneratorRestoreRegister", // name 1095 1, 1, 1, 1, 1, 0, // counts 1096 index); // parameter 1097} 1098 1099int RestoreRegisterIndexOf(const Operator* op) { 1100 DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, op->opcode()); 1101 return OpParameter<int>(op); 1102} 1103 1104const Operator* JSOperatorBuilder::SetNamedProperty( 1105 LanguageMode language_mode, const NameRef& name, 1106 FeedbackSource const& feedback) { 1107 static constexpr int kObject = 1; 1108 static constexpr int kValue = 1; 1109 static constexpr int kFeedbackVector = 1; 1110 static constexpr int kArity = kObject + kValue + kFeedbackVector; 1111 NamedAccess access(language_mode, name, feedback); 1112 return zone()->New<Operator1<NamedAccess>>( // -- 1113 IrOpcode::kJSSetNamedProperty, Operator::kNoProperties, // opcode 1114 "JSSetNamedProperty", // name 1115 kArity, 1, 1, 0, 1, 2, // counts 1116 access); // parameter 1117} 1118 1119const Operator* JSOperatorBuilder::SetKeyedProperty( 1120 LanguageMode language_mode, FeedbackSource const& feedback) { 1121 PropertyAccess access(language_mode, feedback); 1122 return zone()->New<Operator1<PropertyAccess>>( // -- 1123 IrOpcode::kJSSetKeyedProperty, Operator::kNoProperties, // opcode 1124 "JSSetKeyedProperty", // name 1125 4, 1, 1, 0, 1, 2, // counts 1126 access); // parameter 1127} 1128 1129const Operator* JSOperatorBuilder::DefineKeyedOwnProperty( 1130 LanguageMode language_mode, FeedbackSource const& feedback) { 1131 PropertyAccess access(language_mode, feedback); 1132 return zone()->New<Operator1<PropertyAccess>>( // -- 1133 IrOpcode::kJSDefineKeyedOwnProperty, Operator::kNoProperties, // opcode 1134 "JSDefineKeyedOwnProperty", // name 1135 4, 1, 1, 0, 1, 2, // counts 1136 access); // parameter 1137} 1138 1139const Operator* JSOperatorBuilder::DefineNamedOwnProperty( 1140 const NameRef& name, FeedbackSource const& feedback) { 1141 static constexpr int kObject = 1; 1142 static constexpr int kValue = 1; 1143 static constexpr int kFeedbackVector = 1; 1144 static constexpr int kArity = kObject + kValue + kFeedbackVector; 1145 DefineNamedOwnPropertyParameters parameters(name, feedback); 1146 return zone()->New<Operator1<DefineNamedOwnPropertyParameters>>( // -- 1147 IrOpcode::kJSDefineNamedOwnProperty, Operator::kNoProperties, // opcode 1148 "JSDefineNamedOwnProperty", // name 1149 kArity, 1, 1, 0, 1, 2, // counts 1150 parameters); // parameter 1151} 1152 1153const Operator* JSOperatorBuilder::DeleteProperty() { 1154 return zone()->New<Operator>( // -- 1155 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode 1156 "JSDeleteProperty", // name 1157 3, 1, 1, 1, 1, 2); // counts 1158} 1159 1160const Operator* JSOperatorBuilder::CreateGeneratorObject() { 1161 return zone()->New<Operator>( // -- 1162 IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable, // opcode 1163 "JSCreateGeneratorObject", // name 1164 2, 1, 1, 1, 1, 0); // counts 1165} 1166 1167const Operator* JSOperatorBuilder::LoadGlobal(const NameRef& name, 1168 const FeedbackSource& feedback, 1169 TypeofMode typeof_mode) { 1170 static constexpr int kFeedbackVector = 1; 1171 static constexpr int kArity = kFeedbackVector; 1172 LoadGlobalParameters parameters(name, feedback, typeof_mode); 1173 return zone()->New<Operator1<LoadGlobalParameters>>( // -- 1174 IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode 1175 "JSLoadGlobal", // name 1176 kArity, 1, 1, 1, 1, 2, // counts 1177 parameters); // parameter 1178} 1179 1180const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode, 1181 const NameRef& name, 1182 const FeedbackSource& feedback) { 1183 static constexpr int kValue = 1; 1184 static constexpr int kFeedbackVector = 1; 1185 static constexpr int kArity = kValue + kFeedbackVector; 1186 StoreGlobalParameters parameters(language_mode, feedback, name); 1187 return zone()->New<Operator1<StoreGlobalParameters>>( // -- 1188 IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode 1189 "JSStoreGlobal", // name 1190 kArity, 1, 1, 0, 1, 2, // counts 1191 parameters); // parameter 1192} 1193 1194const Operator* JSOperatorBuilder::HasContextExtension(size_t depth) { 1195 return zone()->New<Operator1<size_t>>( // -- 1196 IrOpcode::kJSHasContextExtension, // opcode 1197 Operator::kNoWrite | Operator::kNoThrow, // flags 1198 "JSHasContextExtension", // name 1199 0, 1, 0, 1, 1, 0, // counts 1200 depth); // parameter 1201} 1202 1203const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, 1204 bool immutable) { 1205 ContextAccess access(depth, index, immutable); 1206 return zone()->New<Operator1<ContextAccess>>( // -- 1207 IrOpcode::kJSLoadContext, // opcode 1208 Operator::kNoWrite | Operator::kNoThrow, // flags 1209 "JSLoadContext", // name 1210 0, 1, 0, 1, 1, 0, // counts 1211 access); // parameter 1212} 1213 1214 1215const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { 1216 ContextAccess access(depth, index, false); 1217 return zone()->New<Operator1<ContextAccess>>( // -- 1218 IrOpcode::kJSStoreContext, // opcode 1219 Operator::kNoRead | Operator::kNoThrow, // flags 1220 "JSStoreContext", // name 1221 1, 1, 1, 0, 1, 0, // counts 1222 access); // parameter 1223} 1224 1225const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) { 1226 return zone()->New<Operator1<int32_t>>( // -- 1227 IrOpcode::kJSLoadModule, // opcode 1228 Operator::kNoWrite | Operator::kNoThrow, // flags 1229 "JSLoadModule", // name 1230 1, 1, 1, 1, 1, 0, // counts 1231 cell_index); // parameter 1232} 1233 1234const Operator* JSOperatorBuilder::GetImportMeta() { 1235 return zone()->New<Operator>( // -- 1236 IrOpcode::kJSGetImportMeta, // opcode 1237 Operator::kNoProperties, // flags 1238 "JSGetImportMeta", // name 1239 0, 1, 1, 1, 1, 2); // counts 1240} 1241 1242const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) { 1243 return zone()->New<Operator1<int32_t>>( // -- 1244 IrOpcode::kJSStoreModule, // opcode 1245 Operator::kNoRead | Operator::kNoThrow, // flags 1246 "JSStoreModule", // name 1247 2, 1, 1, 0, 1, 0, // counts 1248 cell_index); // parameter 1249} 1250 1251const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) { 1252 return zone()->New<Operator1<CreateArgumentsType>>( // -- 1253 IrOpcode::kJSCreateArguments, Operator::kEliminatable, // opcode 1254 "JSCreateArguments", // name 1255 1, 1, 0, 1, 1, 0, // counts 1256 type); // parameter 1257} 1258 1259const Operator* JSOperatorBuilder::CreateArray( 1260 size_t arity, base::Optional<AllocationSiteRef> site) { 1261 // constructor, new_target, arg1, ..., argN 1262 int const value_input_count = static_cast<int>(arity) + 2; 1263 CreateArrayParameters parameters(arity, site); 1264 return zone()->New<Operator1<CreateArrayParameters>>( // -- 1265 IrOpcode::kJSCreateArray, Operator::kNoProperties, // opcode 1266 "JSCreateArray", // name 1267 value_input_count, 1, 1, 1, 1, 2, // counts 1268 parameters); // parameter 1269} 1270 1271const Operator* JSOperatorBuilder::CreateArrayIterator(IterationKind kind) { 1272 CreateArrayIteratorParameters parameters(kind); 1273 return zone()->New<Operator1<CreateArrayIteratorParameters>>( // -- 1274 IrOpcode::kJSCreateArrayIterator, Operator::kEliminatable, // opcode 1275 "JSCreateArrayIterator", // name 1276 1, 1, 1, 1, 1, 0, // counts 1277 parameters); // parameter 1278} 1279 1280const Operator* JSOperatorBuilder::CreateAsyncFunctionObject( 1281 int register_count) { 1282 return zone()->New<Operator1<int>>( // -- 1283 IrOpcode::kJSCreateAsyncFunctionObject, // opcode 1284 Operator::kEliminatable, // flags 1285 "JSCreateAsyncFunctionObject", // name 1286 3, 1, 1, 1, 1, 0, // counts 1287 register_count); // parameter 1288} 1289 1290const Operator* JSOperatorBuilder::CreateCollectionIterator( 1291 CollectionKind collection_kind, IterationKind iteration_kind) { 1292 CreateCollectionIteratorParameters parameters(collection_kind, 1293 iteration_kind); 1294 return zone()->New<Operator1<CreateCollectionIteratorParameters>>( 1295 IrOpcode::kJSCreateCollectionIterator, Operator::kEliminatable, 1296 "JSCreateCollectionIterator", 1, 1, 1, 1, 1, 0, parameters); 1297} 1298 1299const Operator* JSOperatorBuilder::CreateBoundFunction(size_t arity, 1300 const MapRef& map) { 1301 // bound_target_function, bound_this, arg1, ..., argN 1302 int const value_input_count = static_cast<int>(arity) + 2; 1303 CreateBoundFunctionParameters parameters(arity, map); 1304 return zone()->New<Operator1<CreateBoundFunctionParameters>>( // -- 1305 IrOpcode::kJSCreateBoundFunction, Operator::kEliminatable, // opcode 1306 "JSCreateBoundFunction", // name 1307 value_input_count, 1, 1, 1, 1, 0, // counts 1308 parameters); // parameter 1309} 1310 1311const Operator* JSOperatorBuilder::CreateClosure( 1312 const SharedFunctionInfoRef& shared_info, const CodeTRef& code, 1313 AllocationType allocation) { 1314 static constexpr int kFeedbackCell = 1; 1315 static constexpr int kArity = kFeedbackCell; 1316 CreateClosureParameters parameters(shared_info, code, allocation); 1317 return zone()->New<Operator1<CreateClosureParameters>>( // -- 1318 IrOpcode::kJSCreateClosure, Operator::kEliminatable, // opcode 1319 "JSCreateClosure", // name 1320 kArity, 1, 1, 1, 1, 0, // counts 1321 parameters); // parameter 1322} 1323 1324const Operator* JSOperatorBuilder::CreateLiteralArray( 1325 const ArrayBoilerplateDescriptionRef& description, 1326 FeedbackSource const& feedback, int literal_flags, int number_of_elements) { 1327 CreateLiteralParameters parameters(description, feedback, number_of_elements, 1328 literal_flags); 1329 return zone()->New<Operator1<CreateLiteralParameters>>( // -- 1330 IrOpcode::kJSCreateLiteralArray, // opcode 1331 Operator::kNoProperties, // properties 1332 "JSCreateLiteralArray", // name 1333 1, 1, 1, 1, 1, 2, // counts 1334 parameters); // parameter 1335} 1336 1337const Operator* JSOperatorBuilder::CreateEmptyLiteralArray( 1338 FeedbackSource const& feedback) { 1339 static constexpr int kFeedbackVector = 1; 1340 static constexpr int kArity = kFeedbackVector; 1341 FeedbackParameter parameters(feedback); 1342 return zone()->New<Operator1<FeedbackParameter>>( // -- 1343 IrOpcode::kJSCreateEmptyLiteralArray, // opcode 1344 Operator::kEliminatable, // properties 1345 "JSCreateEmptyLiteralArray", // name 1346 kArity, 1, 1, 1, 1, 0, // counts 1347 parameters); // parameter 1348} 1349 1350const Operator* JSOperatorBuilder::CreateArrayFromIterable() { 1351 return zone()->New<Operator>( // -- 1352 IrOpcode::kJSCreateArrayFromIterable, // opcode 1353 Operator::kNoProperties, // properties 1354 "JSCreateArrayFromIterable", // name 1355 1, 1, 1, 1, 1, 2); // counts 1356} 1357 1358const Operator* JSOperatorBuilder::CreateLiteralObject( 1359 const ObjectBoilerplateDescriptionRef& constant_properties, 1360 FeedbackSource const& feedback, int literal_flags, 1361 int number_of_properties) { 1362 CreateLiteralParameters parameters(constant_properties, feedback, 1363 number_of_properties, literal_flags); 1364 return zone()->New<Operator1<CreateLiteralParameters>>( // -- 1365 IrOpcode::kJSCreateLiteralObject, // opcode 1366 Operator::kNoProperties, // properties 1367 "JSCreateLiteralObject", // name 1368 1, 1, 1, 1, 1, 2, // counts 1369 parameters); // parameter 1370} 1371 1372const Operator* JSOperatorBuilder::GetTemplateObject( 1373 const TemplateObjectDescriptionRef& description, 1374 const SharedFunctionInfoRef& shared, FeedbackSource const& feedback) { 1375 GetTemplateObjectParameters parameters(description, shared, feedback); 1376 return zone()->New<Operator1<GetTemplateObjectParameters>>( // -- 1377 IrOpcode::kJSGetTemplateObject, // opcode 1378 Operator::kEliminatable, // properties 1379 "JSGetTemplateObject", // name 1380 1, 1, 1, 1, 1, 0, // counts 1381 parameters); // parameter 1382} 1383 1384const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback, 1385 int literal_flags) { 1386 CloneObjectParameters parameters(feedback, literal_flags); 1387 return zone()->New<Operator1<CloneObjectParameters>>( // -- 1388 IrOpcode::kJSCloneObject, // opcode 1389 Operator::kNoProperties, // properties 1390 "JSCloneObject", // name 1391 2, 1, 1, 1, 1, 2, // counts 1392 parameters); // parameter 1393} 1394 1395const Operator* JSOperatorBuilder::StackCheck(StackCheckKind kind) { 1396 return zone()->New<Operator1<StackCheckKind>>( // -- 1397 IrOpcode::kJSStackCheck, // opcode 1398 Operator::kNoWrite, // properties 1399 "JSStackCheck", // name 1400 0, 1, 1, 0, 1, 2, // counts 1401 kind); // parameter 1402} 1403 1404const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() { 1405 return zone()->New<Operator>( // -- 1406 IrOpcode::kJSCreateEmptyLiteralObject, // opcode 1407 Operator::kNoProperties, // properties 1408 "JSCreateEmptyLiteralObject", // name 1409 0, 1, 1, 1, 1, 2); // counts 1410} 1411 1412const Operator* JSOperatorBuilder::CreateLiteralRegExp( 1413 const StringRef& constant_pattern, FeedbackSource const& feedback, 1414 int literal_flags) { 1415 CreateLiteralParameters parameters(constant_pattern, feedback, -1, 1416 literal_flags); 1417 return zone()->New<Operator1<CreateLiteralParameters>>( // -- 1418 IrOpcode::kJSCreateLiteralRegExp, // opcode 1419 Operator::kNoProperties, // properties 1420 "JSCreateLiteralRegExp", // name 1421 1, 1, 1, 1, 1, 2, // counts 1422 parameters); // parameter 1423} 1424 1425const Operator* JSOperatorBuilder::CreateFunctionContext( 1426 const ScopeInfoRef& scope_info, int slot_count, ScopeType scope_type) { 1427 CreateFunctionContextParameters parameters(scope_info, slot_count, 1428 scope_type); 1429 return zone()->New<Operator1<CreateFunctionContextParameters>>( // -- 1430 IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties, // opcode 1431 "JSCreateFunctionContext", // name 1432 0, 1, 1, 1, 1, 2, // counts 1433 parameters); // parameter 1434} 1435 1436const Operator* JSOperatorBuilder::CreateCatchContext( 1437 const ScopeInfoRef& scope_info) { 1438 return zone()->New<Operator1<ScopeInfoTinyRef>>( 1439 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode 1440 "JSCreateCatchContext", // name 1441 1, 1, 1, 1, 1, 2, // counts 1442 ScopeInfoTinyRef{scope_info}); // parameter 1443} 1444 1445const Operator* JSOperatorBuilder::CreateWithContext( 1446 const ScopeInfoRef& scope_info) { 1447 return zone()->New<Operator1<ScopeInfoTinyRef>>( 1448 IrOpcode::kJSCreateWithContext, Operator::kNoProperties, // opcode 1449 "JSCreateWithContext", // name 1450 1, 1, 1, 1, 1, 2, // counts 1451 ScopeInfoTinyRef{scope_info}); // parameter 1452} 1453 1454const Operator* JSOperatorBuilder::CreateBlockContext( 1455 const ScopeInfoRef& scope_info) { 1456 return zone()->New<Operator1<ScopeInfoTinyRef>>( // -- 1457 IrOpcode::kJSCreateBlockContext, Operator::kNoProperties, // opcode 1458 "JSCreateBlockContext", // name 1459 0, 1, 1, 1, 1, 2, // counts 1460 ScopeInfoTinyRef{scope_info}); // parameter 1461} 1462 1463ScopeInfoRef ScopeInfoOf(JSHeapBroker* broker, const Operator* op) { 1464 DCHECK(IrOpcode::kJSCreateBlockContext == op->opcode() || 1465 IrOpcode::kJSCreateWithContext == op->opcode() || 1466 IrOpcode::kJSCreateCatchContext == op->opcode()); 1467 return OpParameter<ScopeInfoTinyRef>(op).AsRef(broker); 1468} 1469 1470bool operator==(ScopeInfoTinyRef const& lhs, ScopeInfoTinyRef const& rhs) { 1471 return lhs.object().location() == rhs.object().location(); 1472} 1473 1474bool operator!=(ScopeInfoTinyRef const& lhs, ScopeInfoTinyRef const& rhs) { 1475 return !(lhs == rhs); 1476} 1477 1478size_t hash_value(ScopeInfoTinyRef const& ref) { 1479 return reinterpret_cast<size_t>(ref.object().location()); 1480} 1481 1482std::ostream& operator<<(std::ostream& os, ScopeInfoTinyRef const& ref) { 1483 return os << Brief(*ref.object()); 1484} 1485 1486#undef CACHED_OP_LIST 1487 1488} // namespace compiler 1489} // namespace internal 1490} // namespace v8 1491