1// Copyright 2012 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/simplified-operator.h" 6 7#include "include/v8-fast-api-calls.h" 8#include "src/base/lazy-instance.h" 9#include "src/compiler/linkage.h" 10#include "src/compiler/opcodes.h" 11#include "src/compiler/operator.h" 12#include "src/compiler/types.h" 13#include "src/handles/handles-inl.h" 14#include "src/objects/feedback-cell.h" 15#include "src/objects/map.h" 16#include "src/objects/name.h" 17#include "src/objects/objects-inl.h" 18 19namespace v8 { 20namespace internal { 21namespace compiler { 22 23size_t hash_value(BaseTaggedness base_taggedness) { 24 return static_cast<uint8_t>(base_taggedness); 25} 26 27std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) { 28 switch (base_taggedness) { 29 case kUntaggedBase: 30 return os << "untagged base"; 31 case kTaggedBase: 32 return os << "tagged base"; 33 } 34 UNREACHABLE(); 35} 36 37std::ostream& operator<<(std::ostream& os, 38 ConstFieldInfo const& const_field_info) { 39 if (const_field_info.IsConst()) { 40 return os << "const (field owner: " 41 << Brief(*const_field_info.owner_map.ToHandleChecked()) << ")"; 42 } else { 43 return os << "mutable"; 44 } 45 UNREACHABLE(); 46} 47 48bool operator==(ConstFieldInfo const& lhs, ConstFieldInfo const& rhs) { 49 return lhs.owner_map.address() == rhs.owner_map.address(); 50} 51 52size_t hash_value(ConstFieldInfo const& const_field_info) { 53 return static_cast<size_t>(const_field_info.owner_map.address()); 54} 55 56bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) { 57 // On purpose we don't include the write barrier kind here, as this method is 58 // really only relevant for eliminating loads and they don't care about the 59 // write barrier mode. 60 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset && 61 lhs.map.address() == rhs.map.address() && 62 lhs.machine_type == rhs.machine_type && 63 lhs.const_field_info == rhs.const_field_info && 64 lhs.is_store_in_literal == rhs.is_store_in_literal; 65} 66 67size_t hash_value(FieldAccess const& access) { 68 // On purpose we don't include the write barrier kind here, as this method is 69 // really only relevant for eliminating loads and they don't care about the 70 // write barrier mode. 71 return base::hash_combine(access.base_is_tagged, access.offset, 72 access.machine_type, access.const_field_info, 73 access.is_store_in_literal); 74} 75 76std::ostream& operator<<(std::ostream& os, FieldAccess const& access) { 77 os << "[" << access.base_is_tagged << ", " << access.offset << ", "; 78#ifdef OBJECT_PRINT 79 Handle<Name> name; 80 if (access.name.ToHandle(&name)) { 81 name->NamePrint(os); 82 os << ", "; 83 } 84 Handle<Map> map; 85 if (access.map.ToHandle(&map)) { 86 os << Brief(*map) << ", "; 87 } 88#endif 89 os << access.type << ", " << access.machine_type << ", " 90 << access.write_barrier_kind << ", " << access.const_field_info; 91 if (access.is_store_in_literal) { 92 os << " (store in literal)"; 93 } 94 if (access.maybe_initializing_or_transitioning_store) { 95 os << " (initializing or transitioning store)"; 96 } 97 os << "]"; 98 return os; 99} 100 101template <> 102void Operator1<FieldAccess>::PrintParameter(std::ostream& os, 103 PrintVerbosity verbose) const { 104 if (verbose == PrintVerbosity::kVerbose) { 105 os << parameter(); 106 } else { 107 os << "[+" << parameter().offset << "]"; 108 } 109} 110 111bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { 112 // On purpose we don't include the write barrier kind here, as this method is 113 // really only relevant for eliminating loads and they don't care about the 114 // write barrier mode. 115 return lhs.base_is_tagged == rhs.base_is_tagged && 116 lhs.header_size == rhs.header_size && 117 lhs.machine_type == rhs.machine_type; 118} 119 120size_t hash_value(ElementAccess const& access) { 121 // On purpose we don't include the write barrier kind here, as this method is 122 // really only relevant for eliminating loads and they don't care about the 123 // write barrier mode. 124 return base::hash_combine(access.base_is_tagged, access.header_size, 125 access.machine_type); 126} 127 128std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { 129 os << access.base_is_tagged << ", " << access.header_size << ", " 130 << access.type << ", " << access.machine_type << ", " 131 << access.write_barrier_kind; 132 return os; 133} 134 135bool operator==(ObjectAccess const& lhs, ObjectAccess const& rhs) { 136 return lhs.machine_type == rhs.machine_type && 137 lhs.write_barrier_kind == rhs.write_barrier_kind; 138} 139 140size_t hash_value(ObjectAccess const& access) { 141 return base::hash_combine(access.machine_type, access.write_barrier_kind); 142} 143 144std::ostream& operator<<(std::ostream& os, ObjectAccess const& access) { 145 os << access.machine_type << ", " << access.write_barrier_kind; 146 return os; 147} 148 149const FieldAccess& FieldAccessOf(const Operator* op) { 150 DCHECK_NOT_NULL(op); 151 DCHECK(op->opcode() == IrOpcode::kLoadField || 152 op->opcode() == IrOpcode::kStoreField); 153 return OpParameter<FieldAccess>(op); 154} 155 156const ElementAccess& ElementAccessOf(const Operator* op) { 157 DCHECK_NOT_NULL(op); 158 DCHECK(op->opcode() == IrOpcode::kLoadElement || 159 op->opcode() == IrOpcode::kStoreElement); 160 return OpParameter<ElementAccess>(op); 161} 162 163const ObjectAccess& ObjectAccessOf(const Operator* op) { 164 DCHECK_NOT_NULL(op); 165 DCHECK(op->opcode() == IrOpcode::kLoadFromObject || 166 op->opcode() == IrOpcode::kLoadImmutableFromObject || 167 op->opcode() == IrOpcode::kStoreToObject || 168 op->opcode() == IrOpcode::kInitializeImmutableInObject); 169 return OpParameter<ObjectAccess>(op); 170} 171 172ExternalArrayType ExternalArrayTypeOf(const Operator* op) { 173 DCHECK(op->opcode() == IrOpcode::kLoadTypedElement || 174 op->opcode() == IrOpcode::kLoadDataViewElement || 175 op->opcode() == IrOpcode::kStoreTypedElement || 176 op->opcode() == IrOpcode::kStoreDataViewElement); 177 return OpParameter<ExternalArrayType>(op); 178} 179 180ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) { 181 DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode()); 182 return OpParameter<ConvertReceiverMode>(op); 183} 184 185size_t hash_value(CheckFloat64HoleMode mode) { 186 return static_cast<size_t>(mode); 187} 188 189std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) { 190 switch (mode) { 191 case CheckFloat64HoleMode::kAllowReturnHole: 192 return os << "allow-return-hole"; 193 case CheckFloat64HoleMode::kNeverReturnHole: 194 return os << "never-return-hole"; 195 } 196 UNREACHABLE(); 197} 198 199CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf( 200 Operator const* op) { 201 DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode()); 202 return OpParameter<CheckFloat64HoleParameters>(op); 203} 204 205std::ostream& operator<<(std::ostream& os, 206 CheckFloat64HoleParameters const& params) { 207 return os << params.mode() << ", " << params.feedback(); 208} 209 210size_t hash_value(const CheckFloat64HoleParameters& params) { 211 FeedbackSource::Hash feedback_hash; 212 return base::hash_combine(params.mode(), feedback_hash(params.feedback())); 213} 214 215bool operator==(CheckFloat64HoleParameters const& lhs, 216 CheckFloat64HoleParameters const& rhs) { 217 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback(); 218} 219 220bool operator!=(CheckFloat64HoleParameters const& lhs, 221 CheckFloat64HoleParameters const& rhs) { 222 return !(lhs == rhs); 223} 224 225CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) { 226 DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged || 227 op->opcode() == IrOpcode::kCheckedInt32Mul); 228 return OpParameter<CheckForMinusZeroMode>(op); 229} 230 231size_t hash_value(CheckForMinusZeroMode mode) { 232 return static_cast<size_t>(mode); 233} 234 235std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) { 236 switch (mode) { 237 case CheckForMinusZeroMode::kCheckForMinusZero: 238 return os << "check-for-minus-zero"; 239 case CheckForMinusZeroMode::kDontCheckForMinusZero: 240 return os << "dont-check-for-minus-zero"; 241 } 242 UNREACHABLE(); 243} 244 245std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) { 246 if (flags & CheckMapsFlag::kTryMigrateInstance) { 247 return os << "TryMigrateInstance"; 248 } else { 249 return os << "None"; 250 } 251} 252 253bool operator==(CheckMapsParameters const& lhs, 254 CheckMapsParameters const& rhs) { 255 return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() && 256 lhs.feedback() == rhs.feedback(); 257} 258 259size_t hash_value(CheckMapsParameters const& p) { 260 FeedbackSource::Hash feedback_hash; 261 return base::hash_combine(p.flags(), p.maps(), feedback_hash(p.feedback())); 262} 263 264std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) { 265 return os << p.flags() << ", " << p.maps() << ", " << p.feedback(); 266} 267 268CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) { 269 DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode()); 270 return OpParameter<CheckMapsParameters>(op); 271} 272 273ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const* op) { 274 DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode()); 275 return OpParameter<ZoneHandleSet<Map>>(op); 276} 277 278ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const* op) { 279 DCHECK_EQ(IrOpcode::kMapGuard, op->opcode()); 280 return OpParameter<ZoneHandleSet<Map>>(op); 281} 282 283size_t hash_value(CheckTaggedInputMode mode) { 284 return static_cast<size_t>(mode); 285} 286 287std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) { 288 switch (mode) { 289 case CheckTaggedInputMode::kNumber: 290 return os << "Number"; 291 case CheckTaggedInputMode::kNumberOrBoolean: 292 return os << "NumberOrBoolean"; 293 case CheckTaggedInputMode::kNumberOrOddball: 294 return os << "NumberOrOddball"; 295 } 296 UNREACHABLE(); 297} 298 299std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) { 300 switch (mode) { 301 case GrowFastElementsMode::kDoubleElements: 302 return os << "DoubleElements"; 303 case GrowFastElementsMode::kSmiOrObjectElements: 304 return os << "SmiOrObjectElements"; 305 } 306 UNREACHABLE(); 307} 308 309bool operator==(const GrowFastElementsParameters& lhs, 310 const GrowFastElementsParameters& rhs) { 311 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback(); 312} 313 314inline size_t hash_value(const GrowFastElementsParameters& params) { 315 FeedbackSource::Hash feedback_hash; 316 return base::hash_combine(params.mode(), feedback_hash(params.feedback())); 317} 318 319std::ostream& operator<<(std::ostream& os, 320 const GrowFastElementsParameters& params) { 321 return os << params.mode() << ", " << params.feedback(); 322} 323 324const GrowFastElementsParameters& GrowFastElementsParametersOf( 325 const Operator* op) { 326 DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode()); 327 return OpParameter<GrowFastElementsParameters>(op); 328} 329 330bool operator==(ElementsTransition const& lhs, ElementsTransition const& rhs) { 331 return lhs.mode() == rhs.mode() && 332 lhs.source().address() == rhs.source().address() && 333 lhs.target().address() == rhs.target().address(); 334} 335 336size_t hash_value(ElementsTransition transition) { 337 return base::hash_combine(static_cast<uint8_t>(transition.mode()), 338 transition.source().address(), 339 transition.target().address()); 340} 341 342std::ostream& operator<<(std::ostream& os, ElementsTransition transition) { 343 switch (transition.mode()) { 344 case ElementsTransition::kFastTransition: 345 return os << "fast-transition from " << Brief(*transition.source()) 346 << " to " << Brief(*transition.target()); 347 case ElementsTransition::kSlowTransition: 348 return os << "slow-transition from " << Brief(*transition.source()) 349 << " to " << Brief(*transition.target()); 350 } 351 UNREACHABLE(); 352} 353 354ElementsTransition const& ElementsTransitionOf(const Operator* op) { 355 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); 356 return OpParameter<ElementsTransition>(op); 357} 358 359namespace { 360 361// Parameters for the TransitionAndStoreElement opcode. 362class TransitionAndStoreElementParameters final { 363 public: 364 TransitionAndStoreElementParameters(Handle<Map> double_map, 365 Handle<Map> fast_map); 366 367 Handle<Map> double_map() const { return double_map_; } 368 Handle<Map> fast_map() const { return fast_map_; } 369 370 private: 371 Handle<Map> const double_map_; 372 Handle<Map> const fast_map_; 373}; 374 375TransitionAndStoreElementParameters::TransitionAndStoreElementParameters( 376 Handle<Map> double_map, Handle<Map> fast_map) 377 : double_map_(double_map), fast_map_(fast_map) {} 378 379bool operator==(TransitionAndStoreElementParameters const& lhs, 380 TransitionAndStoreElementParameters const& rhs) { 381 return lhs.fast_map().address() == rhs.fast_map().address() && 382 lhs.double_map().address() == rhs.double_map().address(); 383} 384 385size_t hash_value(TransitionAndStoreElementParameters parameters) { 386 return base::hash_combine(parameters.fast_map().address(), 387 parameters.double_map().address()); 388} 389 390std::ostream& operator<<(std::ostream& os, 391 TransitionAndStoreElementParameters parameters) { 392 return os << "fast-map" << Brief(*parameters.fast_map()) << " double-map" 393 << Brief(*parameters.double_map()); 394} 395 396} // namespace 397 398namespace { 399 400// Parameters for the TransitionAndStoreNonNumberElement opcode. 401class TransitionAndStoreNonNumberElementParameters final { 402 public: 403 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map, 404 Type value_type); 405 406 Handle<Map> fast_map() const { return fast_map_; } 407 Type value_type() const { return value_type_; } 408 409 private: 410 Handle<Map> const fast_map_; 411 Type value_type_; 412}; 413 414TransitionAndStoreNonNumberElementParameters:: 415 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map, 416 Type value_type) 417 : fast_map_(fast_map), value_type_(value_type) {} 418 419bool operator==(TransitionAndStoreNonNumberElementParameters const& lhs, 420 TransitionAndStoreNonNumberElementParameters const& rhs) { 421 return lhs.fast_map().address() == rhs.fast_map().address() && 422 lhs.value_type() == rhs.value_type(); 423} 424 425size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) { 426 return base::hash_combine(parameters.fast_map().address(), 427 parameters.value_type()); 428} 429 430std::ostream& operator<<( 431 std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) { 432 return os << parameters.value_type() << ", fast-map" 433 << Brief(*parameters.fast_map()); 434} 435 436} // namespace 437 438namespace { 439 440// Parameters for the TransitionAndStoreNumberElement opcode. 441class TransitionAndStoreNumberElementParameters final { 442 public: 443 explicit TransitionAndStoreNumberElementParameters(Handle<Map> double_map); 444 445 Handle<Map> double_map() const { return double_map_; } 446 447 private: 448 Handle<Map> const double_map_; 449}; 450 451TransitionAndStoreNumberElementParameters:: 452 TransitionAndStoreNumberElementParameters(Handle<Map> double_map) 453 : double_map_(double_map) {} 454 455bool operator==(TransitionAndStoreNumberElementParameters const& lhs, 456 TransitionAndStoreNumberElementParameters const& rhs) { 457 return lhs.double_map().address() == rhs.double_map().address(); 458} 459 460size_t hash_value(TransitionAndStoreNumberElementParameters parameters) { 461 return base::hash_combine(parameters.double_map().address()); 462} 463 464std::ostream& operator<<(std::ostream& os, 465 TransitionAndStoreNumberElementParameters parameters) { 466 return os << "double-map" << Brief(*parameters.double_map()); 467} 468 469} // namespace 470 471Handle<Map> DoubleMapParameterOf(const Operator* op) { 472 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) { 473 return OpParameter<TransitionAndStoreElementParameters>(op).double_map(); 474 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) { 475 return OpParameter<TransitionAndStoreNumberElementParameters>(op) 476 .double_map(); 477 } 478 UNREACHABLE(); 479} 480 481Type ValueTypeParameterOf(const Operator* op) { 482 DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode()); 483 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op) 484 .value_type(); 485} 486 487Handle<Map> FastMapParameterOf(const Operator* op) { 488 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) { 489 return OpParameter<TransitionAndStoreElementParameters>(op).fast_map(); 490 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) { 491 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op) 492 .fast_map(); 493 } 494 UNREACHABLE(); 495} 496 497std::ostream& operator<<(std::ostream& os, BigIntOperationHint hint) { 498 switch (hint) { 499 case BigIntOperationHint::kBigInt: 500 return os << "BigInt"; 501 } 502 UNREACHABLE(); 503} 504 505size_t hash_value(BigIntOperationHint hint) { 506 return static_cast<uint8_t>(hint); 507} 508 509std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) { 510 switch (hint) { 511 case NumberOperationHint::kSignedSmall: 512 return os << "SignedSmall"; 513 case NumberOperationHint::kSignedSmallInputs: 514 return os << "SignedSmallInputs"; 515 case NumberOperationHint::kNumber: 516 return os << "Number"; 517 case NumberOperationHint::kNumberOrBoolean: 518 return os << "NumberOrBoolean"; 519 case NumberOperationHint::kNumberOrOddball: 520 return os << "NumberOrOddball"; 521 } 522 UNREACHABLE(); 523} 524 525size_t hash_value(NumberOperationHint hint) { 526 return static_cast<uint8_t>(hint); 527} 528 529NumberOperationHint NumberOperationHintOf(const Operator* op) { 530 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || 531 op->opcode() == IrOpcode::kSpeculativeNumberSubtract || 532 op->opcode() == IrOpcode::kSpeculativeNumberMultiply || 533 op->opcode() == IrOpcode::kSpeculativeNumberPow || 534 op->opcode() == IrOpcode::kSpeculativeNumberDivide || 535 op->opcode() == IrOpcode::kSpeculativeNumberModulus || 536 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft || 537 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight || 538 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical || 539 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd || 540 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr || 541 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor || 542 op->opcode() == IrOpcode::kSpeculativeNumberEqual || 543 op->opcode() == IrOpcode::kSpeculativeNumberLessThan || 544 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual || 545 op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd || 546 op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract); 547 return OpParameter<NumberOperationHint>(op); 548} 549 550bool operator==(NumberOperationParameters const& lhs, 551 NumberOperationParameters const& rhs) { 552 return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback(); 553} 554 555size_t hash_value(NumberOperationParameters const& p) { 556 FeedbackSource::Hash feedback_hash; 557 return base::hash_combine(p.hint(), feedback_hash(p.feedback())); 558} 559 560std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) { 561 return os << p.hint() << ", " << p.feedback(); 562} 563 564NumberOperationParameters const& NumberOperationParametersOf( 565 Operator const* op) { 566 DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode()); 567 return OpParameter<NumberOperationParameters>(op); 568} 569 570bool operator==(SpeculativeBigIntAsNParameters const& lhs, 571 SpeculativeBigIntAsNParameters const& rhs) { 572 return lhs.bits() == rhs.bits() && lhs.feedback() == rhs.feedback(); 573} 574 575size_t hash_value(SpeculativeBigIntAsNParameters const& p) { 576 FeedbackSource::Hash feedback_hash; 577 return base::hash_combine(p.bits(), feedback_hash(p.feedback())); 578} 579 580std::ostream& operator<<(std::ostream& os, 581 SpeculativeBigIntAsNParameters const& p) { 582 return os << p.bits() << ", " << p.feedback(); 583} 584 585SpeculativeBigIntAsNParameters const& SpeculativeBigIntAsNParametersOf( 586 Operator const* op) { 587 DCHECK(op->opcode() == IrOpcode::kSpeculativeBigIntAsUintN || 588 op->opcode() == IrOpcode::kSpeculativeBigIntAsIntN); 589 return OpParameter<SpeculativeBigIntAsNParameters>(op); 590} 591 592size_t hash_value(AllocateParameters info) { 593 return base::hash_combine(info.type(), 594 static_cast<int>(info.allocation_type())); 595} 596 597V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 598 AllocateParameters info) { 599 return os << info.type() << ", " << info.allocation_type(); 600} 601 602bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) { 603 return lhs.allocation_type() == rhs.allocation_type() && 604 lhs.type() == rhs.type(); 605} 606 607const AllocateParameters& AllocateParametersOf(const Operator* op) { 608 DCHECK(op->opcode() == IrOpcode::kAllocate || 609 op->opcode() == IrOpcode::kAllocateRaw); 610 return OpParameter<AllocateParameters>(op); 611} 612 613AllocationType AllocationTypeOf(const Operator* op) { 614 if (op->opcode() == IrOpcode::kNewDoubleElements || 615 op->opcode() == IrOpcode::kNewSmiOrObjectElements) { 616 return OpParameter<AllocationType>(op); 617 } 618 return AllocateParametersOf(op).allocation_type(); 619} 620 621Type AllocateTypeOf(const Operator* op) { 622 DCHECK_EQ(IrOpcode::kAllocate, op->opcode()); 623 return AllocateParametersOf(op).type(); 624} 625 626AbortReason AbortReasonOf(const Operator* op) { 627 DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode()); 628 return static_cast<AbortReason>(OpParameter<int>(op)); 629} 630 631const CheckTaggedInputParameters& CheckTaggedInputParametersOf( 632 const Operator* op) { 633 DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 || 634 op->opcode() == IrOpcode::kCheckedTaggedToFloat64); 635 return OpParameter<CheckTaggedInputParameters>(op); 636} 637 638std::ostream& operator<<(std::ostream& os, 639 const CheckTaggedInputParameters& params) { 640 return os << params.mode() << ", " << params.feedback(); 641} 642 643size_t hash_value(const CheckTaggedInputParameters& params) { 644 FeedbackSource::Hash feedback_hash; 645 return base::hash_combine(params.mode(), feedback_hash(params.feedback())); 646} 647 648bool operator==(CheckTaggedInputParameters const& lhs, 649 CheckTaggedInputParameters const& rhs) { 650 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback(); 651} 652 653const CheckMinusZeroParameters& CheckMinusZeroParametersOf(const Operator* op) { 654 DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 || 655 op->opcode() == IrOpcode::kCheckedTaggedToInt64 || 656 op->opcode() == IrOpcode::kCheckedFloat64ToInt32 || 657 op->opcode() == IrOpcode::kCheckedFloat64ToInt64); 658 return OpParameter<CheckMinusZeroParameters>(op); 659} 660 661std::ostream& operator<<(std::ostream& os, 662 const CheckMinusZeroParameters& params) { 663 return os << params.mode() << ", " << params.feedback(); 664} 665 666size_t hash_value(const CheckMinusZeroParameters& params) { 667 FeedbackSource::Hash feedback_hash; 668 return base::hash_combine(params.mode(), feedback_hash(params.feedback())); 669} 670 671bool operator==(CheckMinusZeroParameters const& lhs, 672 CheckMinusZeroParameters const& rhs) { 673 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback(); 674} 675 676#define PURE_OP_LIST(V) \ 677 V(BooleanNot, Operator::kNoProperties, 1, 0) \ 678 V(NumberEqual, Operator::kCommutative, 2, 0) \ 679 V(NumberLessThan, Operator::kNoProperties, 2, 0) \ 680 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \ 681 V(NumberAdd, Operator::kCommutative, 2, 0) \ 682 V(NumberSubtract, Operator::kNoProperties, 2, 0) \ 683 V(NumberMultiply, Operator::kCommutative, 2, 0) \ 684 V(NumberDivide, Operator::kNoProperties, 2, 0) \ 685 V(NumberModulus, Operator::kNoProperties, 2, 0) \ 686 V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \ 687 V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \ 688 V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \ 689 V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \ 690 V(NumberShiftRight, Operator::kNoProperties, 2, 0) \ 691 V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \ 692 V(NumberImul, Operator::kCommutative, 2, 0) \ 693 V(NumberAbs, Operator::kNoProperties, 1, 0) \ 694 V(NumberClz32, Operator::kNoProperties, 1, 0) \ 695 V(NumberCeil, Operator::kNoProperties, 1, 0) \ 696 V(NumberFloor, Operator::kNoProperties, 1, 0) \ 697 V(NumberFround, Operator::kNoProperties, 1, 0) \ 698 V(NumberAcos, Operator::kNoProperties, 1, 0) \ 699 V(NumberAcosh, Operator::kNoProperties, 1, 0) \ 700 V(NumberAsin, Operator::kNoProperties, 1, 0) \ 701 V(NumberAsinh, Operator::kNoProperties, 1, 0) \ 702 V(NumberAtan, Operator::kNoProperties, 1, 0) \ 703 V(NumberAtan2, Operator::kNoProperties, 2, 0) \ 704 V(NumberAtanh, Operator::kNoProperties, 1, 0) \ 705 V(NumberCbrt, Operator::kNoProperties, 1, 0) \ 706 V(NumberCos, Operator::kNoProperties, 1, 0) \ 707 V(NumberCosh, Operator::kNoProperties, 1, 0) \ 708 V(NumberExp, Operator::kNoProperties, 1, 0) \ 709 V(NumberExpm1, Operator::kNoProperties, 1, 0) \ 710 V(NumberLog, Operator::kNoProperties, 1, 0) \ 711 V(NumberLog1p, Operator::kNoProperties, 1, 0) \ 712 V(NumberLog10, Operator::kNoProperties, 1, 0) \ 713 V(NumberLog2, Operator::kNoProperties, 1, 0) \ 714 V(NumberMax, Operator::kNoProperties, 2, 0) \ 715 V(NumberMin, Operator::kNoProperties, 2, 0) \ 716 V(NumberPow, Operator::kNoProperties, 2, 0) \ 717 V(NumberRound, Operator::kNoProperties, 1, 0) \ 718 V(NumberSign, Operator::kNoProperties, 1, 0) \ 719 V(NumberSin, Operator::kNoProperties, 1, 0) \ 720 V(NumberSinh, Operator::kNoProperties, 1, 0) \ 721 V(NumberSqrt, Operator::kNoProperties, 1, 0) \ 722 V(NumberTan, Operator::kNoProperties, 1, 0) \ 723 V(NumberTanh, Operator::kNoProperties, 1, 0) \ 724 V(NumberTrunc, Operator::kNoProperties, 1, 0) \ 725 V(NumberToBoolean, Operator::kNoProperties, 1, 0) \ 726 V(NumberToInt32, Operator::kNoProperties, 1, 0) \ 727 V(NumberToString, Operator::kNoProperties, 1, 0) \ 728 V(NumberToUint32, Operator::kNoProperties, 1, 0) \ 729 V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \ 730 V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \ 731 V(BigIntNegate, Operator::kNoProperties, 1, 0) \ 732 V(StringConcat, Operator::kNoProperties, 3, 0) \ 733 V(StringToNumber, Operator::kNoProperties, 1, 0) \ 734 V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \ 735 V(StringFromSingleCodePoint, Operator::kNoProperties, 1, 0) \ 736 V(StringIndexOf, Operator::kNoProperties, 3, 0) \ 737 V(StringLength, Operator::kNoProperties, 1, 0) \ 738 V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \ 739 V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \ 740 V(TypeOf, Operator::kNoProperties, 1, 1) \ 741 V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \ 742 V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \ 743 V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \ 744 V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \ 745 V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \ 746 V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \ 747 V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \ 748 V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \ 749 V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \ 750 V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \ 751 V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \ 752 V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \ 753 V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \ 754 V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \ 755 V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \ 756 V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \ 757 V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \ 758 V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \ 759 V(TruncateBigIntToWord64, Operator::kNoProperties, 1, 0) \ 760 V(ChangeInt64ToBigInt, Operator::kNoProperties, 1, 0) \ 761 V(ChangeUint64ToBigInt, Operator::kNoProperties, 1, 0) \ 762 V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \ 763 V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \ 764 V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \ 765 V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \ 766 V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \ 767 V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \ 768 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ 769 V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \ 770 V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \ 771 V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \ 772 V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \ 773 V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \ 774 V(NumberIsNaN, Operator::kNoProperties, 1, 0) \ 775 V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \ 776 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \ 777 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \ 778 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \ 779 V(ObjectIsString, Operator::kNoProperties, 1, 0) \ 780 V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \ 781 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \ 782 V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \ 783 V(NumberIsFinite, Operator::kNoProperties, 1, 0) \ 784 V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \ 785 V(NumberIsInteger, Operator::kNoProperties, 1, 0) \ 786 V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \ 787 V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \ 788 V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \ 789 V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \ 790 V(SameValue, Operator::kCommutative, 2, 0) \ 791 V(SameValueNumbersOnly, Operator::kCommutative, 2, 0) \ 792 V(NumberSameValue, Operator::kCommutative, 2, 0) \ 793 V(ReferenceEqual, Operator::kCommutative, 2, 0) \ 794 V(StringEqual, Operator::kCommutative, 2, 0) \ 795 V(StringLessThan, Operator::kNoProperties, 2, 0) \ 796 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \ 797 V(ToBoolean, Operator::kNoProperties, 1, 0) \ 798 V(NewConsString, Operator::kNoProperties, 3, 0) 799 800#define EFFECT_DEPENDENT_OP_LIST(V) \ 801 V(BigIntAdd, Operator::kNoProperties, 2, 1) \ 802 V(BigIntSubtract, Operator::kNoProperties, 2, 1) \ 803 V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \ 804 V(StringCodePointAt, Operator::kNoProperties, 2, 1) \ 805 V(StringFromCodePointAt, Operator::kNoProperties, 2, 1) \ 806 V(StringSubstring, Operator::kNoProperties, 3, 1) \ 807 V(DateNow, Operator::kNoProperties, 0, 1) 808 809#define SPECULATIVE_NUMBER_BINOP_LIST(V) \ 810 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \ 811 V(SpeculativeNumberEqual) \ 812 V(SpeculativeNumberLessThan) \ 813 V(SpeculativeNumberLessThanOrEqual) 814 815#define CHECKED_OP_LIST(V) \ 816 V(CheckEqualsInternalizedString, 2, 0) \ 817 V(CheckEqualsSymbol, 2, 0) \ 818 V(CheckHeapObject, 1, 1) \ 819 V(CheckInternalizedString, 1, 1) \ 820 V(CheckNotTaggedHole, 1, 1) \ 821 V(CheckReceiver, 1, 1) \ 822 V(CheckReceiverOrNullOrUndefined, 1, 1) \ 823 V(CheckSymbol, 1, 1) \ 824 V(CheckedInt32Add, 2, 1) \ 825 V(CheckedInt32Div, 2, 1) \ 826 V(CheckedInt32Mod, 2, 1) \ 827 V(CheckedInt32Sub, 2, 1) \ 828 V(CheckedUint32Div, 2, 1) \ 829 V(CheckedUint32Mod, 2, 1) 830 831#define CHECKED_WITH_FEEDBACK_OP_LIST(V) \ 832 V(CheckNumber, 1, 1) \ 833 V(CheckSmi, 1, 1) \ 834 V(CheckString, 1, 1) \ 835 V(CheckBigInt, 1, 1) \ 836 V(CheckedInt32ToTaggedSigned, 1, 1) \ 837 V(CheckedInt64ToInt32, 1, 1) \ 838 V(CheckedInt64ToTaggedSigned, 1, 1) \ 839 V(CheckedTaggedToArrayIndex, 1, 1) \ 840 V(CheckedTaggedSignedToInt32, 1, 1) \ 841 V(CheckedTaggedToTaggedPointer, 1, 1) \ 842 V(CheckedTaggedToTaggedSigned, 1, 1) \ 843 V(CheckedUint32ToInt32, 1, 1) \ 844 V(CheckedUint32ToTaggedSigned, 1, 1) \ 845 V(CheckedUint64ToInt32, 1, 1) \ 846 V(CheckedUint64ToTaggedSigned, 1, 1) 847 848#define CHECKED_BOUNDS_OP_LIST(V) \ 849 V(CheckedUint32Bounds) \ 850 V(CheckedUint64Bounds) 851 852struct SimplifiedOperatorGlobalCache final { 853#define PURE(Name, properties, value_input_count, control_input_count) \ 854 struct Name##Operator final : public Operator { \ 855 Name##Operator() \ 856 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ 857 value_input_count, 0, control_input_count, 1, 0, 0) {} \ 858 }; \ 859 Name##Operator k##Name; 860 PURE_OP_LIST(PURE) 861#undef PURE 862 863#define EFFECT_DEPENDENT(Name, properties, value_input_count, \ 864 control_input_count) \ 865 struct Name##Operator final : public Operator { \ 866 Name##Operator() \ 867 : Operator(IrOpcode::k##Name, Operator::kEliminatable | properties, \ 868 #Name, value_input_count, 1, control_input_count, 1, 1, \ 869 0) {} \ 870 }; \ 871 Name##Operator k##Name; 872 EFFECT_DEPENDENT_OP_LIST(EFFECT_DEPENDENT) 873#undef EFFECT_DEPENDENT 874 875#define CHECKED(Name, value_input_count, value_output_count) \ 876 struct Name##Operator final : public Operator { \ 877 Name##Operator() \ 878 : Operator(IrOpcode::k##Name, \ 879 Operator::kFoldable | Operator::kNoThrow, #Name, \ 880 value_input_count, 1, 1, value_output_count, 1, 0) {} \ 881 }; \ 882 Name##Operator k##Name; 883 CHECKED_OP_LIST(CHECKED) 884#undef CHECKED 885 886#define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \ 887 struct Name##Operator final : public Operator1<CheckParameters> { \ 888 Name##Operator() \ 889 : Operator1<CheckParameters>( \ 890 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ 891 #Name, value_input_count, 1, 1, value_output_count, 1, 0, \ 892 CheckParameters(FeedbackSource())) {} \ 893 }; \ 894 Name##Operator k##Name; 895 CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK) 896#undef CHECKED_WITH_FEEDBACK 897 898#define CHECKED_BOUNDS(Name) \ 899 struct Name##Operator final : public Operator1<CheckBoundsParameters> { \ 900 Name##Operator(FeedbackSource feedback, CheckBoundsFlags flags) \ 901 : Operator1<CheckBoundsParameters>( \ 902 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ 903 #Name, 2, 1, 1, 1, 1, 0, \ 904 CheckBoundsParameters(feedback, flags)) {} \ 905 }; \ 906 Name##Operator k##Name = {FeedbackSource(), CheckBoundsFlags()}; \ 907 Name##Operator k##Name##Aborting = {FeedbackSource(), \ 908 CheckBoundsFlag::kAbortOnOutOfBounds}; 909 CHECKED_BOUNDS_OP_LIST(CHECKED_BOUNDS) 910 CHECKED_BOUNDS(CheckBounds) 911 // For IrOpcode::kCheckBounds, we allow additional flags: 912 CheckBoundsOperator kCheckBoundsConverting = { 913 FeedbackSource(), CheckBoundsFlag::kConvertStringAndMinusZero}; 914 CheckBoundsOperator kCheckBoundsAbortingAndConverting = { 915 FeedbackSource(), 916 CheckBoundsFlags(CheckBoundsFlag::kAbortOnOutOfBounds) | 917 CheckBoundsFlags(CheckBoundsFlag::kConvertStringAndMinusZero)}; 918#undef CHECKED_BOUNDS 919 920 template <DeoptimizeReason kDeoptimizeReason> 921 struct CheckIfOperator final : public Operator1<CheckIfParameters> { 922 CheckIfOperator() 923 : Operator1<CheckIfParameters>( 924 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, 925 "CheckIf", 1, 1, 1, 0, 1, 0, 926 CheckIfParameters(kDeoptimizeReason, FeedbackSource())) {} 927 }; 928#define CHECK_IF(Name, message) \ 929 CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name; 930 DEOPTIMIZE_REASON_LIST(CHECK_IF) 931#undef CHECK_IF 932 933 struct FindOrderedHashMapEntryOperator final : public Operator { 934 FindOrderedHashMapEntryOperator() 935 : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable, 936 "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {} 937 }; 938 FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry; 939 940 struct FindOrderedHashMapEntryForInt32KeyOperator final : public Operator { 941 FindOrderedHashMapEntryForInt32KeyOperator() 942 : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key, 943 Operator::kEliminatable, 944 "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {} 945 }; 946 FindOrderedHashMapEntryForInt32KeyOperator 947 kFindOrderedHashMapEntryForInt32Key; 948 949 template <CheckForMinusZeroMode kMode> 950 struct ChangeFloat64ToTaggedOperator final 951 : public Operator1<CheckForMinusZeroMode> { 952 ChangeFloat64ToTaggedOperator() 953 : Operator1<CheckForMinusZeroMode>( 954 IrOpcode::kChangeFloat64ToTagged, Operator::kPure, 955 "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {} 956 }; 957 ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero> 958 kChangeFloat64ToTaggedCheckForMinusZeroOperator; 959 ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero> 960 kChangeFloat64ToTaggedDontCheckForMinusZeroOperator; 961 962 template <CheckForMinusZeroMode kMode> 963 struct CheckedInt32MulOperator final 964 : public Operator1<CheckForMinusZeroMode> { 965 CheckedInt32MulOperator() 966 : Operator1<CheckForMinusZeroMode>( 967 IrOpcode::kCheckedInt32Mul, 968 Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1, 969 1, 1, 1, 0, kMode) {} 970 }; 971 CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero> 972 kCheckedInt32MulCheckForMinusZeroOperator; 973 CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero> 974 kCheckedInt32MulDontCheckForMinusZeroOperator; 975 976 template <CheckForMinusZeroMode kMode> 977 struct CheckedFloat64ToInt32Operator final 978 : public Operator1<CheckMinusZeroParameters> { 979 CheckedFloat64ToInt32Operator() 980 : Operator1<CheckMinusZeroParameters>( 981 IrOpcode::kCheckedFloat64ToInt32, 982 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 983 1, 1, 1, 1, 1, 0, 984 CheckMinusZeroParameters(kMode, FeedbackSource())) {} 985 }; 986 CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero> 987 kCheckedFloat64ToInt32CheckForMinusZeroOperator; 988 CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> 989 kCheckedFloat64ToInt32DontCheckForMinusZeroOperator; 990 991 template <CheckForMinusZeroMode kMode> 992 struct CheckedFloat64ToInt64Operator final 993 : public Operator1<CheckMinusZeroParameters> { 994 CheckedFloat64ToInt64Operator() 995 : Operator1<CheckMinusZeroParameters>( 996 IrOpcode::kCheckedFloat64ToInt64, 997 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 998 1, 1, 1, 1, 1, 0, 999 CheckMinusZeroParameters(kMode, FeedbackSource())) {} 1000 }; 1001 CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero> 1002 kCheckedFloat64ToInt64CheckForMinusZeroOperator; 1003 CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> 1004 kCheckedFloat64ToInt64DontCheckForMinusZeroOperator; 1005 1006 template <CheckForMinusZeroMode kMode> 1007 struct CheckedTaggedToInt32Operator final 1008 : public Operator1<CheckMinusZeroParameters> { 1009 CheckedTaggedToInt32Operator() 1010 : Operator1<CheckMinusZeroParameters>( 1011 IrOpcode::kCheckedTaggedToInt32, 1012 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32", 1013 1, 1, 1, 1, 1, 0, 1014 CheckMinusZeroParameters(kMode, FeedbackSource())) {} 1015 }; 1016 CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero> 1017 kCheckedTaggedToInt32CheckForMinusZeroOperator; 1018 CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> 1019 kCheckedTaggedToInt32DontCheckForMinusZeroOperator; 1020 1021 template <CheckForMinusZeroMode kMode> 1022 struct CheckedTaggedToInt64Operator final 1023 : public Operator1<CheckMinusZeroParameters> { 1024 CheckedTaggedToInt64Operator() 1025 : Operator1<CheckMinusZeroParameters>( 1026 IrOpcode::kCheckedTaggedToInt64, 1027 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64", 1028 1, 1, 1, 1, 1, 0, 1029 CheckMinusZeroParameters(kMode, FeedbackSource())) {} 1030 }; 1031 CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero> 1032 kCheckedTaggedToInt64CheckForMinusZeroOperator; 1033 CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero> 1034 kCheckedTaggedToInt64DontCheckForMinusZeroOperator; 1035 1036 template <CheckTaggedInputMode kMode> 1037 struct CheckedTaggedToFloat64Operator final 1038 : public Operator1<CheckTaggedInputParameters> { 1039 CheckedTaggedToFloat64Operator() 1040 : Operator1<CheckTaggedInputParameters>( 1041 IrOpcode::kCheckedTaggedToFloat64, 1042 Operator::kFoldable | Operator::kNoThrow, 1043 "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0, 1044 CheckTaggedInputParameters(kMode, FeedbackSource())) {} 1045 }; 1046 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber> 1047 kCheckedTaggedToFloat64NumberOperator; 1048 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrBoolean> 1049 kCheckedTaggedToFloat64NumberOrBooleanOperator; 1050 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball> 1051 kCheckedTaggedToFloat64NumberOrOddballOperator; 1052 1053 template <CheckTaggedInputMode kMode> 1054 struct CheckedTruncateTaggedToWord32Operator final 1055 : public Operator1<CheckTaggedInputParameters> { 1056 CheckedTruncateTaggedToWord32Operator() 1057 : Operator1<CheckTaggedInputParameters>( 1058 IrOpcode::kCheckedTruncateTaggedToWord32, 1059 Operator::kFoldable | Operator::kNoThrow, 1060 "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0, 1061 CheckTaggedInputParameters(kMode, FeedbackSource())) {} 1062 }; 1063 CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumber> 1064 kCheckedTruncateTaggedToWord32NumberOperator; 1065 CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumberOrOddball> 1066 kCheckedTruncateTaggedToWord32NumberOrOddballOperator; 1067 1068 template <ConvertReceiverMode kMode> 1069 struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> { 1070 ConvertReceiverOperator() 1071 : Operator1<ConvertReceiverMode>( // -- 1072 IrOpcode::kConvertReceiver, // opcode 1073 Operator::kEliminatable, // flags 1074 "ConvertReceiver", // name 1075 2, 1, 1, 1, 1, 0, // counts 1076 kMode) {} // param 1077 }; 1078 ConvertReceiverOperator<ConvertReceiverMode::kAny> 1079 kConvertReceiverAnyOperator; 1080 ConvertReceiverOperator<ConvertReceiverMode::kNullOrUndefined> 1081 kConvertReceiverNullOrUndefinedOperator; 1082 ConvertReceiverOperator<ConvertReceiverMode::kNotNullOrUndefined> 1083 kConvertReceiverNotNullOrUndefinedOperator; 1084 1085 template <CheckFloat64HoleMode kMode> 1086 struct CheckFloat64HoleNaNOperator final 1087 : public Operator1<CheckFloat64HoleParameters> { 1088 CheckFloat64HoleNaNOperator() 1089 : Operator1<CheckFloat64HoleParameters>( 1090 IrOpcode::kCheckFloat64Hole, 1091 Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1, 1092 1, 1, 1, 1, 0, 1093 CheckFloat64HoleParameters(kMode, FeedbackSource())) {} 1094 }; 1095 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole> 1096 kCheckFloat64HoleAllowReturnHoleOperator; 1097 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole> 1098 kCheckFloat64HoleNeverReturnHoleOperator; 1099 1100 struct EnsureWritableFastElementsOperator final : public Operator { 1101 EnsureWritableFastElementsOperator() 1102 : Operator( // -- 1103 IrOpcode::kEnsureWritableFastElements, // opcode 1104 Operator::kNoDeopt | Operator::kNoThrow, // flags 1105 "EnsureWritableFastElements", // name 1106 2, 1, 1, 1, 1, 0) {} // counts 1107 }; 1108 EnsureWritableFastElementsOperator kEnsureWritableFastElements; 1109 1110 template <GrowFastElementsMode kMode> 1111 struct GrowFastElementsOperator final 1112 : public Operator1<GrowFastElementsParameters> { 1113 GrowFastElementsOperator() 1114 : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow, 1115 "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0, 1116 GrowFastElementsParameters(kMode, FeedbackSource())) {} 1117 }; 1118 1119 GrowFastElementsOperator<GrowFastElementsMode::kDoubleElements> 1120 kGrowFastElementsOperatorDoubleElements; 1121 GrowFastElementsOperator<GrowFastElementsMode::kSmiOrObjectElements> 1122 kGrowFastElementsOperatorSmiOrObjectElements; 1123 1124 struct LoadFieldByIndexOperator final : public Operator { 1125 LoadFieldByIndexOperator() 1126 : Operator( // -- 1127 IrOpcode::kLoadFieldByIndex, // opcode 1128 Operator::kEliminatable, // flags, 1129 "LoadFieldByIndex", // name 1130 2, 1, 1, 1, 1, 0) {} // counts; 1131 }; 1132 LoadFieldByIndexOperator kLoadFieldByIndex; 1133 1134 struct LoadStackArgumentOperator final : public Operator { 1135 LoadStackArgumentOperator() 1136 : Operator( // -- 1137 IrOpcode::kLoadStackArgument, // opcode 1138 Operator::kEliminatable, // flags 1139 "LoadStackArgument", // name 1140 2, 1, 1, 1, 1, 0) {} // counts 1141 }; 1142 LoadStackArgumentOperator kLoadStackArgument; 1143 1144#define SPECULATIVE_NUMBER_BINOP(Name) \ 1145 template <NumberOperationHint kHint> \ 1146 struct Name##Operator final : public Operator1<NumberOperationHint> { \ 1147 Name##Operator() \ 1148 : Operator1<NumberOperationHint>( \ 1149 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ 1150 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \ 1151 }; \ 1152 Name##Operator<NumberOperationHint::kSignedSmall> \ 1153 k##Name##SignedSmallOperator; \ 1154 Name##Operator<NumberOperationHint::kSignedSmallInputs> \ 1155 k##Name##SignedSmallInputsOperator; \ 1156 Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \ 1157 Name##Operator<NumberOperationHint::kNumberOrOddball> \ 1158 k##Name##NumberOrOddballOperator; 1159 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) 1160#undef SPECULATIVE_NUMBER_BINOP 1161 SpeculativeNumberEqualOperator<NumberOperationHint::kNumberOrBoolean> 1162 kSpeculativeNumberEqualNumberOrBooleanOperator; 1163 1164 template <NumberOperationHint kHint> 1165 struct SpeculativeToNumberOperator final 1166 : public Operator1<NumberOperationParameters> { 1167 SpeculativeToNumberOperator() 1168 : Operator1<NumberOperationParameters>( 1169 IrOpcode::kSpeculativeToNumber, 1170 Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber", 1171 1, 1, 1, 1, 1, 0, 1172 NumberOperationParameters(kHint, FeedbackSource())) {} 1173 }; 1174 SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall> 1175 kSpeculativeToNumberSignedSmallOperator; 1176 SpeculativeToNumberOperator<NumberOperationHint::kNumber> 1177 kSpeculativeToNumberNumberOperator; 1178 SpeculativeToNumberOperator<NumberOperationHint::kNumberOrOddball> 1179 kSpeculativeToNumberNumberOrOddballOperator; 1180}; 1181 1182namespace { 1183DEFINE_LAZY_LEAKY_OBJECT_GETTER(SimplifiedOperatorGlobalCache, 1184 GetSimplifiedOperatorGlobalCache) 1185} // namespace 1186 1187SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) 1188 : cache_(*GetSimplifiedOperatorGlobalCache()), zone_(zone) {} 1189 1190#define GET_FROM_CACHE(Name, ...) \ 1191 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } 1192PURE_OP_LIST(GET_FROM_CACHE) 1193EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE) 1194CHECKED_OP_LIST(GET_FROM_CACHE) 1195GET_FROM_CACHE(FindOrderedHashMapEntry) 1196GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key) 1197GET_FROM_CACHE(LoadFieldByIndex) 1198#undef GET_FROM_CACHE 1199 1200#define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \ 1201 value_output_count) \ 1202 const Operator* SimplifiedOperatorBuilder::Name( \ 1203 const FeedbackSource& feedback) { \ 1204 if (!feedback.IsValid()) { \ 1205 return &cache_.k##Name; \ 1206 } \ 1207 return zone()->New<Operator1<CheckParameters>>( \ 1208 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \ 1209 value_input_count, 1, 1, value_output_count, 1, 0, \ 1210 CheckParameters(feedback)); \ 1211 } 1212CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK) 1213#undef GET_FROM_CACHE_WITH_FEEDBACK 1214 1215#define GET_FROM_CACHE_WITH_FEEDBACK(Name) \ 1216 const Operator* SimplifiedOperatorBuilder::Name( \ 1217 const FeedbackSource& feedback, CheckBoundsFlags flags) { \ 1218 DCHECK(!(flags & CheckBoundsFlag::kConvertStringAndMinusZero)); \ 1219 if (!feedback.IsValid()) { \ 1220 if (flags & CheckBoundsFlag::kAbortOnOutOfBounds) { \ 1221 return &cache_.k##Name##Aborting; \ 1222 } else { \ 1223 return &cache_.k##Name; \ 1224 } \ 1225 } \ 1226 return zone()->New<SimplifiedOperatorGlobalCache::Name##Operator>( \ 1227 feedback, flags); \ 1228 } 1229CHECKED_BOUNDS_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK) 1230#undef GET_FROM_CACHE_WITH_FEEDBACK 1231 1232// For IrOpcode::kCheckBounds, we allow additional flags: 1233const Operator* SimplifiedOperatorBuilder::CheckBounds( 1234 const FeedbackSource& feedback, CheckBoundsFlags flags) { 1235 if (!feedback.IsValid()) { 1236 if (flags & CheckBoundsFlag::kAbortOnOutOfBounds) { 1237 if (flags & CheckBoundsFlag::kConvertStringAndMinusZero) { 1238 return &cache_.kCheckBoundsAbortingAndConverting; 1239 } else { 1240 return &cache_.kCheckBoundsAborting; 1241 } 1242 } else { 1243 if (flags & CheckBoundsFlag::kConvertStringAndMinusZero) { 1244 return &cache_.kCheckBoundsConverting; 1245 } else { 1246 return &cache_.kCheckBounds; 1247 } 1248 } 1249 } 1250 return zone()->New<SimplifiedOperatorGlobalCache::CheckBoundsOperator>( 1251 feedback, flags); 1252} 1253 1254bool IsCheckedWithFeedback(const Operator* op) { 1255#define CASE(Name, ...) case IrOpcode::k##Name: 1256 switch (op->opcode()) { 1257 CHECKED_WITH_FEEDBACK_OP_LIST(CASE) return true; 1258 default: 1259 return false; 1260 } 1261#undef CASE 1262} 1263 1264const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) { 1265 return zone()->New<Operator1<int>>( // -- 1266 IrOpcode::kRuntimeAbort, // opcode 1267 Operator::kNoThrow | Operator::kNoDeopt, // flags 1268 "RuntimeAbort", // name 1269 0, 1, 1, 0, 1, 0, // counts 1270 static_cast<int>(reason)); // parameter 1271} 1272 1273const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntAsIntN( 1274 int bits, const FeedbackSource& feedback) { 1275 CHECK(0 <= bits && bits <= 64); 1276 1277 return zone()->New<Operator1<SpeculativeBigIntAsNParameters>>( 1278 IrOpcode::kSpeculativeBigIntAsIntN, Operator::kNoProperties, 1279 "SpeculativeBigIntAsIntN", 1, 1, 1, 1, 1, 0, 1280 SpeculativeBigIntAsNParameters(bits, feedback)); 1281} 1282 1283const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntAsUintN( 1284 int bits, const FeedbackSource& feedback) { 1285 CHECK(0 <= bits && bits <= 64); 1286 1287 return zone()->New<Operator1<SpeculativeBigIntAsNParameters>>( 1288 IrOpcode::kSpeculativeBigIntAsUintN, Operator::kNoProperties, 1289 "SpeculativeBigIntAsUintN", 1, 1, 1, 1, 1, 0, 1290 SpeculativeBigIntAsNParameters(bits, feedback)); 1291} 1292 1293const Operator* SimplifiedOperatorBuilder::AssertType(Type type) { 1294 DCHECK(type.CanBeAsserted()); 1295 return zone()->New<Operator1<Type>>(IrOpcode::kAssertType, 1296 Operator::kNoThrow | Operator::kNoDeopt, 1297 "AssertType", 1, 0, 0, 1, 0, 0, type); 1298} 1299 1300const Operator* SimplifiedOperatorBuilder::VerifyType() { 1301 return zone()->New<Operator>(IrOpcode::kVerifyType, 1302 Operator::kNoThrow | Operator::kNoDeopt, 1303 "VerifyType", 1, 0, 0, 1, 0, 0); 1304} 1305 1306const Operator* SimplifiedOperatorBuilder::CheckIf( 1307 DeoptimizeReason reason, const FeedbackSource& feedback) { 1308 if (!feedback.IsValid()) { 1309 switch (reason) { 1310#define CHECK_IF(Name, message) \ 1311 case DeoptimizeReason::k##Name: \ 1312 return &cache_.kCheckIf##Name; 1313 DEOPTIMIZE_REASON_LIST(CHECK_IF) 1314#undef CHECK_IF 1315 } 1316 } 1317 return zone()->New<Operator1<CheckIfParameters>>( 1318 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf", 1319 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback)); 1320} 1321 1322const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged( 1323 CheckForMinusZeroMode mode) { 1324 switch (mode) { 1325 case CheckForMinusZeroMode::kCheckForMinusZero: 1326 return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator; 1327 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1328 return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator; 1329 } 1330 UNREACHABLE(); 1331} 1332 1333const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul( 1334 CheckForMinusZeroMode mode) { 1335 switch (mode) { 1336 case CheckForMinusZeroMode::kCheckForMinusZero: 1337 return &cache_.kCheckedInt32MulCheckForMinusZeroOperator; 1338 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1339 return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator; 1340 } 1341 UNREACHABLE(); 1342} 1343 1344const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32( 1345 CheckForMinusZeroMode mode, const FeedbackSource& feedback) { 1346 if (!feedback.IsValid()) { 1347 switch (mode) { 1348 case CheckForMinusZeroMode::kCheckForMinusZero: 1349 return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator; 1350 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1351 return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator; 1352 } 1353 } 1354 return zone()->New<Operator1<CheckMinusZeroParameters>>( 1355 IrOpcode::kCheckedFloat64ToInt32, 1356 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1, 1357 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback)); 1358} 1359 1360const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64( 1361 CheckForMinusZeroMode mode, const FeedbackSource& feedback) { 1362 if (!feedback.IsValid()) { 1363 switch (mode) { 1364 case CheckForMinusZeroMode::kCheckForMinusZero: 1365 return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator; 1366 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1367 return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator; 1368 } 1369 } 1370 return zone()->New<Operator1<CheckMinusZeroParameters>>( 1371 IrOpcode::kCheckedFloat64ToInt64, 1372 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1, 1373 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback)); 1374} 1375 1376const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32( 1377 CheckForMinusZeroMode mode, const FeedbackSource& feedback) { 1378 if (!feedback.IsValid()) { 1379 switch (mode) { 1380 case CheckForMinusZeroMode::kCheckForMinusZero: 1381 return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator; 1382 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1383 return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator; 1384 } 1385 } 1386 return zone()->New<Operator1<CheckMinusZeroParameters>>( 1387 IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow, 1388 "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0, 1389 CheckMinusZeroParameters(mode, feedback)); 1390} 1391 1392const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64( 1393 CheckForMinusZeroMode mode, const FeedbackSource& feedback) { 1394 if (!feedback.IsValid()) { 1395 switch (mode) { 1396 case CheckForMinusZeroMode::kCheckForMinusZero: 1397 return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator; 1398 case CheckForMinusZeroMode::kDontCheckForMinusZero: 1399 return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator; 1400 } 1401 } 1402 return zone()->New<Operator1<CheckMinusZeroParameters>>( 1403 IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow, 1404 "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0, 1405 CheckMinusZeroParameters(mode, feedback)); 1406} 1407 1408const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64( 1409 CheckTaggedInputMode mode, const FeedbackSource& feedback) { 1410 if (!feedback.IsValid()) { 1411 switch (mode) { 1412 case CheckTaggedInputMode::kNumber: 1413 return &cache_.kCheckedTaggedToFloat64NumberOperator; 1414 case CheckTaggedInputMode::kNumberOrBoolean: 1415 return &cache_.kCheckedTaggedToFloat64NumberOrBooleanOperator; 1416 case CheckTaggedInputMode::kNumberOrOddball: 1417 return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator; 1418 } 1419 } 1420 return zone()->New<Operator1<CheckTaggedInputParameters>>( 1421 IrOpcode::kCheckedTaggedToFloat64, 1422 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1, 1423 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback)); 1424} 1425 1426const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32( 1427 CheckTaggedInputMode mode, const FeedbackSource& feedback) { 1428 if (!feedback.IsValid()) { 1429 switch (mode) { 1430 case CheckTaggedInputMode::kNumber: 1431 return &cache_.kCheckedTruncateTaggedToWord32NumberOperator; 1432 case CheckTaggedInputMode::kNumberOrBoolean: 1433 // Not used currently. 1434 UNREACHABLE(); 1435 case CheckTaggedInputMode::kNumberOrOddball: 1436 return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator; 1437 } 1438 } 1439 return zone()->New<Operator1<CheckTaggedInputParameters>>( 1440 IrOpcode::kCheckedTruncateTaggedToWord32, 1441 Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32", 1442 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback)); 1443} 1444 1445const Operator* SimplifiedOperatorBuilder::CheckMaps( 1446 CheckMapsFlags flags, ZoneHandleSet<Map> maps, 1447 const FeedbackSource& feedback) { 1448 CheckMapsParameters const parameters(flags, maps, feedback); 1449 return zone()->New<Operator1<CheckMapsParameters>>( // -- 1450 IrOpcode::kCheckMaps, // opcode 1451 Operator::kNoThrow | Operator::kNoWrite, // flags 1452 "CheckMaps", // name 1453 1, 1, 1, 0, 1, 0, // counts 1454 parameters); // parameter 1455} 1456 1457const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) { 1458 DCHECK_LT(0, maps.size()); 1459 return zone()->New<Operator1<ZoneHandleSet<Map>>>( // -- 1460 IrOpcode::kMapGuard, Operator::kEliminatable, // opcode 1461 "MapGuard", // name 1462 1, 1, 1, 0, 1, 0, // counts 1463 maps); // parameter 1464} 1465 1466const Operator* SimplifiedOperatorBuilder::CompareMaps( 1467 ZoneHandleSet<Map> maps) { 1468 DCHECK_LT(0, maps.size()); 1469 return zone()->New<Operator1<ZoneHandleSet<Map>>>( // -- 1470 IrOpcode::kCompareMaps, // opcode 1471 Operator::kNoThrow | Operator::kNoWrite, // flags 1472 "CompareMaps", // name 1473 1, 1, 1, 1, 1, 0, // counts 1474 maps); // parameter 1475} 1476 1477const Operator* SimplifiedOperatorBuilder::ConvertReceiver( 1478 ConvertReceiverMode mode) { 1479 switch (mode) { 1480 case ConvertReceiverMode::kAny: 1481 return &cache_.kConvertReceiverAnyOperator; 1482 case ConvertReceiverMode::kNullOrUndefined: 1483 return &cache_.kConvertReceiverNullOrUndefinedOperator; 1484 case ConvertReceiverMode::kNotNullOrUndefined: 1485 return &cache_.kConvertReceiverNotNullOrUndefinedOperator; 1486 } 1487 UNREACHABLE(); 1488} 1489 1490const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole( 1491 CheckFloat64HoleMode mode, FeedbackSource const& feedback) { 1492 if (!feedback.IsValid()) { 1493 switch (mode) { 1494 case CheckFloat64HoleMode::kAllowReturnHole: 1495 return &cache_.kCheckFloat64HoleAllowReturnHoleOperator; 1496 case CheckFloat64HoleMode::kNeverReturnHole: 1497 return &cache_.kCheckFloat64HoleNeverReturnHoleOperator; 1498 } 1499 UNREACHABLE(); 1500 } 1501 return zone()->New<Operator1<CheckFloat64HoleParameters>>( 1502 IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow, 1503 "CheckFloat64Hole", 1, 1, 1, 1, 1, 0, 1504 CheckFloat64HoleParameters(mode, feedback)); 1505} 1506 1507const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntAdd( 1508 BigIntOperationHint hint) { 1509 return zone()->New<Operator1<BigIntOperationHint>>( 1510 IrOpcode::kSpeculativeBigIntAdd, Operator::kFoldable | Operator::kNoThrow, 1511 "SpeculativeBigIntAdd", 2, 1, 1, 1, 1, 0, hint); 1512} 1513 1514const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntSubtract( 1515 BigIntOperationHint hint) { 1516 return zone()->New<Operator1<BigIntOperationHint>>( 1517 IrOpcode::kSpeculativeBigIntSubtract, 1518 Operator::kFoldable | Operator::kNoThrow, "SpeculativeBigIntSubtract", 2, 1519 1, 1, 1, 1, 0, hint); 1520} 1521 1522const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntNegate( 1523 BigIntOperationHint hint) { 1524 return zone()->New<Operator1<BigIntOperationHint>>( 1525 IrOpcode::kSpeculativeBigIntNegate, 1526 Operator::kFoldable | Operator::kNoThrow, "SpeculativeBigIntNegate", 1, 1, 1527 1, 1, 1, 0, hint); 1528} 1529 1530const Operator* SimplifiedOperatorBuilder::CheckClosure( 1531 const Handle<FeedbackCell>& feedback_cell) { 1532 return zone()->New<Operator1<Handle<FeedbackCell>>>( // -- 1533 IrOpcode::kCheckClosure, // opcode 1534 Operator::kNoThrow | Operator::kNoWrite, // flags 1535 "CheckClosure", // name 1536 1, 1, 1, 1, 1, 0, // counts 1537 feedback_cell); // parameter 1538} 1539 1540Handle<FeedbackCell> FeedbackCellOf(const Operator* op) { 1541 DCHECK(IrOpcode::kCheckClosure == op->opcode()); 1542 return OpParameter<Handle<FeedbackCell>>(op); 1543} 1544 1545const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber( 1546 NumberOperationHint hint, const FeedbackSource& feedback) { 1547 if (!feedback.IsValid()) { 1548 switch (hint) { 1549 case NumberOperationHint::kSignedSmall: 1550 return &cache_.kSpeculativeToNumberSignedSmallOperator; 1551 case NumberOperationHint::kSignedSmallInputs: 1552 break; 1553 case NumberOperationHint::kNumber: 1554 return &cache_.kSpeculativeToNumberNumberOperator; 1555 case NumberOperationHint::kNumberOrBoolean: 1556 // Not used currently. 1557 UNREACHABLE(); 1558 case NumberOperationHint::kNumberOrOddball: 1559 return &cache_.kSpeculativeToNumberNumberOrOddballOperator; 1560 } 1561 } 1562 return zone()->New<Operator1<NumberOperationParameters>>( 1563 IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow, 1564 "SpeculativeToNumber", 1, 1, 1, 1, 1, 0, 1565 NumberOperationParameters(hint, feedback)); 1566} 1567 1568const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() { 1569 return &cache_.kEnsureWritableFastElements; 1570} 1571 1572const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements( 1573 GrowFastElementsMode mode, const FeedbackSource& feedback) { 1574 if (!feedback.IsValid()) { 1575 switch (mode) { 1576 case GrowFastElementsMode::kDoubleElements: 1577 return &cache_.kGrowFastElementsOperatorDoubleElements; 1578 case GrowFastElementsMode::kSmiOrObjectElements: 1579 return &cache_.kGrowFastElementsOperatorSmiOrObjectElements; 1580 } 1581 } 1582 return zone()->New<Operator1<GrowFastElementsParameters>>( // -- 1583 IrOpcode::kMaybeGrowFastElements, // opcode 1584 Operator::kNoThrow, // flags 1585 "MaybeGrowFastElements", // name 1586 4, 1, 1, 1, 1, 0, // counts 1587 GrowFastElementsParameters(mode, feedback)); // parameter 1588} 1589 1590const Operator* SimplifiedOperatorBuilder::TransitionElementsKind( 1591 ElementsTransition transition) { 1592 return zone()->New<Operator1<ElementsTransition>>( // -- 1593 IrOpcode::kTransitionElementsKind, // opcode 1594 Operator::kNoThrow, // flags 1595 "TransitionElementsKind", // name 1596 1, 1, 1, 0, 1, 0, // counts 1597 transition); // parameter 1598} 1599 1600const Operator* SimplifiedOperatorBuilder::ArgumentsLength() { 1601 return zone()->New<Operator>( // -- 1602 IrOpcode::kArgumentsLength, // opcode 1603 Operator::kPure, // flags 1604 "ArgumentsLength", // name 1605 0, 0, 0, 1, 0, 0); // counts 1606} 1607 1608const Operator* SimplifiedOperatorBuilder::RestLength( 1609 int formal_parameter_count) { 1610 return zone()->New<Operator1<int>>( // -- 1611 IrOpcode::kRestLength, // opcode 1612 Operator::kPure, // flags 1613 "RestLength", // name 1614 0, 0, 0, 1, 0, 0, // counts 1615 formal_parameter_count); // parameter 1616} 1617 1618int FormalParameterCountOf(const Operator* op) { 1619 DCHECK(op->opcode() == IrOpcode::kArgumentsLength || 1620 op->opcode() == IrOpcode::kRestLength); 1621 return OpParameter<int>(op); 1622} 1623 1624bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) { 1625 return lhs.feedback() == rhs.feedback(); 1626} 1627 1628size_t hash_value(CheckParameters const& p) { 1629 FeedbackSource::Hash feedback_hash; 1630 return feedback_hash(p.feedback()); 1631} 1632 1633std::ostream& operator<<(std::ostream& os, CheckParameters const& p) { 1634 return os << p.feedback(); 1635} 1636 1637CheckParameters const& CheckParametersOf(Operator const* op) { 1638 if (op->opcode() == IrOpcode::kCheckBounds || 1639 op->opcode() == IrOpcode::kCheckedUint32Bounds || 1640 op->opcode() == IrOpcode::kCheckedUint64Bounds) { 1641 return OpParameter<CheckBoundsParameters>(op).check_parameters(); 1642 } 1643#define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name || 1644 CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR) false)); 1645#undef MAKE_OR 1646 return OpParameter<CheckParameters>(op); 1647} 1648 1649bool operator==(CheckBoundsParameters const& lhs, 1650 CheckBoundsParameters const& rhs) { 1651 return lhs.check_parameters() == rhs.check_parameters() && 1652 lhs.flags() == rhs.flags(); 1653} 1654 1655size_t hash_value(CheckBoundsParameters const& p) { 1656 return base::hash_combine(hash_value(p.check_parameters()), p.flags()); 1657} 1658 1659std::ostream& operator<<(std::ostream& os, CheckBoundsParameters const& p) { 1660 os << p.check_parameters() << ", " << p.flags(); 1661 return os; 1662} 1663 1664CheckBoundsParameters const& CheckBoundsParametersOf(Operator const* op) { 1665 DCHECK(op->opcode() == IrOpcode::kCheckBounds || 1666 op->opcode() == IrOpcode::kCheckedUint32Bounds || 1667 op->opcode() == IrOpcode::kCheckedUint64Bounds); 1668 return OpParameter<CheckBoundsParameters>(op); 1669} 1670 1671bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) { 1672 return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback(); 1673} 1674 1675size_t hash_value(CheckIfParameters const& p) { 1676 FeedbackSource::Hash feedback_hash; 1677 return base::hash_combine(p.reason(), feedback_hash(p.feedback())); 1678} 1679 1680std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) { 1681 return os << p.reason() << ", " << p.feedback(); 1682} 1683 1684CheckIfParameters const& CheckIfParametersOf(Operator const* op) { 1685 CHECK(op->opcode() == IrOpcode::kCheckIf); 1686 return OpParameter<CheckIfParameters>(op); 1687} 1688 1689FastApiCallParameters const& FastApiCallParametersOf(const Operator* op) { 1690 DCHECK_EQ(IrOpcode::kFastApiCall, op->opcode()); 1691 return OpParameter<FastApiCallParameters>(op); 1692} 1693 1694std::ostream& operator<<(std::ostream& os, FastApiCallParameters const& p) { 1695 const auto& c_functions = p.c_functions(); 1696 for (size_t i = 0; i < c_functions.size(); i++) { 1697 os << c_functions[i].address << ":" << c_functions[i].signature << ", "; 1698 } 1699 return os << p.feedback() << ", " << p.descriptor(); 1700} 1701 1702size_t hash_value(FastApiCallParameters const& p) { 1703 const auto& c_functions = p.c_functions(); 1704 size_t hash = 0; 1705 for (size_t i = 0; i < c_functions.size(); i++) { 1706 hash = base::hash_combine(c_functions[i].address, c_functions[i].signature); 1707 } 1708 return base::hash_combine(hash, FeedbackSource::Hash()(p.feedback()), 1709 p.descriptor()); 1710} 1711 1712bool operator==(FastApiCallParameters const& lhs, 1713 FastApiCallParameters const& rhs) { 1714 return lhs.c_functions() == rhs.c_functions() && 1715 lhs.feedback() == rhs.feedback() && 1716 lhs.descriptor() == rhs.descriptor(); 1717} 1718 1719const Operator* SimplifiedOperatorBuilder::NewDoubleElements( 1720 AllocationType allocation) { 1721 return zone()->New<Operator1<AllocationType>>( // -- 1722 IrOpcode::kNewDoubleElements, // opcode 1723 Operator::kEliminatable, // flags 1724 "NewDoubleElements", // name 1725 1, 1, 1, 1, 1, 0, // counts 1726 allocation); // parameter 1727} 1728 1729const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements( 1730 AllocationType allocation) { 1731 return zone()->New<Operator1<AllocationType>>( // -- 1732 IrOpcode::kNewSmiOrObjectElements, // opcode 1733 Operator::kEliminatable, // flags 1734 "NewSmiOrObjectElements", // name 1735 1, 1, 1, 1, 1, 0, // counts 1736 allocation); // parameter 1737} 1738 1739const Operator* SimplifiedOperatorBuilder::NewArgumentsElements( 1740 CreateArgumentsType type, int formal_parameter_count) { 1741 return zone()->New<Operator1<NewArgumentsElementsParameters>>( // -- 1742 IrOpcode::kNewArgumentsElements, // opcode 1743 Operator::kEliminatable, // flags 1744 "NewArgumentsElements", // name 1745 1, 1, 0, 1, 1, 0, // counts 1746 NewArgumentsElementsParameters(type, 1747 formal_parameter_count)); // parameter 1748} 1749 1750bool operator==(const NewArgumentsElementsParameters& lhs, 1751 const NewArgumentsElementsParameters& rhs) { 1752 return lhs.arguments_type() == rhs.arguments_type() && 1753 lhs.formal_parameter_count() == rhs.formal_parameter_count(); 1754} 1755 1756inline size_t hash_value(const NewArgumentsElementsParameters& params) { 1757 return base::hash_combine(params.arguments_type(), 1758 params.formal_parameter_count()); 1759} 1760 1761std::ostream& operator<<(std::ostream& os, 1762 const NewArgumentsElementsParameters& params) { 1763 return os << params.arguments_type() 1764 << ", parameter_count = " << params.formal_parameter_count(); 1765} 1766 1767const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf( 1768 const Operator* op) { 1769 DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode()); 1770 return OpParameter<NewArgumentsElementsParameters>(op); 1771} 1772 1773const Operator* SimplifiedOperatorBuilder::Allocate(Type type, 1774 AllocationType allocation) { 1775 return zone()->New<Operator1<AllocateParameters>>( 1776 IrOpcode::kAllocate, Operator::kEliminatable, "Allocate", 1, 1, 1, 1, 1, 1777 0, AllocateParameters(type, allocation)); 1778} 1779 1780const Operator* SimplifiedOperatorBuilder::AllocateRaw( 1781 Type type, AllocationType allocation, 1782 AllowLargeObjects allow_large_objects) { 1783 return zone()->New<Operator1<AllocateParameters>>( 1784 IrOpcode::kAllocateRaw, Operator::kEliminatable, "AllocateRaw", 1, 1, 1, 1785 1, 1, 1, AllocateParameters(type, allocation, allow_large_objects)); 1786} 1787 1788#define SPECULATIVE_NUMBER_BINOP(Name) \ 1789 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ 1790 switch (hint) { \ 1791 case NumberOperationHint::kSignedSmall: \ 1792 return &cache_.k##Name##SignedSmallOperator; \ 1793 case NumberOperationHint::kSignedSmallInputs: \ 1794 return &cache_.k##Name##SignedSmallInputsOperator; \ 1795 case NumberOperationHint::kNumber: \ 1796 return &cache_.k##Name##NumberOperator; \ 1797 case NumberOperationHint::kNumberOrBoolean: \ 1798 /* Not used currenly. */ \ 1799 UNREACHABLE(); \ 1800 case NumberOperationHint::kNumberOrOddball: \ 1801 return &cache_.k##Name##NumberOrOddballOperator; \ 1802 } \ 1803 UNREACHABLE(); \ 1804 return nullptr; \ 1805 } 1806SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) 1807SPECULATIVE_NUMBER_BINOP(SpeculativeNumberLessThan) 1808SPECULATIVE_NUMBER_BINOP(SpeculativeNumberLessThanOrEqual) 1809#undef SPECULATIVE_NUMBER_BINOP 1810const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual( 1811 NumberOperationHint hint) { 1812 switch (hint) { 1813 case NumberOperationHint::kSignedSmall: 1814 return &cache_.kSpeculativeNumberEqualSignedSmallOperator; 1815 case NumberOperationHint::kSignedSmallInputs: 1816 return &cache_.kSpeculativeNumberEqualSignedSmallInputsOperator; 1817 case NumberOperationHint::kNumber: 1818 return &cache_.kSpeculativeNumberEqualNumberOperator; 1819 case NumberOperationHint::kNumberOrBoolean: 1820 return &cache_.kSpeculativeNumberEqualNumberOrBooleanOperator; 1821 case NumberOperationHint::kNumberOrOddball: 1822 return &cache_.kSpeculativeNumberEqualNumberOrOddballOperator; 1823 } 1824 UNREACHABLE(); 1825} 1826 1827#define ACCESS_OP_LIST(V) \ 1828 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ 1829 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ 1830 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ 1831 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ 1832 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \ 1833 V(LoadFromObject, ObjectAccess, Operator::kNoWrite, 2, 1, 1) \ 1834 V(StoreToObject, ObjectAccess, Operator::kNoRead, 3, 1, 0) \ 1835 V(LoadImmutableFromObject, ObjectAccess, Operator::kNoWrite, 2, 1, 1) \ 1836 V(InitializeImmutableInObject, ObjectAccess, Operator::kNoRead, 3, 1, 0) \ 1837 V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ 1838 V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) 1839 1840#define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ 1841 output_count) \ 1842 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ 1843 return zone()->New<Operator1<Type>>( \ 1844 IrOpcode::k##Name, \ 1845 Operator::kNoDeopt | Operator::kNoThrow | properties, #Name, \ 1846 value_input_count, 1, control_input_count, output_count, 1, 0, \ 1847 access); \ 1848 } 1849ACCESS_OP_LIST(ACCESS) 1850#undef ACCESS 1851 1852const Operator* SimplifiedOperatorBuilder::StoreField( 1853 const FieldAccess& access, bool maybe_initializing_or_transitioning) { 1854 FieldAccess store_access = access; 1855 store_access.maybe_initializing_or_transitioning_store = 1856 maybe_initializing_or_transitioning; 1857 return zone()->New<Operator1<FieldAccess>>( 1858 IrOpcode::kStoreField, 1859 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoRead, "StoreField", 1860 2, 1, 1, 0, 1, 0, store_access); 1861} 1862 1863const Operator* SimplifiedOperatorBuilder::LoadMessage() { 1864 return zone()->New<Operator>(IrOpcode::kLoadMessage, Operator::kEliminatable, 1865 "LoadMessage", 1, 1, 1, 1, 1, 0); 1866} 1867 1868const Operator* SimplifiedOperatorBuilder::StoreMessage() { 1869 return zone()->New<Operator>( 1870 IrOpcode::kStoreMessage, 1871 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoRead, 1872 "StoreMessage", 2, 1, 1, 0, 1, 0); 1873} 1874 1875const Operator* SimplifiedOperatorBuilder::LoadStackArgument() { 1876 return &cache_.kLoadStackArgument; 1877} 1878 1879const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement( 1880 Handle<Map> double_map, Handle<Map> fast_map) { 1881 TransitionAndStoreElementParameters parameters(double_map, fast_map); 1882 return zone()->New<Operator1<TransitionAndStoreElementParameters>>( 1883 IrOpcode::kTransitionAndStoreElement, 1884 Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3, 1885 1, 1, 0, 1, 0, parameters); 1886} 1887 1888const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() { 1889 return zone()->New<Operator>(IrOpcode::kStoreSignedSmallElement, 1890 Operator::kNoDeopt | Operator::kNoThrow, 1891 "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0); 1892} 1893 1894const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement( 1895 Handle<Map> double_map) { 1896 TransitionAndStoreNumberElementParameters parameters(double_map); 1897 return zone()->New<Operator1<TransitionAndStoreNumberElementParameters>>( 1898 IrOpcode::kTransitionAndStoreNumberElement, 1899 Operator::kNoDeopt | Operator::kNoThrow, 1900 "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters); 1901} 1902 1903const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement( 1904 Handle<Map> fast_map, Type value_type) { 1905 TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type); 1906 return zone()->New<Operator1<TransitionAndStoreNonNumberElementParameters>>( 1907 IrOpcode::kTransitionAndStoreNonNumberElement, 1908 Operator::kNoDeopt | Operator::kNoThrow, 1909 "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters); 1910} 1911 1912const Operator* SimplifiedOperatorBuilder::FastApiCall( 1913 const FastApiCallFunctionVector& c_functions, 1914 FeedbackSource const& feedback, CallDescriptor* descriptor) { 1915 DCHECK(!c_functions.empty()); 1916 1917 // All function overloads have the same number of arguments and options. 1918 const CFunctionInfo* signature = c_functions[0].signature; 1919 const int argument_count = signature->ArgumentCount(); 1920 for (size_t i = 1; i < c_functions.size(); i++) { 1921 CHECK_NOT_NULL(c_functions[i].signature); 1922 DCHECK_EQ(c_functions[i].signature->ArgumentCount(), argument_count); 1923 DCHECK_EQ(c_functions[i].signature->HasOptions(), 1924 c_functions[0].signature->HasOptions()); 1925 } 1926 1927 int value_input_count = 1928 argument_count + 1929 static_cast<int>(descriptor->ParameterCount()) + // slow call 1930 FastApiCallNode::kEffectAndControlInputCount; 1931 return zone()->New<Operator1<FastApiCallParameters>>( 1932 IrOpcode::kFastApiCall, Operator::kNoThrow, "FastApiCall", 1933 value_input_count, 1, 1, 1, 1, 0, 1934 FastApiCallParameters(c_functions, feedback, descriptor)); 1935} 1936 1937int FastApiCallNode::FastCallExtraInputCount() const { 1938 const CFunctionInfo* signature = Parameters().c_functions()[0].signature; 1939 CHECK_NOT_NULL(signature); 1940 return kEffectAndControlInputCount + (signature->HasOptions() ? 1 : 0); 1941} 1942 1943int FastApiCallNode::FastCallArgumentCount() const { 1944 FastApiCallParameters p = FastApiCallParametersOf(node()->op()); 1945 const CFunctionInfo* signature = p.c_functions()[0].signature; 1946 CHECK_NOT_NULL(signature); 1947 return signature->ArgumentCount(); 1948} 1949 1950int FastApiCallNode::SlowCallArgumentCount() const { 1951 FastApiCallParameters p = FastApiCallParametersOf(node()->op()); 1952 CallDescriptor* descriptor = p.descriptor(); 1953 CHECK_NOT_NULL(descriptor); 1954 return static_cast<int>(descriptor->ParameterCount()) + 1955 kContextAndFrameStateInputCount; 1956} 1957 1958#undef PURE_OP_LIST 1959#undef EFFECT_DEPENDENT_OP_LIST 1960#undef SPECULATIVE_NUMBER_BINOP_LIST 1961#undef CHECKED_WITH_FEEDBACK_OP_LIST 1962#undef CHECKED_BOUNDS_OP_LIST 1963#undef CHECKED_OP_LIST 1964#undef ACCESS_OP_LIST 1965 1966} // namespace compiler 1967} // namespace internal 1968} // namespace v8 1969