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/objects-inl.h" 14 #include "src/vector-slot-pair.h" 15 16 namespace v8 { 17 namespace internal { 18 namespace compiler { 19 20 std::ostream& operator<<(std::ostream& os, CallFrequency f) { 21 if (f.IsUnknown()) return os << "unknown"; 22 return os << f.value(); 23 } 24 25 CallFrequency CallFrequencyOf(Operator const* op) { 26 DCHECK(op->opcode() == IrOpcode::kJSCallWithArrayLike || 27 op->opcode() == IrOpcode::kJSConstructWithArrayLike); 28 return OpParameter<CallFrequency>(op); 29 } 30 31 32 std::ostream& operator<<(std::ostream& os, 33 ConstructForwardVarargsParameters const& p) { 34 return os << p.arity() << ", " << p.start_index(); 35 } 36 37 ConstructForwardVarargsParameters const& ConstructForwardVarargsParametersOf( 38 Operator const* op) { 39 DCHECK_EQ(IrOpcode::kJSConstructForwardVarargs, op->opcode()); 40 return OpParameter<ConstructForwardVarargsParameters>(op); 41 } 42 43 bool operator==(ConstructParameters const& lhs, 44 ConstructParameters const& rhs) { 45 return lhs.arity() == rhs.arity() && lhs.frequency() == rhs.frequency() && 46 lhs.feedback() == rhs.feedback(); 47 } 48 49 bool operator!=(ConstructParameters const& lhs, 50 ConstructParameters const& rhs) { 51 return !(lhs == rhs); 52 } 53 54 size_t hash_value(ConstructParameters const& p) { 55 return base::hash_combine(p.arity(), p.frequency(), p.feedback()); 56 } 57 58 std::ostream& operator<<(std::ostream& os, ConstructParameters const& p) { 59 return os << p.arity() << ", " << p.frequency(); 60 } 61 62 ConstructParameters const& ConstructParametersOf(Operator const* op) { 63 DCHECK(op->opcode() == IrOpcode::kJSConstruct || 64 op->opcode() == IrOpcode::kJSConstructWithSpread); 65 return OpParameter<ConstructParameters>(op); 66 } 67 68 std::ostream& operator<<(std::ostream& os, CallParameters const& p) { 69 return os << p.arity() << ", " << p.frequency() << ", " << p.convert_mode(); 70 } 71 72 const CallParameters& CallParametersOf(const Operator* op) { 73 DCHECK(op->opcode() == IrOpcode::kJSCall || 74 op->opcode() == IrOpcode::kJSCallWithSpread); 75 return OpParameter<CallParameters>(op); 76 } 77 78 std::ostream& operator<<(std::ostream& os, 79 CallForwardVarargsParameters const& p) { 80 return os << p.arity() << ", " << p.start_index(); 81 } 82 83 CallForwardVarargsParameters const& CallForwardVarargsParametersOf( 84 Operator const* op) { 85 DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, op->opcode()); 86 return OpParameter<CallForwardVarargsParameters>(op); 87 } 88 89 90 bool operator==(CallRuntimeParameters const& lhs, 91 CallRuntimeParameters const& rhs) { 92 return lhs.id() == rhs.id() && lhs.arity() == rhs.arity(); 93 } 94 95 96 bool operator!=(CallRuntimeParameters const& lhs, 97 CallRuntimeParameters const& rhs) { 98 return !(lhs == rhs); 99 } 100 101 102 size_t hash_value(CallRuntimeParameters const& p) { 103 return base::hash_combine(p.id(), p.arity()); 104 } 105 106 107 std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) { 108 return os << p.id() << ", " << p.arity(); 109 } 110 111 112 const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) { 113 DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode()); 114 return OpParameter<CallRuntimeParameters>(op); 115 } 116 117 118 ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable) 119 : immutable_(immutable), 120 depth_(static_cast<uint16_t>(depth)), 121 index_(static_cast<uint32_t>(index)) { 122 DCHECK(depth <= std::numeric_limits<uint16_t>::max()); 123 DCHECK(index <= std::numeric_limits<uint32_t>::max()); 124 } 125 126 127 bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) { 128 return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() && 129 lhs.immutable() == rhs.immutable(); 130 } 131 132 133 bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) { 134 return !(lhs == rhs); 135 } 136 137 138 size_t hash_value(ContextAccess const& access) { 139 return base::hash_combine(access.depth(), access.index(), access.immutable()); 140 } 141 142 143 std::ostream& operator<<(std::ostream& os, ContextAccess const& access) { 144 return os << access.depth() << ", " << access.index() << ", " 145 << access.immutable(); 146 } 147 148 149 ContextAccess const& ContextAccessOf(Operator const* op) { 150 DCHECK(op->opcode() == IrOpcode::kJSLoadContext || 151 op->opcode() == IrOpcode::kJSStoreContext); 152 return OpParameter<ContextAccess>(op); 153 } 154 155 CreateFunctionContextParameters::CreateFunctionContextParameters( 156 Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type) 157 : scope_info_(scope_info), 158 slot_count_(slot_count), 159 scope_type_(scope_type) {} 160 161 bool operator==(CreateFunctionContextParameters const& lhs, 162 CreateFunctionContextParameters const& rhs) { 163 return lhs.scope_info().location() == rhs.scope_info().location() && 164 lhs.slot_count() == rhs.slot_count() && 165 lhs.scope_type() == rhs.scope_type(); 166 } 167 168 bool operator!=(CreateFunctionContextParameters const& lhs, 169 CreateFunctionContextParameters const& rhs) { 170 return !(lhs == rhs); 171 } 172 173 size_t hash_value(CreateFunctionContextParameters const& parameters) { 174 return base::hash_combine(parameters.scope_info().location(), 175 parameters.slot_count(), 176 static_cast<int>(parameters.scope_type())); 177 } 178 179 std::ostream& operator<<(std::ostream& os, 180 CreateFunctionContextParameters const& parameters) { 181 return os << parameters.slot_count() << ", " << parameters.scope_type(); 182 } 183 184 CreateFunctionContextParameters const& CreateFunctionContextParametersOf( 185 Operator const* op) { 186 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, op->opcode()); 187 return OpParameter<CreateFunctionContextParameters>(op); 188 } 189 190 bool operator==(StoreNamedOwnParameters const& lhs, 191 StoreNamedOwnParameters const& rhs) { 192 return lhs.name().location() == rhs.name().location() && 193 lhs.feedback() == rhs.feedback(); 194 } 195 196 bool operator!=(StoreNamedOwnParameters const& lhs, 197 StoreNamedOwnParameters const& rhs) { 198 return !(lhs == rhs); 199 } 200 201 size_t hash_value(StoreNamedOwnParameters const& p) { 202 return base::hash_combine(p.name().location(), p.feedback()); 203 } 204 205 std::ostream& operator<<(std::ostream& os, StoreNamedOwnParameters const& p) { 206 return os << Brief(*p.name()); 207 } 208 209 StoreNamedOwnParameters const& StoreNamedOwnParametersOf(const Operator* op) { 210 DCHECK_EQ(IrOpcode::kJSStoreNamedOwn, op->opcode()); 211 return OpParameter<StoreNamedOwnParameters>(op); 212 } 213 214 bool operator==(FeedbackParameter const& lhs, FeedbackParameter const& rhs) { 215 return lhs.feedback() == rhs.feedback(); 216 } 217 218 bool operator!=(FeedbackParameter const& lhs, FeedbackParameter const& rhs) { 219 return !(lhs == rhs); 220 } 221 222 size_t hash_value(FeedbackParameter const& p) { 223 return base::hash_combine(p.feedback()); 224 } 225 226 std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) { 227 return os; 228 } 229 230 FeedbackParameter const& FeedbackParameterOf(const Operator* op) { 231 DCHECK(op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray || 232 op->opcode() == IrOpcode::kJSInstanceOf || 233 op->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral || 234 op->opcode() == IrOpcode::kJSStoreInArrayLiteral); 235 return OpParameter<FeedbackParameter>(op); 236 } 237 238 bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) { 239 return lhs.name().location() == rhs.name().location() && 240 lhs.language_mode() == rhs.language_mode() && 241 lhs.feedback() == rhs.feedback(); 242 } 243 244 245 bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) { 246 return !(lhs == rhs); 247 } 248 249 250 size_t hash_value(NamedAccess const& p) { 251 return base::hash_combine(p.name().location(), p.language_mode(), 252 p.feedback()); 253 } 254 255 256 std::ostream& operator<<(std::ostream& os, NamedAccess const& p) { 257 return os << Brief(*p.name()) << ", " << p.language_mode(); 258 } 259 260 261 NamedAccess const& NamedAccessOf(const Operator* op) { 262 DCHECK(op->opcode() == IrOpcode::kJSLoadNamed || 263 op->opcode() == IrOpcode::kJSStoreNamed); 264 return OpParameter<NamedAccess>(op); 265 } 266 267 268 std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) { 269 return os << p.language_mode(); 270 } 271 272 273 bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) { 274 return lhs.language_mode() == rhs.language_mode() && 275 lhs.feedback() == rhs.feedback(); 276 } 277 278 279 bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) { 280 return !(lhs == rhs); 281 } 282 283 284 PropertyAccess const& PropertyAccessOf(const Operator* op) { 285 DCHECK(op->opcode() == IrOpcode::kJSLoadProperty || 286 op->opcode() == IrOpcode::kJSStoreProperty); 287 return OpParameter<PropertyAccess>(op); 288 } 289 290 291 size_t hash_value(PropertyAccess const& p) { 292 return base::hash_combine(p.language_mode(), p.feedback()); 293 } 294 295 296 bool operator==(LoadGlobalParameters const& lhs, 297 LoadGlobalParameters const& rhs) { 298 return lhs.name().location() == rhs.name().location() && 299 lhs.feedback() == rhs.feedback() && 300 lhs.typeof_mode() == rhs.typeof_mode(); 301 } 302 303 304 bool operator!=(LoadGlobalParameters const& lhs, 305 LoadGlobalParameters const& rhs) { 306 return !(lhs == rhs); 307 } 308 309 310 size_t hash_value(LoadGlobalParameters const& p) { 311 return base::hash_combine(p.name().location(), p.typeof_mode()); 312 } 313 314 315 std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) { 316 return os << Brief(*p.name()) << ", " << p.typeof_mode(); 317 } 318 319 320 const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) { 321 DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode()); 322 return OpParameter<LoadGlobalParameters>(op); 323 } 324 325 326 bool operator==(StoreGlobalParameters const& lhs, 327 StoreGlobalParameters const& rhs) { 328 return lhs.language_mode() == rhs.language_mode() && 329 lhs.name().location() == rhs.name().location() && 330 lhs.feedback() == rhs.feedback(); 331 } 332 333 334 bool operator!=(StoreGlobalParameters const& lhs, 335 StoreGlobalParameters const& rhs) { 336 return !(lhs == rhs); 337 } 338 339 340 size_t hash_value(StoreGlobalParameters const& p) { 341 return base::hash_combine(p.language_mode(), p.name().location(), 342 p.feedback()); 343 } 344 345 346 std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) { 347 return os << p.language_mode() << ", " << Brief(*p.name()); 348 } 349 350 351 const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) { 352 DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode()); 353 return OpParameter<StoreGlobalParameters>(op); 354 } 355 356 357 CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) { 358 DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode()); 359 return OpParameter<CreateArgumentsType>(op); 360 } 361 362 363 bool operator==(CreateArrayParameters const& lhs, 364 CreateArrayParameters const& rhs) { 365 return lhs.arity() == rhs.arity() && 366 lhs.site().address() == rhs.site().address(); 367 } 368 369 370 bool operator!=(CreateArrayParameters const& lhs, 371 CreateArrayParameters const& rhs) { 372 return !(lhs == rhs); 373 } 374 375 376 size_t hash_value(CreateArrayParameters const& p) { 377 return base::hash_combine(p.arity(), p.site().address()); 378 } 379 380 381 std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) { 382 os << p.arity(); 383 Handle<AllocationSite> site; 384 if (p.site().ToHandle(&site)) os << ", " << Brief(*site); 385 return os; 386 } 387 388 const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) { 389 DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode()); 390 return OpParameter<CreateArrayParameters>(op); 391 } 392 393 bool operator==(CreateArrayIteratorParameters const& lhs, 394 CreateArrayIteratorParameters const& rhs) { 395 return lhs.kind() == rhs.kind(); 396 } 397 398 bool operator!=(CreateArrayIteratorParameters const& lhs, 399 CreateArrayIteratorParameters const& rhs) { 400 return !(lhs == rhs); 401 } 402 403 size_t hash_value(CreateArrayIteratorParameters const& p) { 404 return static_cast<size_t>(p.kind()); 405 } 406 407 std::ostream& operator<<(std::ostream& os, 408 CreateArrayIteratorParameters const& p) { 409 return os << p.kind(); 410 } 411 412 const CreateArrayIteratorParameters& CreateArrayIteratorParametersOf( 413 const Operator* op) { 414 DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, op->opcode()); 415 return OpParameter<CreateArrayIteratorParameters>(op); 416 } 417 418 bool operator==(CreateCollectionIteratorParameters const& lhs, 419 CreateCollectionIteratorParameters const& rhs) { 420 return lhs.collection_kind() == rhs.collection_kind() && 421 lhs.iteration_kind() == rhs.iteration_kind(); 422 } 423 424 bool operator!=(CreateCollectionIteratorParameters const& lhs, 425 CreateCollectionIteratorParameters const& rhs) { 426 return !(lhs == rhs); 427 } 428 429 size_t hash_value(CreateCollectionIteratorParameters const& p) { 430 return base::hash_combine(static_cast<size_t>(p.collection_kind()), 431 static_cast<size_t>(p.iteration_kind())); 432 } 433 434 std::ostream& operator<<(std::ostream& os, 435 CreateCollectionIteratorParameters const& p) { 436 return os << p.collection_kind() << " " << p.iteration_kind(); 437 } 438 439 const CreateCollectionIteratorParameters& CreateCollectionIteratorParametersOf( 440 const Operator* op) { 441 DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, op->opcode()); 442 return OpParameter<CreateCollectionIteratorParameters>(op); 443 } 444 445 bool operator==(CreateBoundFunctionParameters const& lhs, 446 CreateBoundFunctionParameters const& rhs) { 447 return lhs.arity() == rhs.arity() && 448 lhs.map().location() == rhs.map().location(); 449 } 450 451 bool operator!=(CreateBoundFunctionParameters const& lhs, 452 CreateBoundFunctionParameters const& rhs) { 453 return !(lhs == rhs); 454 } 455 456 size_t hash_value(CreateBoundFunctionParameters const& p) { 457 return base::hash_combine(p.arity(), p.map().location()); 458 } 459 460 std::ostream& operator<<(std::ostream& os, 461 CreateBoundFunctionParameters const& p) { 462 os << p.arity(); 463 if (!p.map().is_null()) os << ", " << Brief(*p.map()); 464 return os; 465 } 466 467 const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf( 468 const Operator* op) { 469 DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, op->opcode()); 470 return OpParameter<CreateBoundFunctionParameters>(op); 471 } 472 473 bool operator==(CreateClosureParameters const& lhs, 474 CreateClosureParameters const& rhs) { 475 return lhs.pretenure() == rhs.pretenure() && 476 lhs.code().location() == rhs.code().location() && 477 lhs.feedback_cell().location() == rhs.feedback_cell().location() && 478 lhs.shared_info().location() == rhs.shared_info().location(); 479 } 480 481 482 bool operator!=(CreateClosureParameters const& lhs, 483 CreateClosureParameters const& rhs) { 484 return !(lhs == rhs); 485 } 486 487 488 size_t hash_value(CreateClosureParameters const& p) { 489 return base::hash_combine(p.pretenure(), p.shared_info().location(), 490 p.feedback_cell().location()); 491 } 492 493 494 std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) { 495 return os << p.pretenure() << ", " << Brief(*p.shared_info()) << ", " 496 << Brief(*p.feedback_cell()) << ", " << Brief(*p.code()); 497 } 498 499 500 const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) { 501 DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode()); 502 return OpParameter<CreateClosureParameters>(op); 503 } 504 505 506 bool operator==(CreateLiteralParameters const& lhs, 507 CreateLiteralParameters const& rhs) { 508 return lhs.constant().location() == rhs.constant().location() && 509 lhs.feedback() == rhs.feedback() && lhs.length() == rhs.length() && 510 lhs.flags() == rhs.flags(); 511 } 512 513 514 bool operator!=(CreateLiteralParameters const& lhs, 515 CreateLiteralParameters const& rhs) { 516 return !(lhs == rhs); 517 } 518 519 520 size_t hash_value(CreateLiteralParameters const& p) { 521 return base::hash_combine(p.constant().location(), p.feedback(), p.length(), 522 p.flags()); 523 } 524 525 526 std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) { 527 return os << Brief(*p.constant()) << ", " << p.length() << ", " << p.flags(); 528 } 529 530 531 const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) { 532 DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray || 533 op->opcode() == IrOpcode::kJSCreateLiteralObject || 534 op->opcode() == IrOpcode::kJSCreateLiteralRegExp); 535 return OpParameter<CreateLiteralParameters>(op); 536 } 537 538 bool operator==(CloneObjectParameters const& lhs, 539 CloneObjectParameters const& rhs) { 540 return lhs.feedback() == rhs.feedback() && lhs.flags() == rhs.flags(); 541 } 542 543 bool operator!=(CloneObjectParameters const& lhs, 544 CloneObjectParameters const& rhs) { 545 return !(lhs == rhs); 546 } 547 548 size_t hash_value(CloneObjectParameters const& p) { 549 return base::hash_combine(p.feedback(), p.flags()); 550 } 551 552 std::ostream& operator<<(std::ostream& os, CloneObjectParameters const& p) { 553 return os << p.flags(); 554 } 555 556 const CloneObjectParameters& CloneObjectParametersOf(const Operator* op) { 557 DCHECK(op->opcode() == IrOpcode::kJSCloneObject); 558 return OpParameter<CloneObjectParameters>(op); 559 } 560 561 size_t hash_value(ForInMode mode) { return static_cast<uint8_t>(mode); } 562 563 std::ostream& operator<<(std::ostream& os, ForInMode mode) { 564 switch (mode) { 565 case ForInMode::kUseEnumCacheKeysAndIndices: 566 return os << "UseEnumCacheKeysAndIndices"; 567 case ForInMode::kUseEnumCacheKeys: 568 return os << "UseEnumCacheKeys"; 569 case ForInMode::kGeneric: 570 return os << "Generic"; 571 } 572 UNREACHABLE(); 573 } 574 575 ForInMode ForInModeOf(Operator const* op) { 576 DCHECK(op->opcode() == IrOpcode::kJSForInNext || 577 op->opcode() == IrOpcode::kJSForInPrepare); 578 return OpParameter<ForInMode>(op); 579 } 580 581 BinaryOperationHint BinaryOperationHintOf(const Operator* op) { 582 DCHECK_EQ(IrOpcode::kJSAdd, op->opcode()); 583 return OpParameter<BinaryOperationHint>(op); 584 } 585 586 CompareOperationHint CompareOperationHintOf(const Operator* op) { 587 DCHECK(op->opcode() == IrOpcode::kJSEqual || 588 op->opcode() == IrOpcode::kJSStrictEqual || 589 op->opcode() == IrOpcode::kJSLessThan || 590 op->opcode() == IrOpcode::kJSGreaterThan || 591 op->opcode() == IrOpcode::kJSLessThanOrEqual || 592 op->opcode() == IrOpcode::kJSGreaterThanOrEqual); 593 return OpParameter<CompareOperationHint>(op); 594 } 595 596 #define CACHED_OP_LIST(V) \ 597 V(BitwiseOr, Operator::kNoProperties, 2, 1) \ 598 V(BitwiseXor, Operator::kNoProperties, 2, 1) \ 599 V(BitwiseAnd, Operator::kNoProperties, 2, 1) \ 600 V(ShiftLeft, Operator::kNoProperties, 2, 1) \ 601 V(ShiftRight, Operator::kNoProperties, 2, 1) \ 602 V(ShiftRightLogical, Operator::kNoProperties, 2, 1) \ 603 V(Subtract, Operator::kNoProperties, 2, 1) \ 604 V(Multiply, Operator::kNoProperties, 2, 1) \ 605 V(Divide, Operator::kNoProperties, 2, 1) \ 606 V(Modulus, Operator::kNoProperties, 2, 1) \ 607 V(Exponentiate, Operator::kNoProperties, 2, 1) \ 608 V(BitwiseNot, Operator::kNoProperties, 1, 1) \ 609 V(Decrement, Operator::kNoProperties, 1, 1) \ 610 V(Increment, Operator::kNoProperties, 1, 1) \ 611 V(Negate, Operator::kNoProperties, 1, 1) \ 612 V(ToInteger, Operator::kNoProperties, 1, 1) \ 613 V(ToLength, Operator::kNoProperties, 1, 1) \ 614 V(ToName, Operator::kNoProperties, 1, 1) \ 615 V(ToNumber, Operator::kNoProperties, 1, 1) \ 616 V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1) \ 617 V(ToNumeric, Operator::kNoProperties, 1, 1) \ 618 V(ToObject, Operator::kFoldable, 1, 1) \ 619 V(ToString, Operator::kNoProperties, 1, 1) \ 620 V(Create, Operator::kNoProperties, 2, 1) \ 621 V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \ 622 V(CreateStringIterator, Operator::kEliminatable, 1, 1) \ 623 V(CreateKeyValueArray, Operator::kEliminatable, 2, 1) \ 624 V(CreatePromise, Operator::kEliminatable, 0, 1) \ 625 V(CreateTypedArray, Operator::kNoProperties, 5, 1) \ 626 V(CreateObject, Operator::kNoProperties, 1, 1) \ 627 V(ObjectIsArray, Operator::kNoProperties, 1, 1) \ 628 V(HasProperty, Operator::kNoProperties, 2, 1) \ 629 V(HasInPrototypeChain, Operator::kNoProperties, 2, 1) \ 630 V(OrdinaryHasInstance, Operator::kNoProperties, 2, 1) \ 631 V(ForInEnumerate, Operator::kNoProperties, 1, 1) \ 632 V(LoadMessage, Operator::kNoThrow | Operator::kNoWrite, 0, 1) \ 633 V(StoreMessage, Operator::kNoRead | Operator::kNoThrow, 1, 0) \ 634 V(GeneratorRestoreContinuation, Operator::kNoThrow, 1, 1) \ 635 V(GeneratorRestoreContext, Operator::kNoThrow, 1, 1) \ 636 V(GeneratorRestoreInputOrDebugPos, Operator::kNoThrow, 1, 1) \ 637 V(StackCheck, Operator::kNoWrite, 0, 0) \ 638 V(Debugger, Operator::kNoProperties, 0, 0) \ 639 V(FulfillPromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 640 V(PerformPromiseThen, Operator::kNoDeopt | Operator::kNoThrow, 4, 1) \ 641 V(PromiseResolve, Operator::kNoProperties, 2, 1) \ 642 V(RejectPromise, Operator::kNoDeopt | Operator::kNoThrow, 3, 1) \ 643 V(ResolvePromise, Operator::kNoDeopt | Operator::kNoThrow, 2, 1) \ 644 V(GetSuperConstructor, Operator::kNoWrite, 1, 1) \ 645 V(ParseInt, Operator::kNoProperties, 2, 1) \ 646 V(RegExpTest, Operator::kNoProperties, 2, 1) 647 648 #define BINARY_OP_LIST(V) V(Add) 649 650 #define COMPARE_OP_LIST(V) \ 651 V(Equal, Operator::kNoProperties) \ 652 V(StrictEqual, Operator::kPure) \ 653 V(LessThan, Operator::kNoProperties) \ 654 V(GreaterThan, Operator::kNoProperties) \ 655 V(LessThanOrEqual, Operator::kNoProperties) \ 656 V(GreaterThanOrEqual, Operator::kNoProperties) 657 658 struct JSOperatorGlobalCache final { 659 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 660 struct Name##Operator final : public Operator { \ 661 Name##Operator() \ 662 : Operator(IrOpcode::kJS##Name, properties, "JS" #Name, \ 663 value_input_count, Operator::ZeroIfPure(properties), \ 664 Operator::ZeroIfEliminatable(properties), \ 665 value_output_count, Operator::ZeroIfPure(properties), \ 666 Operator::ZeroIfNoThrow(properties)) {} \ 667 }; \ 668 Name##Operator k##Name##Operator; 669 CACHED_OP_LIST(CACHED_OP) 670 #undef CACHED_OP 671 672 #define BINARY_OP(Name) \ 673 template <BinaryOperationHint kHint> \ 674 struct Name##Operator final : public Operator1<BinaryOperationHint> { \ 675 Name##Operator() \ 676 : Operator1<BinaryOperationHint>(IrOpcode::kJS##Name, \ 677 Operator::kNoProperties, "JS" #Name, \ 678 2, 1, 1, 1, 1, 2, kHint) {} \ 679 }; \ 680 Name##Operator<BinaryOperationHint::kNone> k##Name##NoneOperator; \ 681 Name##Operator<BinaryOperationHint::kSignedSmall> \ 682 k##Name##SignedSmallOperator; \ 683 Name##Operator<BinaryOperationHint::kSignedSmallInputs> \ 684 k##Name##SignedSmallInputsOperator; \ 685 Name##Operator<BinaryOperationHint::kSigned32> k##Name##Signed32Operator; \ 686 Name##Operator<BinaryOperationHint::kNumber> k##Name##NumberOperator; \ 687 Name##Operator<BinaryOperationHint::kNumberOrOddball> \ 688 k##Name##NumberOrOddballOperator; \ 689 Name##Operator<BinaryOperationHint::kString> k##Name##StringOperator; \ 690 Name##Operator<BinaryOperationHint::kBigInt> k##Name##BigIntOperator; \ 691 Name##Operator<BinaryOperationHint::kAny> k##Name##AnyOperator; 692 BINARY_OP_LIST(BINARY_OP) 693 #undef BINARY_OP 694 695 #define COMPARE_OP(Name, properties) \ 696 template <CompareOperationHint kHint> \ 697 struct Name##Operator final : public Operator1<CompareOperationHint> { \ 698 Name##Operator() \ 699 : Operator1<CompareOperationHint>( \ 700 IrOpcode::kJS##Name, properties, "JS" #Name, 2, 1, 1, 1, 1, \ 701 Operator::ZeroIfNoThrow(properties), kHint) {} \ 702 }; \ 703 Name##Operator<CompareOperationHint::kNone> k##Name##NoneOperator; \ 704 Name##Operator<CompareOperationHint::kSignedSmall> \ 705 k##Name##SignedSmallOperator; \ 706 Name##Operator<CompareOperationHint::kNumber> k##Name##NumberOperator; \ 707 Name##Operator<CompareOperationHint::kNumberOrOddball> \ 708 k##Name##NumberOrOddballOperator; \ 709 Name##Operator<CompareOperationHint::kInternalizedString> \ 710 k##Name##InternalizedStringOperator; \ 711 Name##Operator<CompareOperationHint::kString> k##Name##StringOperator; \ 712 Name##Operator<CompareOperationHint::kSymbol> k##Name##SymbolOperator; \ 713 Name##Operator<CompareOperationHint::kBigInt> k##Name##BigIntOperator; \ 714 Name##Operator<CompareOperationHint::kReceiver> k##Name##ReceiverOperator; \ 715 Name##Operator<CompareOperationHint::kAny> k##Name##AnyOperator; 716 COMPARE_OP_LIST(COMPARE_OP) 717 #undef COMPARE_OP 718 }; 719 720 static base::LazyInstance<JSOperatorGlobalCache>::type kJSOperatorGlobalCache = 721 LAZY_INSTANCE_INITIALIZER; 722 723 JSOperatorBuilder::JSOperatorBuilder(Zone* zone) 724 : cache_(kJSOperatorGlobalCache.Get()), zone_(zone) {} 725 726 #define CACHED_OP(Name, properties, value_input_count, value_output_count) \ 727 const Operator* JSOperatorBuilder::Name() { \ 728 return &cache_.k##Name##Operator; \ 729 } 730 CACHED_OP_LIST(CACHED_OP) 731 #undef CACHED_OP 732 733 #define BINARY_OP(Name) \ 734 const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \ 735 switch (hint) { \ 736 case BinaryOperationHint::kNone: \ 737 return &cache_.k##Name##NoneOperator; \ 738 case BinaryOperationHint::kSignedSmall: \ 739 return &cache_.k##Name##SignedSmallOperator; \ 740 case BinaryOperationHint::kSignedSmallInputs: \ 741 return &cache_.k##Name##SignedSmallInputsOperator; \ 742 case BinaryOperationHint::kSigned32: \ 743 return &cache_.k##Name##Signed32Operator; \ 744 case BinaryOperationHint::kNumber: \ 745 return &cache_.k##Name##NumberOperator; \ 746 case BinaryOperationHint::kNumberOrOddball: \ 747 return &cache_.k##Name##NumberOrOddballOperator; \ 748 case BinaryOperationHint::kString: \ 749 return &cache_.k##Name##StringOperator; \ 750 case BinaryOperationHint::kBigInt: \ 751 return &cache_.k##Name##BigIntOperator; \ 752 case BinaryOperationHint::kAny: \ 753 return &cache_.k##Name##AnyOperator; \ 754 } \ 755 UNREACHABLE(); \ 756 return nullptr; \ 757 } 758 BINARY_OP_LIST(BINARY_OP) 759 #undef BINARY_OP 760 761 #define COMPARE_OP(Name, ...) \ 762 const Operator* JSOperatorBuilder::Name(CompareOperationHint hint) { \ 763 switch (hint) { \ 764 case CompareOperationHint::kNone: \ 765 return &cache_.k##Name##NoneOperator; \ 766 case CompareOperationHint::kSignedSmall: \ 767 return &cache_.k##Name##SignedSmallOperator; \ 768 case CompareOperationHint::kNumber: \ 769 return &cache_.k##Name##NumberOperator; \ 770 case CompareOperationHint::kNumberOrOddball: \ 771 return &cache_.k##Name##NumberOrOddballOperator; \ 772 case CompareOperationHint::kInternalizedString: \ 773 return &cache_.k##Name##InternalizedStringOperator; \ 774 case CompareOperationHint::kString: \ 775 return &cache_.k##Name##StringOperator; \ 776 case CompareOperationHint::kSymbol: \ 777 return &cache_.k##Name##SymbolOperator; \ 778 case CompareOperationHint::kBigInt: \ 779 return &cache_.k##Name##BigIntOperator; \ 780 case CompareOperationHint::kReceiver: \ 781 return &cache_.k##Name##ReceiverOperator; \ 782 case CompareOperationHint::kAny: \ 783 return &cache_.k##Name##AnyOperator; \ 784 } \ 785 UNREACHABLE(); \ 786 return nullptr; \ 787 } 788 COMPARE_OP_LIST(COMPARE_OP) 789 #undef COMPARE_OP 790 791 const Operator* JSOperatorBuilder::StoreDataPropertyInLiteral( 792 const VectorSlotPair& feedback) { 793 FeedbackParameter parameters(feedback); 794 return new (zone()) Operator1<FeedbackParameter>( // -- 795 IrOpcode::kJSStoreDataPropertyInLiteral, 796 Operator::kNoThrow, // opcode 797 "JSStoreDataPropertyInLiteral", // name 798 4, 1, 1, 0, 1, 0, // counts 799 parameters); // parameter 800 } 801 802 const Operator* JSOperatorBuilder::StoreInArrayLiteral( 803 const VectorSlotPair& feedback) { 804 FeedbackParameter parameters(feedback); 805 return new (zone()) Operator1<FeedbackParameter>( // -- 806 IrOpcode::kJSStoreInArrayLiteral, 807 Operator::kNoThrow, // opcode 808 "JSStoreInArrayLiteral", // name 809 3, 1, 1, 0, 1, 0, // counts 810 parameters); // parameter 811 } 812 813 const Operator* JSOperatorBuilder::CallForwardVarargs(size_t arity, 814 uint32_t start_index) { 815 CallForwardVarargsParameters parameters(arity, start_index); 816 return new (zone()) Operator1<CallForwardVarargsParameters>( // -- 817 IrOpcode::kJSCallForwardVarargs, Operator::kNoProperties, // opcode 818 "JSCallForwardVarargs", // name 819 parameters.arity(), 1, 1, 1, 1, 2, // counts 820 parameters); // parameter 821 } 822 823 const Operator* JSOperatorBuilder::Call(size_t arity, 824 CallFrequency const& frequency, 825 VectorSlotPair const& feedback, 826 ConvertReceiverMode convert_mode, 827 SpeculationMode speculation_mode) { 828 DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation, 829 feedback.IsValid()); 830 CallParameters parameters(arity, frequency, feedback, convert_mode, 831 speculation_mode); 832 return new (zone()) Operator1<CallParameters>( // -- 833 IrOpcode::kJSCall, Operator::kNoProperties, // opcode 834 "JSCall", // name 835 parameters.arity(), 1, 1, 1, 1, 2, // inputs/outputs 836 parameters); // parameter 837 } 838 839 const Operator* JSOperatorBuilder::CallWithArrayLike(CallFrequency frequency) { 840 return new (zone()) Operator1<CallFrequency>( // -- 841 IrOpcode::kJSCallWithArrayLike, Operator::kNoProperties, // opcode 842 "JSCallWithArrayLike", // name 843 3, 1, 1, 1, 1, 2, // counts 844 frequency); // parameter 845 } 846 847 const Operator* JSOperatorBuilder::CallWithSpread( 848 uint32_t arity, CallFrequency const& frequency, 849 VectorSlotPair const& feedback, SpeculationMode speculation_mode) { 850 DCHECK_IMPLIES(speculation_mode == SpeculationMode::kAllowSpeculation, 851 feedback.IsValid()); 852 CallParameters parameters(arity, frequency, feedback, 853 ConvertReceiverMode::kAny, speculation_mode); 854 return new (zone()) Operator1<CallParameters>( // -- 855 IrOpcode::kJSCallWithSpread, Operator::kNoProperties, // opcode 856 "JSCallWithSpread", // name 857 parameters.arity(), 1, 1, 1, 1, 2, // counts 858 parameters); // parameter 859 } 860 861 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id) { 862 const Runtime::Function* f = Runtime::FunctionForId(id); 863 return CallRuntime(f, f->nargs); 864 } 865 866 867 const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id, 868 size_t arity) { 869 const Runtime::Function* f = Runtime::FunctionForId(id); 870 return CallRuntime(f, arity); 871 } 872 873 874 const Operator* JSOperatorBuilder::CallRuntime(const Runtime::Function* f, 875 size_t arity) { 876 CallRuntimeParameters parameters(f->function_id, arity); 877 DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity())); 878 return new (zone()) Operator1<CallRuntimeParameters>( // -- 879 IrOpcode::kJSCallRuntime, Operator::kNoProperties, // opcode 880 "JSCallRuntime", // name 881 parameters.arity(), 1, 1, f->result_size, 1, 2, // inputs/outputs 882 parameters); // parameter 883 } 884 885 const Operator* JSOperatorBuilder::ConstructForwardVarargs( 886 size_t arity, uint32_t start_index) { 887 ConstructForwardVarargsParameters parameters(arity, start_index); 888 return new (zone()) Operator1<ConstructForwardVarargsParameters>( // -- 889 IrOpcode::kJSConstructForwardVarargs, Operator::kNoProperties, // opcode 890 "JSConstructForwardVarargs", // name 891 parameters.arity(), 1, 1, 1, 1, 2, // counts 892 parameters); // parameter 893 } 894 895 const Operator* JSOperatorBuilder::Construct(uint32_t arity, 896 CallFrequency frequency, 897 VectorSlotPair const& feedback) { 898 ConstructParameters parameters(arity, frequency, feedback); 899 return new (zone()) Operator1<ConstructParameters>( // -- 900 IrOpcode::kJSConstruct, Operator::kNoProperties, // opcode 901 "JSConstruct", // name 902 parameters.arity(), 1, 1, 1, 1, 2, // counts 903 parameters); // parameter 904 } 905 906 const Operator* JSOperatorBuilder::ConstructWithArrayLike( 907 CallFrequency frequency) { 908 return new (zone()) Operator1<CallFrequency>( // -- 909 IrOpcode::kJSConstructWithArrayLike, // opcode 910 Operator::kNoProperties, // properties 911 "JSConstructWithArrayLike", // name 912 3, 1, 1, 1, 1, 2, // counts 913 frequency); // parameter 914 } 915 916 const Operator* JSOperatorBuilder::ConstructWithSpread( 917 uint32_t arity, CallFrequency frequency, VectorSlotPair const& feedback) { 918 ConstructParameters parameters(arity, frequency, feedback); 919 return new (zone()) Operator1<ConstructParameters>( // -- 920 IrOpcode::kJSConstructWithSpread, Operator::kNoProperties, // opcode 921 "JSConstructWithSpread", // name 922 parameters.arity(), 1, 1, 1, 1, 2, // counts 923 parameters); // parameter 924 } 925 926 const Operator* JSOperatorBuilder::LoadNamed(Handle<Name> name, 927 const VectorSlotPair& feedback) { 928 NamedAccess access(LanguageMode::kSloppy, name, feedback); 929 return new (zone()) Operator1<NamedAccess>( // -- 930 IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode 931 "JSLoadNamed", // name 932 1, 1, 1, 1, 1, 2, // counts 933 access); // parameter 934 } 935 936 const Operator* JSOperatorBuilder::LoadProperty( 937 VectorSlotPair const& feedback) { 938 PropertyAccess access(LanguageMode::kSloppy, feedback); 939 return new (zone()) Operator1<PropertyAccess>( // -- 940 IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode 941 "JSLoadProperty", // name 942 2, 1, 1, 1, 1, 2, // counts 943 access); // parameter 944 } 945 946 const Operator* JSOperatorBuilder::InstanceOf(VectorSlotPair const& feedback) { 947 FeedbackParameter parameter(feedback); 948 return new (zone()) Operator1<FeedbackParameter>( // -- 949 IrOpcode::kJSInstanceOf, Operator::kNoProperties, // opcode 950 "JSInstanceOf", // name 951 2, 1, 1, 1, 1, 2, // counts 952 parameter); // parameter 953 } 954 955 const Operator* JSOperatorBuilder::ForInNext(ForInMode mode) { 956 return new (zone()) Operator1<ForInMode>( // -- 957 IrOpcode::kJSForInNext, Operator::kNoProperties, // opcode 958 "JSForInNext", // name 959 4, 1, 1, 1, 1, 2, // counts 960 mode); // parameter 961 } 962 963 const Operator* JSOperatorBuilder::ForInPrepare(ForInMode mode) { 964 return new (zone()) Operator1<ForInMode>( // -- 965 IrOpcode::kJSForInPrepare, // opcode 966 Operator::kNoWrite | Operator::kNoThrow, // flags 967 "JSForInPrepare", // name 968 1, 1, 1, 3, 1, 1, // counts 969 mode); // parameter 970 } 971 972 const Operator* JSOperatorBuilder::GeneratorStore(int register_count) { 973 return new (zone()) Operator1<int>( // -- 974 IrOpcode::kJSGeneratorStore, Operator::kNoThrow, // opcode 975 "JSGeneratorStore", // name 976 3 + register_count, 1, 1, 0, 1, 0, // counts 977 register_count); // parameter 978 } 979 980 int GeneratorStoreValueCountOf(const Operator* op) { 981 DCHECK_EQ(IrOpcode::kJSGeneratorStore, op->opcode()); 982 return OpParameter<int>(op); 983 } 984 985 const Operator* JSOperatorBuilder::GeneratorRestoreRegister(int index) { 986 return new (zone()) Operator1<int>( // -- 987 IrOpcode::kJSGeneratorRestoreRegister, Operator::kNoThrow, // opcode 988 "JSGeneratorRestoreRegister", // name 989 1, 1, 1, 1, 1, 0, // counts 990 index); // parameter 991 } 992 993 int RestoreRegisterIndexOf(const Operator* op) { 994 DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, op->opcode()); 995 return OpParameter<int>(op); 996 } 997 998 const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode, 999 Handle<Name> name, 1000 VectorSlotPair const& feedback) { 1001 NamedAccess access(language_mode, name, feedback); 1002 return new (zone()) Operator1<NamedAccess>( // -- 1003 IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode 1004 "JSStoreNamed", // name 1005 2, 1, 1, 0, 1, 2, // counts 1006 access); // parameter 1007 } 1008 1009 1010 const Operator* JSOperatorBuilder::StoreProperty( 1011 LanguageMode language_mode, VectorSlotPair const& feedback) { 1012 PropertyAccess access(language_mode, feedback); 1013 return new (zone()) Operator1<PropertyAccess>( // -- 1014 IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode 1015 "JSStoreProperty", // name 1016 3, 1, 1, 0, 1, 2, // counts 1017 access); // parameter 1018 } 1019 1020 const Operator* JSOperatorBuilder::StoreNamedOwn( 1021 Handle<Name> name, VectorSlotPair const& feedback) { 1022 StoreNamedOwnParameters parameters(name, feedback); 1023 return new (zone()) Operator1<StoreNamedOwnParameters>( // -- 1024 IrOpcode::kJSStoreNamedOwn, Operator::kNoProperties, // opcode 1025 "JSStoreNamedOwn", // name 1026 2, 1, 1, 0, 1, 2, // counts 1027 parameters); // parameter 1028 } 1029 1030 const Operator* JSOperatorBuilder::DeleteProperty() { 1031 return new (zone()) Operator( // -- 1032 IrOpcode::kJSDeleteProperty, Operator::kNoProperties, // opcode 1033 "JSDeleteProperty", // name 1034 3, 1, 1, 1, 1, 2); // counts 1035 } 1036 1037 const Operator* JSOperatorBuilder::CreateGeneratorObject() { 1038 return new (zone()) Operator( // -- 1039 IrOpcode::kJSCreateGeneratorObject, Operator::kEliminatable, // opcode 1040 "JSCreateGeneratorObject", // name 1041 2, 1, 1, 1, 1, 0); // counts 1042 } 1043 1044 const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name, 1045 const VectorSlotPair& feedback, 1046 TypeofMode typeof_mode) { 1047 LoadGlobalParameters parameters(name, feedback, typeof_mode); 1048 return new (zone()) Operator1<LoadGlobalParameters>( // -- 1049 IrOpcode::kJSLoadGlobal, Operator::kNoProperties, // opcode 1050 "JSLoadGlobal", // name 1051 0, 1, 1, 1, 1, 2, // counts 1052 parameters); // parameter 1053 } 1054 1055 1056 const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode, 1057 const Handle<Name>& name, 1058 const VectorSlotPair& feedback) { 1059 StoreGlobalParameters parameters(language_mode, feedback, name); 1060 return new (zone()) Operator1<StoreGlobalParameters>( // -- 1061 IrOpcode::kJSStoreGlobal, Operator::kNoProperties, // opcode 1062 "JSStoreGlobal", // name 1063 1, 1, 1, 0, 1, 2, // counts 1064 parameters); // parameter 1065 } 1066 1067 1068 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index, 1069 bool immutable) { 1070 ContextAccess access(depth, index, immutable); 1071 return new (zone()) Operator1<ContextAccess>( // -- 1072 IrOpcode::kJSLoadContext, // opcode 1073 Operator::kNoWrite | Operator::kNoThrow, // flags 1074 "JSLoadContext", // name 1075 0, 1, 0, 1, 1, 0, // counts 1076 access); // parameter 1077 } 1078 1079 1080 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) { 1081 ContextAccess access(depth, index, false); 1082 return new (zone()) Operator1<ContextAccess>( // -- 1083 IrOpcode::kJSStoreContext, // opcode 1084 Operator::kNoRead | Operator::kNoThrow, // flags 1085 "JSStoreContext", // name 1086 1, 1, 1, 0, 1, 0, // counts 1087 access); // parameter 1088 } 1089 1090 const Operator* JSOperatorBuilder::LoadModule(int32_t cell_index) { 1091 return new (zone()) Operator1<int32_t>( // -- 1092 IrOpcode::kJSLoadModule, // opcode 1093 Operator::kNoWrite | Operator::kNoThrow, // flags 1094 "JSLoadModule", // name 1095 1, 1, 1, 1, 1, 0, // counts 1096 cell_index); // parameter 1097 } 1098 1099 const Operator* JSOperatorBuilder::StoreModule(int32_t cell_index) { 1100 return new (zone()) Operator1<int32_t>( // -- 1101 IrOpcode::kJSStoreModule, // opcode 1102 Operator::kNoRead | Operator::kNoThrow, // flags 1103 "JSStoreModule", // name 1104 2, 1, 1, 0, 1, 0, // counts 1105 cell_index); // parameter 1106 } 1107 1108 const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) { 1109 return new (zone()) Operator1<CreateArgumentsType>( // -- 1110 IrOpcode::kJSCreateArguments, Operator::kEliminatable, // opcode 1111 "JSCreateArguments", // name 1112 1, 1, 0, 1, 1, 0, // counts 1113 type); // parameter 1114 } 1115 1116 const Operator* JSOperatorBuilder::CreateArray( 1117 size_t arity, MaybeHandle<AllocationSite> site) { 1118 // constructor, new_target, arg1, ..., argN 1119 int const value_input_count = static_cast<int>(arity) + 2; 1120 CreateArrayParameters parameters(arity, site); 1121 return new (zone()) Operator1<CreateArrayParameters>( // -- 1122 IrOpcode::kJSCreateArray, Operator::kNoProperties, // opcode 1123 "JSCreateArray", // name 1124 value_input_count, 1, 1, 1, 1, 2, // counts 1125 parameters); // parameter 1126 } 1127 1128 const Operator* JSOperatorBuilder::CreateArrayIterator(IterationKind kind) { 1129 CreateArrayIteratorParameters parameters(kind); 1130 return new (zone()) Operator1<CreateArrayIteratorParameters>( // -- 1131 IrOpcode::kJSCreateArrayIterator, Operator::kEliminatable, // opcode 1132 "JSCreateArrayIterator", // name 1133 1, 1, 1, 1, 1, 0, // counts 1134 parameters); // parameter 1135 } 1136 1137 const Operator* JSOperatorBuilder::CreateCollectionIterator( 1138 CollectionKind collection_kind, IterationKind iteration_kind) { 1139 CreateCollectionIteratorParameters parameters(collection_kind, 1140 iteration_kind); 1141 return new (zone()) Operator1<CreateCollectionIteratorParameters>( 1142 IrOpcode::kJSCreateCollectionIterator, Operator::kEliminatable, 1143 "JSCreateCollectionIterator", 1, 1, 1, 1, 1, 0, parameters); 1144 } 1145 1146 const Operator* JSOperatorBuilder::CreateBoundFunction(size_t arity, 1147 Handle<Map> map) { 1148 // bound_target_function, bound_this, arg1, ..., argN 1149 int const value_input_count = static_cast<int>(arity) + 2; 1150 CreateBoundFunctionParameters parameters(arity, map); 1151 return new (zone()) Operator1<CreateBoundFunctionParameters>( // -- 1152 IrOpcode::kJSCreateBoundFunction, Operator::kEliminatable, // opcode 1153 "JSCreateBoundFunction", // name 1154 value_input_count, 1, 1, 1, 1, 0, // counts 1155 parameters); // parameter 1156 } 1157 1158 const Operator* JSOperatorBuilder::CreateClosure( 1159 Handle<SharedFunctionInfo> shared_info, Handle<FeedbackCell> feedback_cell, 1160 Handle<Code> code, PretenureFlag pretenure) { 1161 CreateClosureParameters parameters(shared_info, feedback_cell, code, 1162 pretenure); 1163 return new (zone()) Operator1<CreateClosureParameters>( // -- 1164 IrOpcode::kJSCreateClosure, Operator::kEliminatable, // opcode 1165 "JSCreateClosure", // name 1166 0, 1, 1, 1, 1, 0, // counts 1167 parameters); // parameter 1168 } 1169 1170 const Operator* JSOperatorBuilder::CreateLiteralArray( 1171 Handle<ArrayBoilerplateDescription> description, 1172 VectorSlotPair const& feedback, int literal_flags, int number_of_elements) { 1173 CreateLiteralParameters parameters(description, feedback, number_of_elements, 1174 literal_flags); 1175 return new (zone()) Operator1<CreateLiteralParameters>( // -- 1176 IrOpcode::kJSCreateLiteralArray, // opcode 1177 Operator::kNoProperties, // properties 1178 "JSCreateLiteralArray", // name 1179 0, 1, 1, 1, 1, 2, // counts 1180 parameters); // parameter 1181 } 1182 1183 const Operator* JSOperatorBuilder::CreateEmptyLiteralArray( 1184 VectorSlotPair const& feedback) { 1185 FeedbackParameter parameters(feedback); 1186 return new (zone()) Operator1<FeedbackParameter>( // -- 1187 IrOpcode::kJSCreateEmptyLiteralArray, // opcode 1188 Operator::kEliminatable, // properties 1189 "JSCreateEmptyLiteralArray", // name 1190 0, 1, 1, 1, 1, 0, // counts 1191 parameters); // parameter 1192 } 1193 1194 const Operator* JSOperatorBuilder::CreateLiteralObject( 1195 Handle<ObjectBoilerplateDescription> constant_properties, 1196 VectorSlotPair const& feedback, int literal_flags, 1197 int number_of_properties) { 1198 CreateLiteralParameters parameters(constant_properties, feedback, 1199 number_of_properties, literal_flags); 1200 return new (zone()) Operator1<CreateLiteralParameters>( // -- 1201 IrOpcode::kJSCreateLiteralObject, // opcode 1202 Operator::kNoProperties, // properties 1203 "JSCreateLiteralObject", // name 1204 0, 1, 1, 1, 1, 2, // counts 1205 parameters); // parameter 1206 } 1207 1208 const Operator* JSOperatorBuilder::CloneObject(VectorSlotPair const& feedback, 1209 int literal_flags) { 1210 CloneObjectParameters parameters(feedback, literal_flags); 1211 return new (zone()) Operator1<CloneObjectParameters>( // -- 1212 IrOpcode::kJSCloneObject, // opcode 1213 Operator::kNoProperties, // properties 1214 "JSCloneObject", // name 1215 1, 1, 1, 1, 1, 2, // counts 1216 parameters); // parameter 1217 } 1218 1219 const Operator* JSOperatorBuilder::CreateEmptyLiteralObject() { 1220 return new (zone()) Operator( // -- 1221 IrOpcode::kJSCreateEmptyLiteralObject, // opcode 1222 Operator::kNoProperties, // properties 1223 "JSCreateEmptyLiteralObject", // name 1224 1, 1, 1, 1, 1, 2); // counts 1225 } 1226 1227 const Operator* JSOperatorBuilder::CreateLiteralRegExp( 1228 Handle<String> constant_pattern, VectorSlotPair const& feedback, 1229 int literal_flags) { 1230 CreateLiteralParameters parameters(constant_pattern, feedback, -1, 1231 literal_flags); 1232 return new (zone()) Operator1<CreateLiteralParameters>( // -- 1233 IrOpcode::kJSCreateLiteralRegExp, // opcode 1234 Operator::kNoProperties, // properties 1235 "JSCreateLiteralRegExp", // name 1236 0, 1, 1, 1, 1, 2, // counts 1237 parameters); // parameter 1238 } 1239 1240 const Operator* JSOperatorBuilder::CreateFunctionContext( 1241 Handle<ScopeInfo> scope_info, int slot_count, ScopeType scope_type) { 1242 CreateFunctionContextParameters parameters(scope_info, slot_count, 1243 scope_type); 1244 return new (zone()) Operator1<CreateFunctionContextParameters>( // -- 1245 IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties, // opcode 1246 "JSCreateFunctionContext", // name 1247 0, 1, 1, 1, 1, 2, // counts 1248 parameters); // parameter 1249 } 1250 1251 const Operator* JSOperatorBuilder::CreateCatchContext( 1252 const Handle<ScopeInfo>& scope_info) { 1253 return new (zone()) Operator1<Handle<ScopeInfo>>( 1254 IrOpcode::kJSCreateCatchContext, Operator::kNoProperties, // opcode 1255 "JSCreateCatchContext", // name 1256 1, 1, 1, 1, 1, 2, // counts 1257 scope_info); // parameter 1258 } 1259 1260 const Operator* JSOperatorBuilder::CreateWithContext( 1261 const Handle<ScopeInfo>& scope_info) { 1262 return new (zone()) Operator1<Handle<ScopeInfo>>( 1263 IrOpcode::kJSCreateWithContext, Operator::kNoProperties, // opcode 1264 "JSCreateWithContext", // name 1265 1, 1, 1, 1, 1, 2, // counts 1266 scope_info); // parameter 1267 } 1268 1269 const Operator* JSOperatorBuilder::CreateBlockContext( 1270 const Handle<ScopeInfo>& scope_info) { 1271 return new (zone()) Operator1<Handle<ScopeInfo>>( // -- 1272 IrOpcode::kJSCreateBlockContext, Operator::kNoProperties, // opcode 1273 "JSCreateBlockContext", // name 1274 0, 1, 1, 1, 1, 2, // counts 1275 scope_info); // parameter 1276 } 1277 1278 Handle<ScopeInfo> ScopeInfoOf(const Operator* op) { 1279 DCHECK(IrOpcode::kJSCreateBlockContext == op->opcode() || 1280 IrOpcode::kJSCreateWithContext == op->opcode() || 1281 IrOpcode::kJSCreateCatchContext == op->opcode()); 1282 return OpParameter<Handle<ScopeInfo>>(op); 1283 } 1284 1285 #undef BINARY_OP_LIST 1286 #undef CACHED_OP_LIST 1287 #undef COMPARE_OP_LIST 1288 1289 } // namespace compiler 1290 } // namespace internal 1291 } // namespace v8 1292