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#ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ 6#define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ 7 8#include <iosfwd> 9 10#include "src/base/compiler-specific.h" 11#include "src/codegen/machine-type.h" 12#include "src/codegen/tnode.h" 13#include "src/common/globals.h" 14#include "src/compiler/common-operator.h" 15#include "src/compiler/feedback-source.h" 16#include "src/compiler/node-properties.h" 17#include "src/compiler/operator.h" 18#include "src/compiler/types.h" 19#include "src/compiler/write-barrier-kind.h" 20#include "src/deoptimizer/deoptimize-reason.h" 21#include "src/handles/handles.h" 22#include "src/handles/maybe-handles.h" 23#include "src/objects/objects.h" 24#include "src/objects/type-hints.h" 25#include "src/zone/zone-handle-set.h" 26 27namespace v8 { 28class CFunctionInfo; 29 30namespace internal { 31 32// Forward declarations. 33enum class AbortReason : uint8_t; 34class Zone; 35 36namespace compiler { 37 38// Forward declarations. 39class Operator; 40struct SimplifiedOperatorGlobalCache; 41class CallDescriptor; 42 43enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase }; 44 45size_t hash_value(BaseTaggedness); 46 47std::ostream& operator<<(std::ostream&, BaseTaggedness); 48 49struct ConstFieldInfo { 50 // the map that introduced the const field, if any. An access is considered 51 // mutable iff the handle is null. 52 MaybeHandle<Map> owner_map; 53 54 ConstFieldInfo() : owner_map(MaybeHandle<Map>()) {} 55 explicit ConstFieldInfo(Handle<Map> owner_map) : owner_map(owner_map) {} 56 57 bool IsConst() const { return !owner_map.is_null(); } 58 59 // No const field owner, i.e., a mutable field 60 static ConstFieldInfo None() { return ConstFieldInfo(); } 61}; 62 63V8_EXPORT_PRIVATE bool operator==(ConstFieldInfo const&, ConstFieldInfo const&); 64 65size_t hash_value(ConstFieldInfo const&); 66 67V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, 68 ConstFieldInfo const&); 69 70// An access descriptor for loads/stores of fixed structures like field 71// accesses of heap objects. Accesses from either tagged or untagged base 72// pointers are supported; untagging is done automatically during lowering. 73struct FieldAccess { 74 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. 75 int offset; // offset of the field, without tag. 76 MaybeHandle<Name> name; // debugging only. 77 MaybeHandle<Map> map; // map of the field value (if known). 78 Type type; // type of the field. 79 MachineType machine_type; // machine type of the field. 80 WriteBarrierKind write_barrier_kind; // write barrier hint. 81 ConstFieldInfo const_field_info; // the constness of this access, and the 82 // field owner map, if the access is const 83 bool is_store_in_literal; // originates from a kStoreInLiteral access 84#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 85 ExternalPointerTag external_pointer_tag = kExternalPointerNullTag; 86#endif 87 bool maybe_initializing_or_transitioning_store; // store is potentially 88 // initializing a newly 89 // allocated object or part 90 // of a map transition. 91 92 FieldAccess() 93 : base_is_tagged(kTaggedBase), 94 offset(0), 95 type(Type::None()), 96 machine_type(MachineType::None()), 97 write_barrier_kind(kFullWriteBarrier), 98 const_field_info(ConstFieldInfo::None()), 99 is_store_in_literal(false), 100 maybe_initializing_or_transitioning_store(false) {} 101 102 FieldAccess(BaseTaggedness base_is_tagged, int offset, MaybeHandle<Name> name, 103 MaybeHandle<Map> map, Type type, MachineType machine_type, 104 WriteBarrierKind write_barrier_kind, 105 ConstFieldInfo const_field_info = ConstFieldInfo::None(), 106 bool is_store_in_literal = false, 107#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 108 ExternalPointerTag external_pointer_tag = kExternalPointerNullTag, 109#endif 110 bool maybe_initializing_or_transitioning_store = false) 111 : base_is_tagged(base_is_tagged), 112 offset(offset), 113 name(name), 114 map(map), 115 type(type), 116 machine_type(machine_type), 117 write_barrier_kind(write_barrier_kind), 118 const_field_info(const_field_info), 119 is_store_in_literal(is_store_in_literal), 120#ifdef V8_SANDBOXED_EXTERNAL_POINTERS 121 external_pointer_tag(external_pointer_tag), 122#endif 123 maybe_initializing_or_transitioning_store( 124 maybe_initializing_or_transitioning_store) { 125 DCHECK_GE(offset, 0); 126 DCHECK_IMPLIES( 127 machine_type.IsMapWord(), 128 offset == HeapObject::kMapOffset && base_is_tagged != kUntaggedBase); 129 DCHECK_IMPLIES(machine_type.IsMapWord(), 130 (write_barrier_kind == kMapWriteBarrier || 131 write_barrier_kind == kNoWriteBarrier || 132 write_barrier_kind == kAssertNoWriteBarrier)); 133 } 134 135 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } 136}; 137 138V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&); 139 140size_t hash_value(FieldAccess const&); 141 142V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&); 143 144V8_EXPORT_PRIVATE FieldAccess const& FieldAccessOf(const Operator* op) 145 V8_WARN_UNUSED_RESULT; 146 147template <> 148void Operator1<FieldAccess>::PrintParameter(std::ostream& os, 149 PrintVerbosity verbose) const; 150 151// An access descriptor for loads/stores of indexed structures like characters 152// in strings or off-heap backing stores. Accesses from either tagged or 153// untagged base pointers are supported; untagging is done automatically during 154// lowering. 155struct ElementAccess { 156 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. 157 int header_size; // size of the header, without tag. 158 Type type; // type of the element. 159 MachineType machine_type; // machine type of the element. 160 WriteBarrierKind write_barrier_kind; // write barrier hint. 161 162 ElementAccess() 163 : base_is_tagged(kTaggedBase), 164 header_size(0), 165 type(Type::None()), 166 machine_type(MachineType::None()), 167 write_barrier_kind(kFullWriteBarrier) {} 168 169 ElementAccess(BaseTaggedness base_is_tagged, int header_size, Type type, 170 MachineType machine_type, WriteBarrierKind write_barrier_kind) 171 : base_is_tagged(base_is_tagged), 172 header_size(header_size), 173 type(type), 174 machine_type(machine_type), 175 write_barrier_kind(write_barrier_kind) {} 176 177 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } 178}; 179 180V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&); 181 182size_t hash_value(ElementAccess const&); 183 184V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&); 185 186V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op) 187 V8_WARN_UNUSED_RESULT; 188 189ExternalArrayType ExternalArrayTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; 190 191// An access descriptor for loads/stores of CSA-accessible structures. 192struct ObjectAccess { 193 MachineType machine_type; // machine type of the field. 194 WriteBarrierKind write_barrier_kind; // write barrier hint. 195 196 ObjectAccess() 197 : machine_type(MachineType::None()), 198 write_barrier_kind(kFullWriteBarrier) {} 199 200 ObjectAccess(MachineType machine_type, WriteBarrierKind write_barrier_kind) 201 : machine_type(machine_type), write_barrier_kind(write_barrier_kind) {} 202 203 int tag() const { return kHeapObjectTag; } 204}; 205 206V8_EXPORT_PRIVATE bool operator==(ObjectAccess const&, ObjectAccess const&); 207 208size_t hash_value(ObjectAccess const&); 209 210V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ObjectAccess const&); 211 212V8_EXPORT_PRIVATE ObjectAccess const& ObjectAccessOf(const Operator* op) 213 V8_WARN_UNUSED_RESULT; 214 215// The ConvertReceiverMode is used as parameter by ConvertReceiver operators. 216ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) 217 V8_WARN_UNUSED_RESULT; 218 219// A the parameters for several Check nodes. The {feedback} parameter is 220// optional. If {feedback} references a valid CallIC slot and this MapCheck 221// fails, then speculation on that CallIC slot will be disabled. 222class CheckParameters final { 223 public: 224 explicit CheckParameters(const FeedbackSource& feedback) 225 : feedback_(feedback) {} 226 227 FeedbackSource const& feedback() const { return feedback_; } 228 229 private: 230 FeedbackSource feedback_; 231}; 232 233bool operator==(CheckParameters const&, CheckParameters const&); 234 235size_t hash_value(CheckParameters const&); 236 237std::ostream& operator<<(std::ostream&, CheckParameters const&); 238 239CheckParameters const& CheckParametersOf(Operator const*) V8_WARN_UNUSED_RESULT; 240 241enum class CheckBoundsFlag : uint8_t { 242 kConvertStringAndMinusZero = 1 << 0, // instead of deopting on such inputs 243 kAbortOnOutOfBounds = 1 << 1, // instead of deopting if input is OOB 244}; 245using CheckBoundsFlags = base::Flags<CheckBoundsFlag>; 246DEFINE_OPERATORS_FOR_FLAGS(CheckBoundsFlags) 247 248class CheckBoundsParameters final { 249 public: 250 CheckBoundsParameters(const FeedbackSource& feedback, CheckBoundsFlags flags) 251 : check_parameters_(feedback), flags_(flags) {} 252 253 CheckBoundsFlags flags() const { return flags_; } 254 const CheckParameters& check_parameters() const { return check_parameters_; } 255 256 private: 257 CheckParameters check_parameters_; 258 CheckBoundsFlags flags_; 259}; 260 261bool operator==(CheckBoundsParameters const&, CheckBoundsParameters const&); 262 263size_t hash_value(CheckBoundsParameters const&); 264 265std::ostream& operator<<(std::ostream&, CheckBoundsParameters const&); 266 267CheckBoundsParameters const& CheckBoundsParametersOf(Operator const*) 268 V8_WARN_UNUSED_RESULT; 269 270class CheckIfParameters final { 271 public: 272 explicit CheckIfParameters(DeoptimizeReason reason, 273 const FeedbackSource& feedback) 274 : reason_(reason), feedback_(feedback) {} 275 276 FeedbackSource const& feedback() const { return feedback_; } 277 DeoptimizeReason reason() const { return reason_; } 278 279 private: 280 DeoptimizeReason reason_; 281 FeedbackSource feedback_; 282}; 283 284bool operator==(CheckIfParameters const&, CheckIfParameters const&); 285 286size_t hash_value(CheckIfParameters const&); 287 288std::ostream& operator<<(std::ostream&, CheckIfParameters const&); 289 290CheckIfParameters const& CheckIfParametersOf(Operator const*) 291 V8_WARN_UNUSED_RESULT; 292 293enum class CheckFloat64HoleMode : uint8_t { 294 kNeverReturnHole, // Never return the hole (deoptimize instead). 295 kAllowReturnHole // Allow to return the hole (signaling NaN). 296}; 297 298size_t hash_value(CheckFloat64HoleMode); 299 300std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode); 301 302class CheckFloat64HoleParameters { 303 public: 304 CheckFloat64HoleParameters(CheckFloat64HoleMode mode, 305 FeedbackSource const& feedback) 306 : mode_(mode), feedback_(feedback) {} 307 308 CheckFloat64HoleMode mode() const { return mode_; } 309 FeedbackSource const& feedback() const { return feedback_; } 310 311 private: 312 CheckFloat64HoleMode mode_; 313 FeedbackSource feedback_; 314}; 315 316CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(Operator const*) 317 V8_WARN_UNUSED_RESULT; 318 319std::ostream& operator<<(std::ostream&, CheckFloat64HoleParameters const&); 320 321size_t hash_value(CheckFloat64HoleParameters const&); 322 323bool operator==(CheckFloat64HoleParameters const&, 324 CheckFloat64HoleParameters const&); 325bool operator!=(CheckFloat64HoleParameters const&, 326 CheckFloat64HoleParameters const&); 327 328// Parameter for CheckClosure node. 329Handle<FeedbackCell> FeedbackCellOf(const Operator* op); 330 331enum class CheckTaggedInputMode : uint8_t { 332 kNumber, 333 kNumberOrBoolean, 334 kNumberOrOddball, 335}; 336 337size_t hash_value(CheckTaggedInputMode); 338 339V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, CheckTaggedInputMode); 340 341class CheckTaggedInputParameters { 342 public: 343 CheckTaggedInputParameters(CheckTaggedInputMode mode, 344 const FeedbackSource& feedback) 345 : mode_(mode), feedback_(feedback) {} 346 347 CheckTaggedInputMode mode() const { return mode_; } 348 const FeedbackSource& feedback() const { return feedback_; } 349 350 private: 351 CheckTaggedInputMode mode_; 352 FeedbackSource feedback_; 353}; 354 355const CheckTaggedInputParameters& CheckTaggedInputParametersOf(const Operator*) 356 V8_WARN_UNUSED_RESULT; 357 358std::ostream& operator<<(std::ostream&, 359 const CheckTaggedInputParameters& params); 360 361size_t hash_value(const CheckTaggedInputParameters& params); 362 363bool operator==(CheckTaggedInputParameters const&, 364 CheckTaggedInputParameters const&); 365 366enum class CheckForMinusZeroMode : uint8_t { 367 kCheckForMinusZero, 368 kDontCheckForMinusZero, 369}; 370 371size_t hash_value(CheckForMinusZeroMode); 372 373V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, 374 CheckForMinusZeroMode); 375 376CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) 377 V8_WARN_UNUSED_RESULT; 378 379class CheckMinusZeroParameters { 380 public: 381 CheckMinusZeroParameters(CheckForMinusZeroMode mode, 382 const FeedbackSource& feedback) 383 : mode_(mode), feedback_(feedback) {} 384 385 CheckForMinusZeroMode mode() const { return mode_; } 386 const FeedbackSource& feedback() const { return feedback_; } 387 388 private: 389 CheckForMinusZeroMode mode_; 390 FeedbackSource feedback_; 391}; 392 393V8_EXPORT_PRIVATE const CheckMinusZeroParameters& CheckMinusZeroParametersOf( 394 const Operator* op) V8_WARN_UNUSED_RESULT; 395 396V8_EXPORT_PRIVATE std::ostream& operator<<( 397 std::ostream&, const CheckMinusZeroParameters& params); 398 399size_t hash_value(const CheckMinusZeroParameters& params); 400 401bool operator==(CheckMinusZeroParameters const&, 402 CheckMinusZeroParameters const&); 403 404enum class CheckMapsFlag : uint8_t { 405 kNone = 0u, 406 kTryMigrateInstance = 1u << 0, 407}; 408using CheckMapsFlags = base::Flags<CheckMapsFlag>; 409 410DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags) 411 412std::ostream& operator<<(std::ostream&, CheckMapsFlags); 413 414// A descriptor for map checks. The {feedback} parameter is optional. 415// If {feedback} references a valid CallIC slot and this MapCheck fails, 416// then speculation on that CallIC slot will be disabled. 417class CheckMapsParameters final { 418 public: 419 CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps, 420 const FeedbackSource& feedback) 421 : flags_(flags), maps_(maps), feedback_(feedback) {} 422 423 CheckMapsFlags flags() const { return flags_; } 424 ZoneHandleSet<Map> const& maps() const { return maps_; } 425 FeedbackSource const& feedback() const { return feedback_; } 426 427 private: 428 CheckMapsFlags const flags_; 429 ZoneHandleSet<Map> const maps_; 430 FeedbackSource const feedback_; 431}; 432 433bool operator==(CheckMapsParameters const&, CheckMapsParameters const&); 434 435size_t hash_value(CheckMapsParameters const&); 436 437std::ostream& operator<<(std::ostream&, CheckMapsParameters const&); 438 439CheckMapsParameters const& CheckMapsParametersOf(Operator const*) 440 V8_WARN_UNUSED_RESULT; 441 442ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const*) V8_WARN_UNUSED_RESULT; 443 444// Parameters for CompareMaps operator. 445ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const*) 446 V8_WARN_UNUSED_RESULT; 447 448// A descriptor for growing elements backing stores. 449enum class GrowFastElementsMode : uint8_t { 450 kDoubleElements, 451 kSmiOrObjectElements 452}; 453 454inline size_t hash_value(GrowFastElementsMode mode) { 455 return static_cast<uint8_t>(mode); 456} 457 458std::ostream& operator<<(std::ostream&, GrowFastElementsMode); 459 460class GrowFastElementsParameters { 461 public: 462 GrowFastElementsParameters(GrowFastElementsMode mode, 463 const FeedbackSource& feedback) 464 : mode_(mode), feedback_(feedback) {} 465 466 GrowFastElementsMode mode() const { return mode_; } 467 const FeedbackSource& feedback() const { return feedback_; } 468 469 private: 470 GrowFastElementsMode mode_; 471 FeedbackSource feedback_; 472}; 473 474bool operator==(const GrowFastElementsParameters&, 475 const GrowFastElementsParameters&); 476 477inline size_t hash_value(const GrowFastElementsParameters&); 478 479std::ostream& operator<<(std::ostream&, const GrowFastElementsParameters&); 480 481const GrowFastElementsParameters& GrowFastElementsParametersOf(const Operator*) 482 V8_WARN_UNUSED_RESULT; 483 484// A descriptor for elements kind transitions. 485class ElementsTransition final { 486 public: 487 enum Mode : uint8_t { 488 kFastTransition, // simple transition, just updating the map. 489 kSlowTransition // full transition, round-trip to the runtime. 490 }; 491 492 ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target) 493 : mode_(mode), source_(source), target_(target) {} 494 495 Mode mode() const { return mode_; } 496 Handle<Map> source() const { return source_; } 497 Handle<Map> target() const { return target_; } 498 499 private: 500 Mode const mode_; 501 Handle<Map> const source_; 502 Handle<Map> const target_; 503}; 504 505bool operator==(ElementsTransition const&, ElementsTransition const&); 506 507size_t hash_value(ElementsTransition); 508 509std::ostream& operator<<(std::ostream&, ElementsTransition); 510 511ElementsTransition const& ElementsTransitionOf(const Operator* op) 512 V8_WARN_UNUSED_RESULT; 513 514// Parameters for TransitionAndStoreElement, or 515// TransitionAndStoreNonNumberElement, or 516// TransitionAndStoreNumberElement. 517Handle<Map> DoubleMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; 518Handle<Map> FastMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; 519 520// Parameters for TransitionAndStoreNonNumberElement. 521Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; 522 523// A hint for speculative number operations. 524enum class NumberOperationHint : uint8_t { 525 kSignedSmall, // Inputs were Smi, output was in Smi. 526 kSignedSmallInputs, // Inputs were Smi, output was Number. 527 kNumber, // Inputs were Number, output was Number. 528 kNumberOrBoolean, // Inputs were Number or Boolean, output was Number. 529 kNumberOrOddball, // Inputs were Number or Oddball, output was Number. 530}; 531 532enum class BigIntOperationHint : uint8_t { 533 kBigInt, 534}; 535 536size_t hash_value(NumberOperationHint); 537size_t hash_value(BigIntOperationHint); 538 539V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint); 540V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint); 541V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op) 542 V8_WARN_UNUSED_RESULT; 543 544class NumberOperationParameters { 545 public: 546 NumberOperationParameters(NumberOperationHint hint, 547 const FeedbackSource& feedback) 548 : hint_(hint), feedback_(feedback) {} 549 550 NumberOperationHint hint() const { return hint_; } 551 const FeedbackSource& feedback() const { return feedback_; } 552 553 private: 554 NumberOperationHint hint_; 555 FeedbackSource feedback_; 556}; 557 558size_t hash_value(NumberOperationParameters const&); 559V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, 560 const NumberOperationParameters&); 561bool operator==(NumberOperationParameters const&, 562 NumberOperationParameters const&); 563const NumberOperationParameters& NumberOperationParametersOf(const Operator* op) 564 V8_WARN_UNUSED_RESULT; 565 566class SpeculativeBigIntAsNParameters { 567 public: 568 SpeculativeBigIntAsNParameters(int bits, const FeedbackSource& feedback) 569 : bits_(bits), feedback_(feedback) { 570 DCHECK_GE(bits_, 0); 571 DCHECK_LE(bits_, 64); 572 } 573 574 int bits() const { return bits_; } 575 const FeedbackSource& feedback() const { return feedback_; } 576 577 private: 578 int bits_; 579 FeedbackSource feedback_; 580}; 581 582size_t hash_value(SpeculativeBigIntAsNParameters const&); 583V8_EXPORT_PRIVATE std::ostream& operator<<( 584 std::ostream&, const SpeculativeBigIntAsNParameters&); 585bool operator==(SpeculativeBigIntAsNParameters const&, 586 SpeculativeBigIntAsNParameters const&); 587const SpeculativeBigIntAsNParameters& SpeculativeBigIntAsNParametersOf( 588 const Operator* op) V8_WARN_UNUSED_RESULT; 589 590int FormalParameterCountOf(const Operator* op) V8_WARN_UNUSED_RESULT; 591 592class AllocateParameters { 593 public: 594 AllocateParameters( 595 Type type, AllocationType allocation_type, 596 AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse) 597 : type_(type), 598 allocation_type_(allocation_type), 599 allow_large_objects_(allow_large_objects) {} 600 601 Type type() const { return type_; } 602 AllocationType allocation_type() const { return allocation_type_; } 603 AllowLargeObjects allow_large_objects() const { return allow_large_objects_; } 604 605 private: 606 Type type_; 607 AllocationType allocation_type_; 608 AllowLargeObjects allow_large_objects_; 609}; 610 611bool IsCheckedWithFeedback(const Operator* op); 612 613size_t hash_value(AllocateParameters); 614 615V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters); 616 617bool operator==(AllocateParameters const&, AllocateParameters const&); 618 619const AllocateParameters& AllocateParametersOf(const Operator* op) 620 V8_WARN_UNUSED_RESULT; 621 622AllocationType AllocationTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; 623 624Type AllocateTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; 625 626UnicodeEncoding UnicodeEncodingOf(const Operator*) V8_WARN_UNUSED_RESULT; 627 628AbortReason AbortReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT; 629 630DeoptimizeReason DeoptimizeReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT; 631 632class NewArgumentsElementsParameters { 633 public: 634 NewArgumentsElementsParameters(CreateArgumentsType type, 635 int formal_parameter_count) 636 : type_(type), formal_parameter_count_(formal_parameter_count) {} 637 638 CreateArgumentsType arguments_type() const { return type_; } 639 int formal_parameter_count() const { return formal_parameter_count_; } 640 641 private: 642 CreateArgumentsType type_; 643 int formal_parameter_count_; 644}; 645 646bool operator==(const NewArgumentsElementsParameters&, 647 const NewArgumentsElementsParameters&); 648 649inline size_t hash_value(const NewArgumentsElementsParameters&); 650 651std::ostream& operator<<(std::ostream&, const NewArgumentsElementsParameters&); 652 653const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf( 654 const Operator*) V8_WARN_UNUSED_RESULT; 655 656struct FastApiCallFunction { 657 Address address; 658 const CFunctionInfo* signature; 659 660 bool operator==(const FastApiCallFunction& rhs) const { 661 return address == rhs.address && signature == rhs.signature; 662 } 663}; 664typedef ZoneVector<FastApiCallFunction> FastApiCallFunctionVector; 665 666class FastApiCallParameters { 667 public: 668 explicit FastApiCallParameters(const FastApiCallFunctionVector& c_functions, 669 FeedbackSource const& feedback, 670 CallDescriptor* descriptor) 671 : c_functions_(c_functions), 672 feedback_(feedback), 673 descriptor_(descriptor) {} 674 675 const FastApiCallFunctionVector& c_functions() const { return c_functions_; } 676 FeedbackSource const& feedback() const { return feedback_; } 677 CallDescriptor* descriptor() const { return descriptor_; } 678 679 private: 680 // A single FastApiCall node can represent multiple overloaded functions. 681 const FastApiCallFunctionVector c_functions_; 682 683 const FeedbackSource feedback_; 684 CallDescriptor* descriptor_; 685}; 686 687FastApiCallParameters const& FastApiCallParametersOf(const Operator* op) 688 V8_WARN_UNUSED_RESULT; 689 690V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, 691 FastApiCallParameters const&); 692 693size_t hash_value(FastApiCallParameters const&); 694 695bool operator==(FastApiCallParameters const&, FastApiCallParameters const&); 696 697// Interface for building simplified operators, which represent the 698// medium-level operations of V8, including adding numbers, allocating objects, 699// indexing into objects and arrays, etc. 700// All operators are typed but many are representation independent. 701 702// Number values from JS can be in one of these representations: 703// - Tagged: word-sized integer that is either 704// - a signed small integer (31 or 32 bits plus a tag) 705// - a tagged pointer to a HeapNumber object that has a float64 field 706// - Int32: an untagged signed 32-bit integer 707// - Uint32: an untagged unsigned 32-bit integer 708// - Float64: an untagged float64 709 710// Additional representations for intermediate code or non-JS code: 711// - Int64: an untagged signed 64-bit integer 712// - Uint64: an untagged unsigned 64-bit integer 713// - Float32: an untagged float32 714 715// Boolean values can be: 716// - Bool: a tagged pointer to either the canonical JS #false or 717// the canonical JS #true object 718// - Bit: an untagged integer 0 or 1, but word-sized 719class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final 720 : public NON_EXPORTED_BASE(ZoneObject) { 721 public: 722 explicit SimplifiedOperatorBuilder(Zone* zone); 723 SimplifiedOperatorBuilder(const SimplifiedOperatorBuilder&) = delete; 724 SimplifiedOperatorBuilder& operator=(const SimplifiedOperatorBuilder&) = 725 delete; 726 727 const Operator* BooleanNot(); 728 729 const Operator* NumberEqual(); 730 const Operator* NumberSameValue(); 731 const Operator* NumberLessThan(); 732 const Operator* NumberLessThanOrEqual(); 733 const Operator* NumberAdd(); 734 const Operator* NumberSubtract(); 735 const Operator* NumberMultiply(); 736 const Operator* NumberDivide(); 737 const Operator* NumberModulus(); 738 const Operator* NumberBitwiseOr(); 739 const Operator* NumberBitwiseXor(); 740 const Operator* NumberBitwiseAnd(); 741 const Operator* NumberShiftLeft(); 742 const Operator* NumberShiftRight(); 743 const Operator* NumberShiftRightLogical(); 744 const Operator* NumberImul(); 745 const Operator* NumberAbs(); 746 const Operator* NumberClz32(); 747 const Operator* NumberCeil(); 748 const Operator* NumberFloor(); 749 const Operator* NumberFround(); 750 const Operator* NumberAcos(); 751 const Operator* NumberAcosh(); 752 const Operator* NumberAsin(); 753 const Operator* NumberAsinh(); 754 const Operator* NumberAtan(); 755 const Operator* NumberAtan2(); 756 const Operator* NumberAtanh(); 757 const Operator* NumberCbrt(); 758 const Operator* NumberCos(); 759 const Operator* NumberCosh(); 760 const Operator* NumberExp(); 761 const Operator* NumberExpm1(); 762 const Operator* NumberLog(); 763 const Operator* NumberLog1p(); 764 const Operator* NumberLog10(); 765 const Operator* NumberLog2(); 766 const Operator* NumberMax(); 767 const Operator* NumberMin(); 768 const Operator* NumberPow(); 769 const Operator* NumberRound(); 770 const Operator* NumberSign(); 771 const Operator* NumberSin(); 772 const Operator* NumberSinh(); 773 const Operator* NumberSqrt(); 774 const Operator* NumberTan(); 775 const Operator* NumberTanh(); 776 const Operator* NumberTrunc(); 777 const Operator* NumberToBoolean(); 778 const Operator* NumberToInt32(); 779 const Operator* NumberToString(); 780 const Operator* NumberToUint32(); 781 const Operator* NumberToUint8Clamped(); 782 783 const Operator* NumberSilenceNaN(); 784 785 const Operator* BigIntAdd(); 786 const Operator* BigIntSubtract(); 787 const Operator* BigIntNegate(); 788 789 const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint); 790 const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint); 791 792 const Operator* SpeculativeNumberAdd(NumberOperationHint hint); 793 const Operator* SpeculativeNumberSubtract(NumberOperationHint hint); 794 const Operator* SpeculativeNumberMultiply(NumberOperationHint hint); 795 const Operator* SpeculativeNumberDivide(NumberOperationHint hint); 796 const Operator* SpeculativeNumberModulus(NumberOperationHint hint); 797 const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint); 798 const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint); 799 const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint); 800 const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint); 801 const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint); 802 const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint); 803 const Operator* SpeculativeNumberPow(NumberOperationHint hint); 804 805 const Operator* SpeculativeNumberLessThan(NumberOperationHint hint); 806 const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint); 807 const Operator* SpeculativeNumberEqual(NumberOperationHint hint); 808 809 const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint); 810 const Operator* SpeculativeBigIntSubtract(BigIntOperationHint hint); 811 const Operator* SpeculativeBigIntNegate(BigIntOperationHint hint); 812 const Operator* SpeculativeBigIntAsIntN(int bits, 813 const FeedbackSource& feedback); 814 const Operator* SpeculativeBigIntAsUintN(int bits, 815 const FeedbackSource& feedback); 816 817 const Operator* ReferenceEqual(); 818 const Operator* SameValue(); 819 const Operator* SameValueNumbersOnly(); 820 821 const Operator* TypeOf(); 822 823 const Operator* ToBoolean(); 824 825 const Operator* StringConcat(); 826 const Operator* StringEqual(); 827 const Operator* StringLessThan(); 828 const Operator* StringLessThanOrEqual(); 829 const Operator* StringCharCodeAt(); 830 const Operator* StringCodePointAt(); 831 const Operator* StringFromSingleCharCode(); 832 const Operator* StringFromSingleCodePoint(); 833 const Operator* StringFromCodePointAt(); 834 const Operator* StringIndexOf(); 835 const Operator* StringLength(); 836 const Operator* StringToLowerCaseIntl(); 837 const Operator* StringToUpperCaseIntl(); 838 const Operator* StringSubstring(); 839 840 const Operator* FindOrderedHashMapEntry(); 841 const Operator* FindOrderedHashMapEntryForInt32Key(); 842 843 const Operator* SpeculativeToNumber(NumberOperationHint hint, 844 const FeedbackSource& feedback); 845 846 const Operator* StringToNumber(); 847 const Operator* PlainPrimitiveToNumber(); 848 const Operator* PlainPrimitiveToWord32(); 849 const Operator* PlainPrimitiveToFloat64(); 850 851 const Operator* ChangeTaggedSignedToInt32(); 852 const Operator* ChangeTaggedSignedToInt64(); 853 const Operator* ChangeTaggedToInt32(); 854 const Operator* ChangeTaggedToInt64(); 855 const Operator* ChangeTaggedToUint32(); 856 const Operator* ChangeTaggedToFloat64(); 857 const Operator* ChangeTaggedToTaggedSigned(); 858 const Operator* ChangeInt31ToTaggedSigned(); 859 const Operator* ChangeInt32ToTagged(); 860 const Operator* ChangeInt64ToTagged(); 861 const Operator* ChangeUint32ToTagged(); 862 const Operator* ChangeUint64ToTagged(); 863 const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode); 864 const Operator* ChangeFloat64ToTaggedPointer(); 865 const Operator* ChangeTaggedToBit(); 866 const Operator* ChangeBitToTagged(); 867 const Operator* TruncateBigIntToWord64(); 868 const Operator* ChangeInt64ToBigInt(); 869 const Operator* ChangeUint64ToBigInt(); 870 const Operator* TruncateTaggedToWord32(); 871 const Operator* TruncateTaggedToFloat64(); 872 const Operator* TruncateTaggedToBit(); 873 const Operator* TruncateTaggedPointerToBit(); 874 875 const Operator* CompareMaps(ZoneHandleSet<Map>); 876 const Operator* MapGuard(ZoneHandleSet<Map> maps); 877 878 const Operator* CheckBounds(const FeedbackSource& feedback, 879 CheckBoundsFlags flags = {}); 880 const Operator* CheckedUint32Bounds(const FeedbackSource& feedback, 881 CheckBoundsFlags flags); 882 const Operator* CheckedUint64Bounds(const FeedbackSource& feedback, 883 CheckBoundsFlags flags); 884 885 const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell); 886 const Operator* CheckEqualsInternalizedString(); 887 const Operator* CheckEqualsSymbol(); 888 const Operator* CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const&); 889 const Operator* CheckHeapObject(); 890 const Operator* CheckIf(DeoptimizeReason deoptimize_reason, 891 const FeedbackSource& feedback = FeedbackSource()); 892 const Operator* CheckInternalizedString(); 893 const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>, 894 const FeedbackSource& = FeedbackSource()); 895 const Operator* CheckNotTaggedHole(); 896 const Operator* CheckNumber(const FeedbackSource& feedback); 897 const Operator* CheckReceiver(); 898 const Operator* CheckReceiverOrNullOrUndefined(); 899 const Operator* CheckSmi(const FeedbackSource& feedback); 900 const Operator* CheckString(const FeedbackSource& feedback); 901 const Operator* CheckSymbol(); 902 903 const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode, 904 const FeedbackSource& feedback); 905 const Operator* CheckedFloat64ToInt64(CheckForMinusZeroMode, 906 const FeedbackSource& feedback); 907 const Operator* CheckedInt32Add(); 908 const Operator* CheckedInt32Div(); 909 const Operator* CheckedInt32Mod(); 910 const Operator* CheckedInt32Mul(CheckForMinusZeroMode); 911 const Operator* CheckedInt32Sub(); 912 const Operator* CheckedInt32ToTaggedSigned(const FeedbackSource& feedback); 913 const Operator* CheckedInt64ToInt32(const FeedbackSource& feedback); 914 const Operator* CheckedInt64ToTaggedSigned(const FeedbackSource& feedback); 915 const Operator* CheckedTaggedSignedToInt32(const FeedbackSource& feedback); 916 const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode, 917 const FeedbackSource& feedback); 918 const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode, 919 const FeedbackSource& feedback); 920 const Operator* CheckedTaggedToArrayIndex(const FeedbackSource& feedback); 921 const Operator* CheckedTaggedToInt64(CheckForMinusZeroMode, 922 const FeedbackSource& feedback); 923 const Operator* CheckedTaggedToTaggedPointer(const FeedbackSource& feedback); 924 const Operator* CheckedTaggedToTaggedSigned(const FeedbackSource& feedback); 925 const Operator* CheckBigInt(const FeedbackSource& feedback); 926 const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode, 927 const FeedbackSource& feedback); 928 const Operator* CheckedUint32Div(); 929 const Operator* CheckedUint32Mod(); 930 const Operator* CheckedUint32ToInt32(const FeedbackSource& feedback); 931 const Operator* CheckedUint32ToTaggedSigned(const FeedbackSource& feedback); 932 const Operator* CheckedUint64ToInt32(const FeedbackSource& feedback); 933 const Operator* CheckedUint64ToTaggedSigned(const FeedbackSource& feedback); 934 935 const Operator* ConvertReceiver(ConvertReceiverMode); 936 937 const Operator* ConvertTaggedHoleToUndefined(); 938 939 const Operator* ObjectIsArrayBufferView(); 940 const Operator* ObjectIsBigInt(); 941 const Operator* ObjectIsCallable(); 942 const Operator* ObjectIsConstructor(); 943 const Operator* ObjectIsDetectableCallable(); 944 const Operator* ObjectIsMinusZero(); 945 const Operator* NumberIsMinusZero(); 946 const Operator* ObjectIsNaN(); 947 const Operator* NumberIsNaN(); 948 const Operator* ObjectIsNonCallable(); 949 const Operator* ObjectIsNumber(); 950 const Operator* ObjectIsReceiver(); 951 const Operator* ObjectIsSmi(); 952 const Operator* ObjectIsString(); 953 const Operator* ObjectIsSymbol(); 954 const Operator* ObjectIsUndetectable(); 955 956 const Operator* NumberIsFloat64Hole(); 957 const Operator* NumberIsFinite(); 958 const Operator* ObjectIsFiniteNumber(); 959 const Operator* NumberIsInteger(); 960 const Operator* ObjectIsSafeInteger(); 961 const Operator* NumberIsSafeInteger(); 962 const Operator* ObjectIsInteger(); 963 964 const Operator* ArgumentsLength(); 965 const Operator* RestLength(int formal_parameter_count); 966 967 const Operator* NewDoubleElements(AllocationType); 968 const Operator* NewSmiOrObjectElements(AllocationType); 969 970 // new-arguments-elements arguments-length 971 const Operator* NewArgumentsElements(CreateArgumentsType type, 972 int formal_parameter_count); 973 974 // new-cons-string length, first, second 975 const Operator* NewConsString(); 976 977 // ensure-writable-fast-elements object, elements 978 const Operator* EnsureWritableFastElements(); 979 980 // maybe-grow-fast-elements object, elements, index, length 981 const Operator* MaybeGrowFastElements(GrowFastElementsMode mode, 982 const FeedbackSource& feedback); 983 984 // transition-elements-kind object, from-map, to-map 985 const Operator* TransitionElementsKind(ElementsTransition transition); 986 987 const Operator* Allocate(Type type, 988 AllocationType allocation = AllocationType::kYoung); 989 const Operator* AllocateRaw( 990 Type type, AllocationType allocation = AllocationType::kYoung, 991 AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse); 992 993 const Operator* LoadMessage(); 994 const Operator* StoreMessage(); 995 996 const Operator* LoadFieldByIndex(); 997 const Operator* LoadField(FieldAccess const&); 998 const Operator* StoreField(FieldAccess const&, 999 bool maybe_initializing_or_transitioning = true); 1000 1001 // load-element [base + index] 1002 const Operator* LoadElement(ElementAccess const&); 1003 1004 // load-stack-argument [base + index] 1005 const Operator* LoadStackArgument(); 1006 1007 // store-element [base + index], value 1008 const Operator* StoreElement(ElementAccess const&); 1009 1010 // store-element [base + index], value, only with fast arrays. 1011 const Operator* TransitionAndStoreElement(Handle<Map> double_map, 1012 Handle<Map> fast_map); 1013 // store-element [base + index], smi value, only with fast arrays. 1014 const Operator* StoreSignedSmallElement(); 1015 1016 // store-element [base + index], double value, only with fast arrays. 1017 const Operator* TransitionAndStoreNumberElement(Handle<Map> double_map); 1018 1019 // store-element [base + index], object value, only with fast arrays. 1020 const Operator* TransitionAndStoreNonNumberElement(Handle<Map> fast_map, 1021 Type value_type); 1022 1023 // load-from-object [base + offset] 1024 // This operator comes in two flavors: LoadImmutableFromObject guarantees that 1025 // the underlying object field will be initialized at most once for the 1026 // duration of the program. This enables more optimizations in 1027 // CsaLoadElimination. 1028 // Note: LoadImmutableFromObject is unrelated to LoadImmutable and is lowered 1029 // into a regular Load. 1030 const Operator* LoadFromObject(ObjectAccess const&); 1031 const Operator* LoadImmutableFromObject(ObjectAccess const&); 1032 1033 // store-to-object [base + offset], value 1034 // This operator comes in two flavors: InitializeImmutableInObject guarantees 1035 // that the underlying object field has not and will not be initialized again 1036 // for the duration of the program. This enables more optimizations in 1037 // CsaLoadElimination. 1038 const Operator* StoreToObject(ObjectAccess const&); 1039 const Operator* InitializeImmutableInObject(ObjectAccess const&); 1040 1041 // load-typed-element buffer, [base + external + index] 1042 const Operator* LoadTypedElement(ExternalArrayType const&); 1043 1044 // load-data-view-element object, [base + index] 1045 const Operator* LoadDataViewElement(ExternalArrayType const&); 1046 1047 // store-typed-element buffer, [base + external + index], value 1048 const Operator* StoreTypedElement(ExternalArrayType const&); 1049 1050 // store-data-view-element object, [base + index], value 1051 const Operator* StoreDataViewElement(ExternalArrayType const&); 1052 1053 // Abort (for terminating execution on internal error). 1054 const Operator* RuntimeAbort(AbortReason reason); 1055 1056 // Abort if the value input does not inhabit the given type 1057 const Operator* AssertType(Type type); 1058 1059 // Abort if the value does not match the node's computed type after 1060 // SimplifiedLowering. 1061 const Operator* VerifyType(); 1062 1063 const Operator* DateNow(); 1064 1065 // Represents the inputs necessary to construct a fast and a slow API call. 1066 const Operator* FastApiCall( 1067 const FastApiCallFunctionVector& c_candidate_functions, 1068 FeedbackSource const& feedback, CallDescriptor* descriptor); 1069 1070 private: 1071 Zone* zone() const { return zone_; } 1072 1073 const SimplifiedOperatorGlobalCache& cache_; 1074 Zone* const zone_; 1075}; 1076 1077// Node wrappers. 1078 1079// TODO(jgruber): Consider merging with JSNodeWrapperBase. 1080class SimplifiedNodeWrapperBase : public NodeWrapper { 1081 public: 1082 explicit constexpr SimplifiedNodeWrapperBase(Node* node) 1083 : NodeWrapper(node) {} 1084 1085 // Valid iff this node has a context input. 1086 TNode<Object> context() const { 1087 // Could be a Context or NoContextConstant. 1088 return TNode<Object>::UncheckedCast( 1089 NodeProperties::GetContextInput(node())); 1090 } 1091 1092 // Valid iff this node has exactly one effect input. 1093 Effect effect() const { 1094 DCHECK_EQ(node()->op()->EffectInputCount(), 1); 1095 return Effect{NodeProperties::GetEffectInput(node())}; 1096 } 1097 1098 // Valid iff this node has exactly one control input. 1099 Control control() const { 1100 DCHECK_EQ(node()->op()->ControlInputCount(), 1); 1101 return Control{NodeProperties::GetControlInput(node())}; 1102 } 1103 1104 // Valid iff this node has a frame state input. 1105 FrameState frame_state() const { 1106 return FrameState{NodeProperties::GetFrameStateInput(node())}; 1107 } 1108}; 1109 1110#define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \ 1111 static constexpr int Name##Index() { return TheIndex; } \ 1112 TNode<Type> name() const { \ 1113 return TNode<Type>::UncheckedCast( \ 1114 NodeProperties::GetValueInput(node(), TheIndex)); \ 1115 } 1116 1117class FastApiCallNode final : public SimplifiedNodeWrapperBase { 1118 public: 1119 explicit constexpr FastApiCallNode(Node* node) 1120 : SimplifiedNodeWrapperBase(node) { 1121 DCHECK_EQ(IrOpcode::kFastApiCall, node->opcode()); 1122 } 1123 1124 const FastApiCallParameters& Parameters() const { 1125 return FastApiCallParametersOf(node()->op()); 1126 } 1127 1128#define INPUTS(V) V(Receiver, receiver, 0, Object) 1129 INPUTS(DEFINE_INPUT_ACCESSORS) 1130#undef INPUTS 1131 1132 // Besides actual arguments, FastApiCall nodes also take: 1133 static constexpr int kSlowTargetInputCount = 1; 1134 static constexpr int kFastReceiverInputCount = 1; 1135 static constexpr int kSlowReceiverInputCount = 1; 1136 static constexpr int kExtraInputCount = kFastReceiverInputCount; 1137 1138 static constexpr int kArityInputCount = 1; 1139 static constexpr int kNewTargetInputCount = 1; 1140 static constexpr int kHolderInputCount = 1; 1141 static constexpr int kContextAndFrameStateInputCount = 2; 1142 static constexpr int kEffectAndControlInputCount = 2; 1143 int FastCallExtraInputCount() const; 1144 static constexpr int kSlowCallExtraInputCount = 1145 kSlowTargetInputCount + kArityInputCount + kNewTargetInputCount + 1146 kSlowReceiverInputCount + kHolderInputCount + 1147 kContextAndFrameStateInputCount + kEffectAndControlInputCount; 1148 1149 static constexpr int kSlowCallDataArgumentIndex = 3; 1150 1151 // This is the arity fed into FastApiCallArguments. 1152 static constexpr int ArityForArgc(int c_arg_count, int js_arg_count) { 1153 return c_arg_count + js_arg_count + kEffectAndControlInputCount; 1154 } 1155 1156 int FastCallArgumentCount() const; 1157 int SlowCallArgumentCount() const; 1158 1159 constexpr int FirstFastCallArgumentIndex() const { 1160 return ReceiverIndex() + 1; 1161 } 1162 constexpr int FastCallArgumentIndex(int i) const { 1163 return FirstFastCallArgumentIndex() + i; 1164 } 1165 TNode<Object> FastCallArgument(int i) const { 1166 DCHECK_LT(i, FastCallArgumentCount()); 1167 return TNode<Object>::UncheckedCast( 1168 NodeProperties::GetValueInput(node(), FastCallArgumentIndex(i))); 1169 } 1170 1171 int FirstSlowCallArgumentIndex() const { return FastCallArgumentCount(); } 1172 int SlowCallArgumentIndex(int i) const { 1173 return FirstSlowCallArgumentIndex() + i; 1174 } 1175 TNode<Object> SlowCallArgument(int i) const { 1176 DCHECK_LT(i, SlowCallArgumentCount()); 1177 return TNode<Object>::UncheckedCast( 1178 NodeProperties::GetValueInput(node(), SlowCallArgumentIndex(i))); 1179 } 1180}; 1181 1182#undef DEFINE_INPUT_ACCESSORS 1183 1184} // namespace compiler 1185} // namespace internal 1186} // namespace v8 1187 1188#endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ 1189