| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
| #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
| |
| #include <iosfwd> |
| |
| #include "src/base/compiler-specific.h" |
| #include "src/codegen/machine-type.h" |
| #include "src/codegen/tnode.h" |
| #include "src/common/globals.h" |
| #include "src/compiler/feedback-source.h" |
| #include "src/compiler/node-properties.h" |
| #include "src/compiler/operator.h" |
| #include "src/compiler/types.h" |
| #include "src/compiler/write-barrier-kind.h" |
| #include "src/deoptimizer/deoptimize-reason.h" |
| #include "src/handles/handles.h" |
| #include "src/handles/maybe-handles.h" |
| #include "src/objects/objects.h" |
| #include "src/objects/type-hints.h" |
| #include "src/zone/zone-handle-set.h" |
| |
| namespace v8 { |
| class CFunctionInfo; |
| |
| namespace internal { |
| |
| // Forward declarations. |
| enum class AbortReason : uint8_t; |
| class Zone; |
| |
| namespace compiler { |
| |
| // Forward declarations. |
| class Operator; |
| struct SimplifiedOperatorGlobalCache; |
| class CallDescriptor; |
| |
| enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase }; |
| |
| size_t hash_value(BaseTaggedness); |
| |
| std::ostream& operator<<(std::ostream&, BaseTaggedness); |
| |
| size_t hash_value(LoadSensitivity); |
| |
| std::ostream& operator<<(std::ostream&, LoadSensitivity); |
| |
| struct ConstFieldInfo { |
| // the map that introduced the const field, if any. An access is considered |
| // mutable iff the handle is null. |
| MaybeHandle<Map> owner_map; |
| |
| ConstFieldInfo() : owner_map(MaybeHandle<Map>()) {} |
| explicit ConstFieldInfo(Handle<Map> owner_map) : owner_map(owner_map) {} |
| |
| bool IsConst() const { return !owner_map.is_null(); } |
| |
| // No const field owner, i.e., a mutable field |
| static ConstFieldInfo None() { return ConstFieldInfo(); } |
| }; |
| |
| V8_EXPORT_PRIVATE bool operator==(ConstFieldInfo const&, ConstFieldInfo const&); |
| |
| size_t hash_value(ConstFieldInfo const&); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, |
| ConstFieldInfo const&); |
| |
| // An access descriptor for loads/stores of fixed structures like field |
| // accesses of heap objects. Accesses from either tagged or untagged base |
| // pointers are supported; untagging is done automatically during lowering. |
| struct FieldAccess { |
| BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. |
| int offset; // offset of the field, without tag. |
| MaybeHandle<Name> name; // debugging only. |
| MaybeHandle<Map> map; // map of the field value (if known). |
| Type type; // type of the field. |
| MachineType machine_type; // machine type of the field. |
| WriteBarrierKind write_barrier_kind; // write barrier hint. |
| LoadSensitivity load_sensitivity; // load safety for poisoning. |
| ConstFieldInfo const_field_info; // the constness of this access, and the |
| // field owner map, if the access is const |
| bool is_store_in_literal; // originates from a kStoreInLiteral access |
| #ifdef V8_HEAP_SANDBOX |
| ExternalPointerTag external_pointer_tag = kExternalPointerNullTag; |
| #endif |
| |
| FieldAccess() |
| : base_is_tagged(kTaggedBase), |
| offset(0), |
| type(Type::None()), |
| machine_type(MachineType::None()), |
| write_barrier_kind(kFullWriteBarrier), |
| load_sensitivity(LoadSensitivity::kUnsafe), |
| const_field_info(ConstFieldInfo::None()), |
| is_store_in_literal(false) {} |
| |
| FieldAccess(BaseTaggedness base_is_tagged, int offset, MaybeHandle<Name> name, |
| MaybeHandle<Map> map, Type type, MachineType machine_type, |
| WriteBarrierKind write_barrier_kind, |
| LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe, |
| ConstFieldInfo const_field_info = ConstFieldInfo::None(), |
| bool is_store_in_literal = false |
| #ifdef V8_HEAP_SANDBOX |
| , |
| ExternalPointerTag external_pointer_tag = kExternalPointerNullTag |
| #endif |
| ) |
| : base_is_tagged(base_is_tagged), |
| offset(offset), |
| name(name), |
| map(map), |
| type(type), |
| machine_type(machine_type), |
| write_barrier_kind(write_barrier_kind), |
| load_sensitivity(load_sensitivity), |
| const_field_info(const_field_info), |
| is_store_in_literal(is_store_in_literal) |
| #ifdef V8_HEAP_SANDBOX |
| , |
| external_pointer_tag(external_pointer_tag) |
| #endif |
| { |
| DCHECK_GE(offset, 0); |
| } |
| |
| int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } |
| }; |
| |
| V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&); |
| |
| size_t hash_value(FieldAccess const&); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&); |
| |
| V8_EXPORT_PRIVATE FieldAccess const& FieldAccessOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| template <> |
| void Operator1<FieldAccess>::PrintParameter(std::ostream& os, |
| PrintVerbosity verbose) const; |
| |
| // An access descriptor for loads/stores of indexed structures like characters |
| // in strings or off-heap backing stores. Accesses from either tagged or |
| // untagged base pointers are supported; untagging is done automatically during |
| // lowering. |
| struct ElementAccess { |
| BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. |
| int header_size; // size of the header, without tag. |
| Type type; // type of the element. |
| MachineType machine_type; // machine type of the element. |
| WriteBarrierKind write_barrier_kind; // write barrier hint. |
| LoadSensitivity load_sensitivity; // load safety for poisoning. |
| |
| ElementAccess() |
| : base_is_tagged(kTaggedBase), |
| header_size(0), |
| type(Type::None()), |
| machine_type(MachineType::None()), |
| write_barrier_kind(kFullWriteBarrier), |
| load_sensitivity(LoadSensitivity::kUnsafe) {} |
| |
| ElementAccess(BaseTaggedness base_is_tagged, int header_size, Type type, |
| MachineType machine_type, WriteBarrierKind write_barrier_kind, |
| LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe) |
| : base_is_tagged(base_is_tagged), |
| header_size(header_size), |
| type(type), |
| machine_type(machine_type), |
| write_barrier_kind(write_barrier_kind), |
| load_sensitivity(load_sensitivity) {} |
| |
| int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } |
| }; |
| |
| V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&); |
| |
| size_t hash_value(ElementAccess const&); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&); |
| |
| V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| ExternalArrayType ExternalArrayTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| // An access descriptor for loads/stores of CSA-accessible structures. |
| struct ObjectAccess { |
| MachineType machine_type; // machine type of the field. |
| WriteBarrierKind write_barrier_kind; // write barrier hint. |
| |
| ObjectAccess() |
| : machine_type(MachineType::None()), |
| write_barrier_kind(kFullWriteBarrier) {} |
| |
| ObjectAccess(MachineType machine_type, WriteBarrierKind write_barrier_kind) |
| : machine_type(machine_type), write_barrier_kind(write_barrier_kind) {} |
| |
| int tag() const { return kHeapObjectTag; } |
| }; |
| |
| V8_EXPORT_PRIVATE bool operator==(ObjectAccess const&, ObjectAccess const&); |
| |
| size_t hash_value(ObjectAccess const&); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ObjectAccess const&); |
| |
| V8_EXPORT_PRIVATE ObjectAccess const& ObjectAccessOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| // The ConvertReceiverMode is used as parameter by ConvertReceiver operators. |
| ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| // A the parameters for several Check nodes. The {feedback} parameter is |
| // optional. If {feedback} references a valid CallIC slot and this MapCheck |
| // fails, then speculation on that CallIC slot will be disabled. |
| class CheckParameters final { |
| public: |
| explicit CheckParameters(const FeedbackSource& feedback) |
| : feedback_(feedback) {} |
| |
| FeedbackSource const& feedback() const { return feedback_; } |
| |
| private: |
| FeedbackSource feedback_; |
| }; |
| |
| bool operator==(CheckParameters const&, CheckParameters const&); |
| |
| size_t hash_value(CheckParameters const&); |
| |
| std::ostream& operator<<(std::ostream&, CheckParameters const&); |
| |
| CheckParameters const& CheckParametersOf(Operator const*) V8_WARN_UNUSED_RESULT; |
| |
| enum class CheckBoundsFlag : uint8_t { |
| kConvertStringAndMinusZero = 1 << 0, // instead of deopting on such inputs |
| kAbortOnOutOfBounds = 1 << 1, // instead of deopting if input is OOB |
| }; |
| using CheckBoundsFlags = base::Flags<CheckBoundsFlag>; |
| DEFINE_OPERATORS_FOR_FLAGS(CheckBoundsFlags) |
| |
| class CheckBoundsParameters final { |
| public: |
| CheckBoundsParameters(const FeedbackSource& feedback, CheckBoundsFlags flags) |
| : check_parameters_(feedback), flags_(flags) {} |
| |
| CheckBoundsFlags flags() const { return flags_; } |
| const CheckParameters& check_parameters() const { return check_parameters_; } |
| |
| private: |
| CheckParameters check_parameters_; |
| CheckBoundsFlags flags_; |
| }; |
| |
| bool operator==(CheckBoundsParameters const&, CheckBoundsParameters const&); |
| |
| size_t hash_value(CheckBoundsParameters const&); |
| |
| std::ostream& operator<<(std::ostream&, CheckBoundsParameters const&); |
| |
| CheckBoundsParameters const& CheckBoundsParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| class CheckIfParameters final { |
| public: |
| explicit CheckIfParameters(DeoptimizeReason reason, |
| const FeedbackSource& feedback) |
| : reason_(reason), feedback_(feedback) {} |
| |
| FeedbackSource const& feedback() const { return feedback_; } |
| DeoptimizeReason reason() const { return reason_; } |
| |
| private: |
| DeoptimizeReason reason_; |
| FeedbackSource feedback_; |
| }; |
| |
| bool operator==(CheckIfParameters const&, CheckIfParameters const&); |
| |
| size_t hash_value(CheckIfParameters const&); |
| |
| std::ostream& operator<<(std::ostream&, CheckIfParameters const&); |
| |
| CheckIfParameters const& CheckIfParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| enum class CheckFloat64HoleMode : uint8_t { |
| kNeverReturnHole, // Never return the hole (deoptimize instead). |
| kAllowReturnHole // Allow to return the hole (signaling NaN). |
| }; |
| |
| size_t hash_value(CheckFloat64HoleMode); |
| |
| std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode); |
| |
| class CheckFloat64HoleParameters { |
| public: |
| CheckFloat64HoleParameters(CheckFloat64HoleMode mode, |
| FeedbackSource const& feedback) |
| : mode_(mode), feedback_(feedback) {} |
| |
| CheckFloat64HoleMode mode() const { return mode_; } |
| FeedbackSource const& feedback() const { return feedback_; } |
| |
| private: |
| CheckFloat64HoleMode mode_; |
| FeedbackSource feedback_; |
| }; |
| |
| CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| std::ostream& operator<<(std::ostream&, CheckFloat64HoleParameters const&); |
| |
| size_t hash_value(CheckFloat64HoleParameters const&); |
| |
| bool operator==(CheckFloat64HoleParameters const&, |
| CheckFloat64HoleParameters const&); |
| bool operator!=(CheckFloat64HoleParameters const&, |
| CheckFloat64HoleParameters const&); |
| |
| // Parameter for CheckClosure node. |
| Handle<FeedbackCell> FeedbackCellOf(const Operator* op); |
| |
| enum class CheckTaggedInputMode : uint8_t { |
| kNumber, |
| kNumberOrBoolean, |
| kNumberOrOddball, |
| }; |
| |
| size_t hash_value(CheckTaggedInputMode); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, CheckTaggedInputMode); |
| |
| class CheckTaggedInputParameters { |
| public: |
| CheckTaggedInputParameters(CheckTaggedInputMode mode, |
| const FeedbackSource& feedback) |
| : mode_(mode), feedback_(feedback) {} |
| |
| CheckTaggedInputMode mode() const { return mode_; } |
| const FeedbackSource& feedback() const { return feedback_; } |
| |
| private: |
| CheckTaggedInputMode mode_; |
| FeedbackSource feedback_; |
| }; |
| |
| const CheckTaggedInputParameters& CheckTaggedInputParametersOf(const Operator*) |
| V8_WARN_UNUSED_RESULT; |
| |
| std::ostream& operator<<(std::ostream&, |
| const CheckTaggedInputParameters& params); |
| |
| size_t hash_value(const CheckTaggedInputParameters& params); |
| |
| bool operator==(CheckTaggedInputParameters const&, |
| CheckTaggedInputParameters const&); |
| |
| enum class CheckForMinusZeroMode : uint8_t { |
| kCheckForMinusZero, |
| kDontCheckForMinusZero, |
| }; |
| |
| size_t hash_value(CheckForMinusZeroMode); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, |
| CheckForMinusZeroMode); |
| |
| CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) |
| V8_WARN_UNUSED_RESULT; |
| |
| class CheckMinusZeroParameters { |
| public: |
| CheckMinusZeroParameters(CheckForMinusZeroMode mode, |
| const FeedbackSource& feedback) |
| : mode_(mode), feedback_(feedback) {} |
| |
| CheckForMinusZeroMode mode() const { return mode_; } |
| const FeedbackSource& feedback() const { return feedback_; } |
| |
| private: |
| CheckForMinusZeroMode mode_; |
| FeedbackSource feedback_; |
| }; |
| |
| V8_EXPORT_PRIVATE const CheckMinusZeroParameters& CheckMinusZeroParametersOf( |
| const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<( |
| std::ostream&, const CheckMinusZeroParameters& params); |
| |
| size_t hash_value(const CheckMinusZeroParameters& params); |
| |
| bool operator==(CheckMinusZeroParameters const&, |
| CheckMinusZeroParameters const&); |
| |
| enum class CheckMapsFlag : uint8_t { |
| kNone = 0u, |
| kTryMigrateInstance = 1u << 0, |
| }; |
| using CheckMapsFlags = base::Flags<CheckMapsFlag>; |
| |
| DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags) |
| |
| std::ostream& operator<<(std::ostream&, CheckMapsFlags); |
| |
| // A descriptor for map checks. The {feedback} parameter is optional. |
| // If {feedback} references a valid CallIC slot and this MapCheck fails, |
| // then speculation on that CallIC slot will be disabled. |
| class CheckMapsParameters final { |
| public: |
| CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps, |
| const FeedbackSource& feedback) |
| : flags_(flags), maps_(maps), feedback_(feedback) {} |
| |
| CheckMapsFlags flags() const { return flags_; } |
| ZoneHandleSet<Map> const& maps() const { return maps_; } |
| FeedbackSource const& feedback() const { return feedback_; } |
| |
| private: |
| CheckMapsFlags const flags_; |
| ZoneHandleSet<Map> const maps_; |
| FeedbackSource const feedback_; |
| }; |
| |
| bool operator==(CheckMapsParameters const&, CheckMapsParameters const&); |
| |
| size_t hash_value(CheckMapsParameters const&); |
| |
| std::ostream& operator<<(std::ostream&, CheckMapsParameters const&); |
| |
| CheckMapsParameters const& CheckMapsParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| // A descriptor for dynamic map checks. |
| class DynamicCheckMapsParameters final { |
| public: |
| enum ICState { kMonomorphic, kPolymorphic }; |
| |
| DynamicCheckMapsParameters(CheckMapsFlags flags, Handle<Object> handler, |
| ZoneHandleSet<Map> const& maps, |
| const FeedbackSource& feedback) |
| : flags_(flags), handler_(handler), maps_(maps), feedback_(feedback) {} |
| |
| CheckMapsFlags flags() const { return flags_; } |
| Handle<Object> handler() const { return handler_; } |
| ZoneHandleSet<Map> const& maps() const { return maps_; } |
| FeedbackSource const& feedback() const { return feedback_; } |
| ICState state() const { |
| return maps_.size() == 1 ? ICState::kMonomorphic : ICState::kPolymorphic; |
| } |
| |
| private: |
| CheckMapsFlags const flags_; |
| Handle<Object> const handler_; |
| ZoneHandleSet<Map> const maps_; |
| FeedbackSource const feedback_; |
| }; |
| |
| bool operator==(DynamicCheckMapsParameters const&, |
| DynamicCheckMapsParameters const&); |
| |
| size_t hash_value(DynamicCheckMapsParameters const&); |
| |
| std::ostream& operator<<(std::ostream&, DynamicCheckMapsParameters const&); |
| |
| DynamicCheckMapsParameters const& DynamicCheckMapsParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const*) V8_WARN_UNUSED_RESULT; |
| |
| // Parameters for CompareMaps operator. |
| ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const*) |
| V8_WARN_UNUSED_RESULT; |
| |
| // A descriptor for growing elements backing stores. |
| enum class GrowFastElementsMode : uint8_t { |
| kDoubleElements, |
| kSmiOrObjectElements |
| }; |
| |
| inline size_t hash_value(GrowFastElementsMode mode) { |
| return static_cast<uint8_t>(mode); |
| } |
| |
| std::ostream& operator<<(std::ostream&, GrowFastElementsMode); |
| |
| class GrowFastElementsParameters { |
| public: |
| GrowFastElementsParameters(GrowFastElementsMode mode, |
| const FeedbackSource& feedback) |
| : mode_(mode), feedback_(feedback) {} |
| |
| GrowFastElementsMode mode() const { return mode_; } |
| const FeedbackSource& feedback() const { return feedback_; } |
| |
| private: |
| GrowFastElementsMode mode_; |
| FeedbackSource feedback_; |
| }; |
| |
| bool operator==(const GrowFastElementsParameters&, |
| const GrowFastElementsParameters&); |
| |
| inline size_t hash_value(const GrowFastElementsParameters&); |
| |
| std::ostream& operator<<(std::ostream&, const GrowFastElementsParameters&); |
| |
| const GrowFastElementsParameters& GrowFastElementsParametersOf(const Operator*) |
| V8_WARN_UNUSED_RESULT; |
| |
| // A descriptor for elements kind transitions. |
| class ElementsTransition final { |
| public: |
| enum Mode : uint8_t { |
| kFastTransition, // simple transition, just updating the map. |
| kSlowTransition // full transition, round-trip to the runtime. |
| }; |
| |
| ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target) |
| : mode_(mode), source_(source), target_(target) {} |
| |
| Mode mode() const { return mode_; } |
| Handle<Map> source() const { return source_; } |
| Handle<Map> target() const { return target_; } |
| |
| private: |
| Mode const mode_; |
| Handle<Map> const source_; |
| Handle<Map> const target_; |
| }; |
| |
| bool operator==(ElementsTransition const&, ElementsTransition const&); |
| |
| size_t hash_value(ElementsTransition); |
| |
| std::ostream& operator<<(std::ostream&, ElementsTransition); |
| |
| ElementsTransition const& ElementsTransitionOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| // Parameters for TransitionAndStoreElement, or |
| // TransitionAndStoreNonNumberElement, or |
| // TransitionAndStoreNumberElement. |
| Handle<Map> DoubleMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| Handle<Map> FastMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| // Parameters for TransitionAndStoreNonNumberElement. |
| Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| // A hint for speculative number operations. |
| enum class NumberOperationHint : uint8_t { |
| kSignedSmall, // Inputs were Smi, output was in Smi. |
| kSignedSmallInputs, // Inputs were Smi, output was Number. |
| kSigned32, // Inputs were Signed32, output was Number. |
| kNumber, // Inputs were Number, output was Number. |
| kNumberOrBoolean, // Inputs were Number or Boolean, output was Number. |
| kNumberOrOddball, // Inputs were Number or Oddball, output was Number. |
| }; |
| |
| enum class BigIntOperationHint : uint8_t { |
| kBigInt, |
| }; |
| |
| size_t hash_value(NumberOperationHint); |
| size_t hash_value(BigIntOperationHint); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint); |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint); |
| V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| class NumberOperationParameters { |
| public: |
| NumberOperationParameters(NumberOperationHint hint, |
| const FeedbackSource& feedback) |
| : hint_(hint), feedback_(feedback) {} |
| |
| NumberOperationHint hint() const { return hint_; } |
| const FeedbackSource& feedback() const { return feedback_; } |
| |
| private: |
| NumberOperationHint hint_; |
| FeedbackSource feedback_; |
| }; |
| |
| size_t hash_value(NumberOperationParameters const&); |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, |
| const NumberOperationParameters&); |
| bool operator==(NumberOperationParameters const&, |
| NumberOperationParameters const&); |
| const NumberOperationParameters& NumberOperationParametersOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| int FormalParameterCountOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| class AllocateParameters { |
| public: |
| AllocateParameters( |
| Type type, AllocationType allocation_type, |
| AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse) |
| : type_(type), |
| allocation_type_(allocation_type), |
| allow_large_objects_(allow_large_objects) {} |
| |
| Type type() const { return type_; } |
| AllocationType allocation_type() const { return allocation_type_; } |
| AllowLargeObjects allow_large_objects() const { return allow_large_objects_; } |
| |
| private: |
| Type type_; |
| AllocationType allocation_type_; |
| AllowLargeObjects allow_large_objects_; |
| }; |
| |
| bool IsCheckedWithFeedback(const Operator* op); |
| |
| size_t hash_value(AllocateParameters); |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters); |
| |
| bool operator==(AllocateParameters const&, AllocateParameters const&); |
| |
| const AllocateParameters& AllocateParametersOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| AllocationType AllocationTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| Type AllocateTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| UnicodeEncoding UnicodeEncodingOf(const Operator*) V8_WARN_UNUSED_RESULT; |
| |
| AbortReason AbortReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| DeoptimizeReason DeoptimizeReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT; |
| |
| class NewArgumentsElementsParameters { |
| public: |
| NewArgumentsElementsParameters(CreateArgumentsType type, |
| int formal_parameter_count) |
| : type_(type), formal_parameter_count_(formal_parameter_count) {} |
| |
| CreateArgumentsType arguments_type() const { return type_; } |
| int formal_parameter_count() const { return formal_parameter_count_; } |
| |
| private: |
| CreateArgumentsType type_; |
| int formal_parameter_count_; |
| }; |
| |
| bool operator==(const NewArgumentsElementsParameters&, |
| const NewArgumentsElementsParameters&); |
| |
| inline size_t hash_value(const NewArgumentsElementsParameters&); |
| |
| std::ostream& operator<<(std::ostream&, const NewArgumentsElementsParameters&); |
| |
| const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf( |
| const Operator*) V8_WARN_UNUSED_RESULT; |
| |
| class FastApiCallParameters { |
| public: |
| explicit FastApiCallParameters(const CFunctionInfo* signature, |
| FeedbackSource const& feedback, |
| CallDescriptor* descriptor) |
| : signature_(signature), feedback_(feedback), descriptor_(descriptor) {} |
| |
| const CFunctionInfo* signature() const { return signature_; } |
| FeedbackSource const& feedback() const { return feedback_; } |
| CallDescriptor* descriptor() const { return descriptor_; } |
| |
| private: |
| const CFunctionInfo* signature_; |
| const FeedbackSource feedback_; |
| CallDescriptor* descriptor_; |
| }; |
| |
| FastApiCallParameters const& FastApiCallParametersOf(const Operator* op) |
| V8_WARN_UNUSED_RESULT; |
| |
| V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, |
| FastApiCallParameters const&); |
| |
| size_t hash_value(FastApiCallParameters const&); |
| |
| bool operator==(FastApiCallParameters const&, FastApiCallParameters const&); |
| |
| // Interface for building simplified operators, which represent the |
| // medium-level operations of V8, including adding numbers, allocating objects, |
| // indexing into objects and arrays, etc. |
| // All operators are typed but many are representation independent. |
| |
| // Number values from JS can be in one of these representations: |
| // - Tagged: word-sized integer that is either |
| // - a signed small integer (31 or 32 bits plus a tag) |
| // - a tagged pointer to a HeapNumber object that has a float64 field |
| // - Int32: an untagged signed 32-bit integer |
| // - Uint32: an untagged unsigned 32-bit integer |
| // - Float64: an untagged float64 |
| |
| // Additional representations for intermediate code or non-JS code: |
| // - Int64: an untagged signed 64-bit integer |
| // - Uint64: an untagged unsigned 64-bit integer |
| // - Float32: an untagged float32 |
| |
| // Boolean values can be: |
| // - Bool: a tagged pointer to either the canonical JS #false or |
| // the canonical JS #true object |
| // - Bit: an untagged integer 0 or 1, but word-sized |
| class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final |
| : public NON_EXPORTED_BASE(ZoneObject) { |
| public: |
| explicit SimplifiedOperatorBuilder(Zone* zone); |
| SimplifiedOperatorBuilder(const SimplifiedOperatorBuilder&) = delete; |
| SimplifiedOperatorBuilder& operator=(const SimplifiedOperatorBuilder&) = |
| delete; |
| |
| const Operator* BooleanNot(); |
| |
| const Operator* NumberEqual(); |
| const Operator* NumberSameValue(); |
| const Operator* NumberLessThan(); |
| const Operator* NumberLessThanOrEqual(); |
| const Operator* NumberAdd(); |
| const Operator* NumberSubtract(); |
| const Operator* NumberMultiply(); |
| const Operator* NumberDivide(); |
| const Operator* NumberModulus(); |
| const Operator* NumberBitwiseOr(); |
| const Operator* NumberBitwiseXor(); |
| const Operator* NumberBitwiseAnd(); |
| const Operator* NumberShiftLeft(); |
| const Operator* NumberShiftRight(); |
| const Operator* NumberShiftRightLogical(); |
| const Operator* NumberImul(); |
| const Operator* NumberAbs(); |
| const Operator* NumberClz32(); |
| const Operator* NumberCeil(); |
| const Operator* NumberFloor(); |
| const Operator* NumberFround(); |
| const Operator* NumberAcos(); |
| const Operator* NumberAcosh(); |
| const Operator* NumberAsin(); |
| const Operator* NumberAsinh(); |
| const Operator* NumberAtan(); |
| const Operator* NumberAtan2(); |
| const Operator* NumberAtanh(); |
| const Operator* NumberCbrt(); |
| const Operator* NumberCos(); |
| const Operator* NumberCosh(); |
| const Operator* NumberExp(); |
| const Operator* NumberExpm1(); |
| const Operator* NumberLog(); |
| const Operator* NumberLog1p(); |
| const Operator* NumberLog10(); |
| const Operator* NumberLog2(); |
| const Operator* NumberMax(); |
| const Operator* NumberMin(); |
| const Operator* NumberPow(); |
| const Operator* NumberRound(); |
| const Operator* NumberSign(); |
| const Operator* NumberSin(); |
| const Operator* NumberSinh(); |
| const Operator* NumberSqrt(); |
| const Operator* NumberTan(); |
| const Operator* NumberTanh(); |
| const Operator* NumberTrunc(); |
| const Operator* NumberToBoolean(); |
| const Operator* NumberToInt32(); |
| const Operator* NumberToString(); |
| const Operator* NumberToUint32(); |
| const Operator* NumberToUint8Clamped(); |
| |
| const Operator* NumberSilenceNaN(); |
| |
| const Operator* BigIntAdd(); |
| const Operator* BigIntSubtract(); |
| const Operator* BigIntNegate(); |
| |
| const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint); |
| const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint); |
| |
| const Operator* SpeculativeNumberAdd(NumberOperationHint hint); |
| const Operator* SpeculativeNumberSubtract(NumberOperationHint hint); |
| const Operator* SpeculativeNumberMultiply(NumberOperationHint hint); |
| const Operator* SpeculativeNumberDivide(NumberOperationHint hint); |
| const Operator* SpeculativeNumberModulus(NumberOperationHint hint); |
| const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint); |
| const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint); |
| const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint); |
| const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint); |
| const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint); |
| const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint); |
| |
| const Operator* SpeculativeNumberLessThan(NumberOperationHint hint); |
| const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint); |
| const Operator* SpeculativeNumberEqual(NumberOperationHint hint); |
| |
| const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint); |
| const Operator* SpeculativeBigIntSubtract(BigIntOperationHint hint); |
| const Operator* SpeculativeBigIntNegate(BigIntOperationHint hint); |
| const Operator* BigIntAsUintN(int bits); |
| |
| const Operator* ReferenceEqual(); |
| const Operator* SameValue(); |
| const Operator* SameValueNumbersOnly(); |
| |
| const Operator* TypeOf(); |
| |
| // Adds the given delta to the current feedback vector's interrupt budget, |
| // and calls the runtime profiler in case the budget is exhausted. A note on |
| // the delta parameter: the interrupt budget mechanism originates in the |
| // interpreter and thus still refers to 'bytecodes' even though we are |
| // generating native code. The interrupt budget essentially corresponds to |
| // the number of bytecodes we can execute before calling the profiler. The |
| // delta parameter represents the executed bytecodes since the last update. |
| const Operator* UpdateInterruptBudget(int delta); |
| |
| // Takes the current feedback vector as input 0, and generates a check of the |
| // vector's marker. Depending on the marker's value, we either do nothing, |
| // trigger optimized compilation, or install a finished code object. |
| const Operator* TierUpCheck(); |
| |
| const Operator* ToBoolean(); |
| |
| const Operator* StringConcat(); |
| const Operator* StringEqual(); |
| const Operator* StringLessThan(); |
| const Operator* StringLessThanOrEqual(); |
| const Operator* StringCharCodeAt(); |
| const Operator* StringCodePointAt(); |
| const Operator* StringFromSingleCharCode(); |
| const Operator* StringFromSingleCodePoint(); |
| const Operator* StringFromCodePointAt(); |
| const Operator* StringIndexOf(); |
| const Operator* StringLength(); |
| const Operator* StringToLowerCaseIntl(); |
| const Operator* StringToUpperCaseIntl(); |
| const Operator* StringSubstring(); |
| |
| const Operator* FindOrderedHashMapEntry(); |
| const Operator* FindOrderedHashMapEntryForInt32Key(); |
| |
| const Operator* SpeculativeToNumber(NumberOperationHint hint, |
| const FeedbackSource& feedback); |
| |
| const Operator* StringToNumber(); |
| const Operator* PlainPrimitiveToNumber(); |
| const Operator* PlainPrimitiveToWord32(); |
| const Operator* PlainPrimitiveToFloat64(); |
| |
| const Operator* ChangeTaggedSignedToInt32(); |
| const Operator* ChangeTaggedSignedToInt64(); |
| const Operator* ChangeTaggedToInt32(); |
| const Operator* ChangeTaggedToInt64(); |
| const Operator* ChangeTaggedToUint32(); |
| const Operator* ChangeTaggedToFloat64(); |
| const Operator* ChangeTaggedToTaggedSigned(); |
| const Operator* ChangeInt31ToTaggedSigned(); |
| const Operator* ChangeInt32ToTagged(); |
| const Operator* ChangeInt64ToTagged(); |
| const Operator* ChangeUint32ToTagged(); |
| const Operator* ChangeUint64ToTagged(); |
| const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode); |
| const Operator* ChangeFloat64ToTaggedPointer(); |
| const Operator* ChangeTaggedToBit(); |
| const Operator* ChangeBitToTagged(); |
| const Operator* TruncateBigIntToUint64(); |
| const Operator* ChangeUint64ToBigInt(); |
| const Operator* TruncateTaggedToWord32(); |
| const Operator* TruncateTaggedToFloat64(); |
| const Operator* TruncateTaggedToBit(); |
| const Operator* TruncateTaggedPointerToBit(); |
| |
| const Operator* PoisonIndex(); |
| const Operator* CompareMaps(ZoneHandleSet<Map>); |
| const Operator* MapGuard(ZoneHandleSet<Map> maps); |
| |
| const Operator* CheckBounds(const FeedbackSource& feedback, |
| CheckBoundsFlags flags = {}); |
| const Operator* CheckedUint32Bounds(const FeedbackSource& feedback, |
| CheckBoundsFlags flags); |
| const Operator* CheckedUint64Bounds(const FeedbackSource& feedback, |
| CheckBoundsFlags flags); |
| |
| const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell); |
| const Operator* CheckEqualsInternalizedString(); |
| const Operator* CheckEqualsSymbol(); |
| const Operator* CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const&); |
| const Operator* CheckHeapObject(); |
| const Operator* CheckIf(DeoptimizeReason deoptimize_reason, |
| const FeedbackSource& feedback = FeedbackSource()); |
| const Operator* CheckInternalizedString(); |
| const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>, |
| const FeedbackSource& = FeedbackSource()); |
| const Operator* DynamicCheckMaps(CheckMapsFlags flags, Handle<Object> handler, |
| ZoneHandleSet<Map> const& maps, |
| const FeedbackSource& feedback); |
| const Operator* CheckNotTaggedHole(); |
| const Operator* CheckNumber(const FeedbackSource& feedback); |
| const Operator* CheckReceiver(); |
| const Operator* CheckReceiverOrNullOrUndefined(); |
| const Operator* CheckSmi(const FeedbackSource& feedback); |
| const Operator* CheckString(const FeedbackSource& feedback); |
| const Operator* CheckSymbol(); |
| |
| const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedFloat64ToInt64(CheckForMinusZeroMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedInt32Add(); |
| const Operator* CheckedInt32Div(); |
| const Operator* CheckedInt32Mod(); |
| const Operator* CheckedInt32Mul(CheckForMinusZeroMode); |
| const Operator* CheckedInt32Sub(); |
| const Operator* CheckedInt32ToTaggedSigned(const FeedbackSource& feedback); |
| const Operator* CheckedInt64ToInt32(const FeedbackSource& feedback); |
| const Operator* CheckedInt64ToTaggedSigned(const FeedbackSource& feedback); |
| const Operator* CheckedTaggedSignedToInt32(const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToArrayIndex(const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToInt64(CheckForMinusZeroMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToTaggedPointer(const FeedbackSource& feedback); |
| const Operator* CheckedTaggedToTaggedSigned(const FeedbackSource& feedback); |
| const Operator* CheckBigInt(const FeedbackSource& feedback); |
| const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode, |
| const FeedbackSource& feedback); |
| const Operator* CheckedUint32Div(); |
| const Operator* CheckedUint32Mod(); |
| const Operator* CheckedUint32ToInt32(const FeedbackSource& feedback); |
| const Operator* CheckedUint32ToTaggedSigned(const FeedbackSource& feedback); |
| const Operator* CheckedUint64ToInt32(const FeedbackSource& feedback); |
| const Operator* CheckedUint64ToTaggedSigned(const FeedbackSource& feedback); |
| |
| const Operator* ConvertReceiver(ConvertReceiverMode); |
| |
| const Operator* ConvertTaggedHoleToUndefined(); |
| |
| const Operator* ObjectIsArrayBufferView(); |
| const Operator* ObjectIsBigInt(); |
| const Operator* ObjectIsCallable(); |
| const Operator* ObjectIsConstructor(); |
| const Operator* ObjectIsDetectableCallable(); |
| const Operator* ObjectIsMinusZero(); |
| const Operator* NumberIsMinusZero(); |
| const Operator* ObjectIsNaN(); |
| const Operator* NumberIsNaN(); |
| const Operator* ObjectIsNonCallable(); |
| const Operator* ObjectIsNumber(); |
| const Operator* ObjectIsReceiver(); |
| const Operator* ObjectIsSmi(); |
| const Operator* ObjectIsString(); |
| const Operator* ObjectIsSymbol(); |
| const Operator* ObjectIsUndetectable(); |
| |
| const Operator* NumberIsFloat64Hole(); |
| const Operator* NumberIsFinite(); |
| const Operator* ObjectIsFiniteNumber(); |
| const Operator* NumberIsInteger(); |
| const Operator* ObjectIsSafeInteger(); |
| const Operator* NumberIsSafeInteger(); |
| const Operator* ObjectIsInteger(); |
| |
| const Operator* ArgumentsFrame(); |
| const Operator* ArgumentsLength(int formal_parameter_count); |
| const Operator* RestLength(int formal_parameter_count); |
| |
| const Operator* NewDoubleElements(AllocationType); |
| const Operator* NewSmiOrObjectElements(AllocationType); |
| |
| // new-arguments-elements frame, arguments count |
| const Operator* NewArgumentsElements(CreateArgumentsType type, |
| int formal_parameter_count); |
| |
| // new-cons-string length, first, second |
| const Operator* NewConsString(); |
| |
| // ensure-writable-fast-elements object, elements |
| const Operator* EnsureWritableFastElements(); |
| |
| // maybe-grow-fast-elements object, elements, index, length |
| const Operator* MaybeGrowFastElements(GrowFastElementsMode mode, |
| const FeedbackSource& feedback); |
| |
| // transition-elements-kind object, from-map, to-map |
| const Operator* TransitionElementsKind(ElementsTransition transition); |
| |
| const Operator* Allocate(Type type, |
| AllocationType allocation = AllocationType::kYoung); |
| const Operator* AllocateRaw( |
| Type type, AllocationType allocation = AllocationType::kYoung, |
| AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse); |
| |
| const Operator* LoadMessage(); |
| const Operator* StoreMessage(); |
| |
| const Operator* LoadFieldByIndex(); |
| const Operator* LoadField(FieldAccess const&); |
| const Operator* StoreField(FieldAccess const&); |
| |
| // load-element [base + index] |
| const Operator* LoadElement(ElementAccess const&); |
| |
| // load-stack-argument [base + index] |
| const Operator* LoadStackArgument(); |
| |
| // store-element [base + index], value |
| const Operator* StoreElement(ElementAccess const&); |
| |
| // store-element [base + index], value, only with fast arrays. |
| const Operator* TransitionAndStoreElement(Handle<Map> double_map, |
| Handle<Map> fast_map); |
| // store-element [base + index], smi value, only with fast arrays. |
| const Operator* StoreSignedSmallElement(); |
| |
| // store-element [base + index], double value, only with fast arrays. |
| const Operator* TransitionAndStoreNumberElement(Handle<Map> double_map); |
| |
| // store-element [base + index], object value, only with fast arrays. |
| const Operator* TransitionAndStoreNonNumberElement(Handle<Map> fast_map, |
| Type value_type); |
| |
| // load-from-object [base + offset] |
| const Operator* LoadFromObject(ObjectAccess const&); |
| |
| // store-to-object [base + offset], value |
| const Operator* StoreToObject(ObjectAccess const&); |
| |
| // load-typed-element buffer, [base + external + index] |
| const Operator* LoadTypedElement(ExternalArrayType const&); |
| |
| // load-data-view-element object, [base + index] |
| const Operator* LoadDataViewElement(ExternalArrayType const&); |
| |
| // store-typed-element buffer, [base + external + index], value |
| const Operator* StoreTypedElement(ExternalArrayType const&); |
| |
| // store-data-view-element object, [base + index], value |
| const Operator* StoreDataViewElement(ExternalArrayType const&); |
| |
| // Abort (for terminating execution on internal error). |
| const Operator* RuntimeAbort(AbortReason reason); |
| |
| // Abort if the value input does not inhabit the given type |
| const Operator* AssertType(Type type); |
| |
| const Operator* DateNow(); |
| |
| // Represents the inputs necessary to construct a fast and a slow API call. |
| const Operator* FastApiCall(const CFunctionInfo* signature, |
| FeedbackSource const& feedback, |
| CallDescriptor* descriptor); |
| |
| private: |
| Zone* zone() const { return zone_; } |
| |
| const SimplifiedOperatorGlobalCache& cache_; |
| Zone* const zone_; |
| }; |
| |
| // Node wrappers. |
| |
| // TODO(jgruber): Consider merging with JSNodeWrapperBase. |
| class SimplifiedNodeWrapperBase : public NodeWrapper { |
| public: |
| explicit constexpr SimplifiedNodeWrapperBase(Node* node) |
| : NodeWrapper(node) {} |
| |
| // Valid iff this node has a context input. |
| TNode<Object> context() const { |
| // Could be a Context or NoContextConstant. |
| return TNode<Object>::UncheckedCast( |
| NodeProperties::GetContextInput(node())); |
| } |
| |
| // Valid iff this node has exactly one effect input. |
| Effect effect() const { |
| DCHECK_EQ(node()->op()->EffectInputCount(), 1); |
| return Effect{NodeProperties::GetEffectInput(node())}; |
| } |
| |
| // Valid iff this node has exactly one control input. |
| Control control() const { |
| DCHECK_EQ(node()->op()->ControlInputCount(), 1); |
| return Control{NodeProperties::GetControlInput(node())}; |
| } |
| |
| // Valid iff this node has a frame state input. |
| FrameState frame_state() const { |
| return FrameState{NodeProperties::GetFrameStateInput(node())}; |
| } |
| }; |
| |
| #define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \ |
| static constexpr int Name##Index() { return TheIndex; } \ |
| TNode<Type> name() const { \ |
| return TNode<Type>::UncheckedCast( \ |
| NodeProperties::GetValueInput(node(), TheIndex)); \ |
| } |
| |
| class FastApiCallNode final : public SimplifiedNodeWrapperBase { |
| public: |
| explicit constexpr FastApiCallNode(Node* node) |
| : SimplifiedNodeWrapperBase(node) { |
| CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kFastApiCall); |
| } |
| |
| const FastApiCallParameters& Parameters() const { |
| return FastApiCallParametersOf(node()->op()); |
| } |
| |
| #define INPUTS(V) \ |
| V(Target, target, 0, Object) \ |
| V(Receiver, receiver, 1, Object) |
| INPUTS(DEFINE_INPUT_ACCESSORS) |
| #undef INPUTS |
| |
| // Besides actual arguments, FastApiCall nodes also take: |
| static constexpr int kFastTargetInputCount = 1; |
| static constexpr int kSlowTargetInputCount = 1; |
| static constexpr int kFastReceiverInputCount = 1; |
| static constexpr int kSlowReceiverInputCount = 1; |
| static constexpr int kExtraInputCount = |
| kFastTargetInputCount + kFastReceiverInputCount; |
| |
| static constexpr int kHasErrorInputCount = 1; |
| static constexpr int kArityInputCount = 1; |
| static constexpr int kNewTargetInputCount = 1; |
| static constexpr int kHolderInputCount = 1; |
| static constexpr int kContextAndFrameStateInputCount = 2; |
| static constexpr int kEffectAndControlInputCount = 2; |
| static constexpr int kFastCallExtraInputCount = |
| kFastTargetInputCount + kHasErrorInputCount + kEffectAndControlInputCount; |
| static constexpr int kSlowCallExtraInputCount = |
| kSlowTargetInputCount + kArityInputCount + kNewTargetInputCount + |
| kSlowReceiverInputCount + kHolderInputCount + |
| kContextAndFrameStateInputCount + kEffectAndControlInputCount; |
| |
| // This is the arity fed into FastApiCallArguments. |
| static constexpr int ArityForArgc(int c_arg_count, int js_arg_count) { |
| return c_arg_count + kFastTargetInputCount + js_arg_count + |
| kEffectAndControlInputCount; |
| } |
| |
| int FastCallArgumentCount() const; |
| int SlowCallArgumentCount() const; |
| |
| constexpr int FirstFastCallArgumentIndex() const { |
| return ReceiverIndex() + 1; |
| } |
| constexpr int FastCallArgumentIndex(int i) const { |
| return FirstFastCallArgumentIndex() + i; |
| } |
| TNode<Object> FastCallArgument(int i) const { |
| DCHECK_LT(i, FastCallArgumentCount()); |
| return TNode<Object>::UncheckedCast( |
| NodeProperties::GetValueInput(node(), FastCallArgumentIndex(i))); |
| } |
| |
| int FirstSlowCallArgumentIndex() const { |
| return FastCallArgumentCount() + FastApiCallNode::kFastTargetInputCount; |
| } |
| int SlowCallArgumentIndex(int i) const { |
| return FirstSlowCallArgumentIndex() + i; |
| } |
| TNode<Object> SlowCallArgument(int i) const { |
| DCHECK_LT(i, SlowCallArgumentCount()); |
| return TNode<Object>::UncheckedCast( |
| NodeProperties::GetValueInput(node(), SlowCallArgumentIndex(i))); |
| } |
| }; |
| |
| class TierUpCheckNode final : public SimplifiedNodeWrapperBase { |
| public: |
| explicit constexpr TierUpCheckNode(Node* node) |
| : SimplifiedNodeWrapperBase(node) { |
| CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kTierUpCheck); |
| } |
| |
| #define INPUTS(V) \ |
| V(FeedbackVector, feedback_vector, 0, FeedbackVector) \ |
| V(Target, target, 1, JSReceiver) \ |
| V(NewTarget, new_target, 2, Object) \ |
| V(InputCount, input_count, 3, UntaggedT) \ |
| V(Context, context, 4, Context) |
| INPUTS(DEFINE_INPUT_ACCESSORS) |
| #undef INPUTS |
| }; |
| |
| class UpdateInterruptBudgetNode final : public SimplifiedNodeWrapperBase { |
| public: |
| explicit constexpr UpdateInterruptBudgetNode(Node* node) |
| : SimplifiedNodeWrapperBase(node) { |
| CONSTEXPR_DCHECK(node->opcode() == IrOpcode::kUpdateInterruptBudget); |
| } |
| |
| int delta() const { return OpParameter<int>(node()->op()); } |
| |
| #define INPUTS(V) V(FeedbackCell, feedback_cell, 0, FeedbackCell) |
| INPUTS(DEFINE_INPUT_ACCESSORS) |
| #undef INPUTS |
| }; |
| |
| #undef DEFINE_INPUT_ACCESSORS |
| |
| } // namespace compiler |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |