/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/codegen/tnode.h
452 строки
13 KB
Michaël Zasso
deps: update V8 to 14.1.146.11
04 окт 2025, 19:47
Не верифицирован
04 окт 2025, 19:47
7772a2d
Код
Авторство
О чём код?
// Copyright 2015 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_CODEGEN_TNODE_H_ #define V8_CODEGEN_TNODE_H_ #include <type_traits> #include "include/v8config.h" #include "src/codegen/machine-type.h" #include "src/objects/tagged.h" namespace v8 { namespace internal { class HeapNumber; class BigInt; namespace compiler { class Node; } // namespace compiler struct UntaggedT {}; struct IntegralT : UntaggedT {}; struct WordT : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineType::PointerRepresentation(); }; struct RawPtrT : WordT { static constexpr MachineType kMachineType = MachineType::Pointer(); }; // A RawPtrT that is guaranteed to point into the sandbox. struct SandboxedPtrT : WordT { static constexpr MachineType kMachineType = MachineType::SandboxedPointer(); }; template <class To> struct RawPtr : RawPtrT {}; struct Word32T : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kWord32; }; struct Int32T : Word32T { static constexpr MachineType kMachineType = MachineType::Int32(); }; struct Uint32T : Word32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; struct Int16T : Int32T { static constexpr MachineType kMachineType = MachineType::Int16(); }; struct Uint16T : Uint32T, Int32T { static constexpr MachineType kMachineType = MachineType::Uint16(); }; struct Int8T : Int16T { static constexpr MachineType kMachineType = MachineType::Int8(); }; struct Uint8T : Uint16T, Int16T { static constexpr MachineType kMachineType = MachineType::Uint8(); }; struct Word64T : IntegralT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kWord64; }; struct AdditiveSafeIntegerT : Word64T { static constexpr MachineType kMachineType = MachineType::Int64(); }; struct Int64T : Word64T { static constexpr MachineType kMachineType = MachineType::Int64(); }; struct Uint64T : Word64T { static constexpr MachineType kMachineType = MachineType::Uint64(); }; struct IntPtrT : WordT { static constexpr MachineType kMachineType = MachineType::IntPtr(); }; struct UintPtrT : WordT { static constexpr MachineType kMachineType = MachineType::UintPtr(); }; struct ExternalPointerHandleT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; struct CppHeapPointerHandleT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; struct IndirectPointerHandleT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; struct JSDispatchHandleT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; #ifdef V8_ENABLE_SANDBOX struct ExternalPointerT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; #else struct ExternalPointerT : UntaggedT { static constexpr MachineType kMachineType = MachineType::Pointer(); }; #endif #ifdef V8_COMPRESS_POINTERS struct CppHeapPointerT : Uint32T { static constexpr MachineType kMachineType = MachineType::Uint32(); }; #else // !V8_COMPRESS_POINTERS struct CppHeapPointerT : UntaggedT { static constexpr MachineType kMachineType = MachineType::Pointer(); }; #endif // !V8_COMPRESS_POINTERS struct Float16RawBitsT : Word32T { static constexpr MachineType kMachineType = MachineType::Uint16(); }; struct Float32T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kFloat32; static constexpr MachineType kMachineType = MachineType::Float32(); }; struct Float64T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kFloat64; static constexpr MachineType kMachineType = MachineType::Float64(); }; #ifdef V8_COMPRESS_POINTERS using TaggedT = Int32T; #else using TaggedT = IntPtrT; #endif #ifdef V8_ENABLE_SANDBOX using TrustedPointerT = IndirectPointerHandleT; #else using TrustedPointerT = TaggedT; #endif // Result of a comparison operation. struct BoolT : Word32T { static constexpr MachineType kMachineType = MachineType::Int32(); }; // Value type of a Turbofan node with two results. template <class T1, class T2> struct PairT {}; struct Simd128T : UntaggedT { static const MachineRepresentation kMachineRepresentation = MachineRepresentation::kSimd128; static constexpr MachineType kMachineType = MachineType::Simd128(); }; struct I8x16T : Simd128T {}; struct I16x8T : Simd128T {}; struct I32x2T : Simd128T {}; inline constexpr MachineType CommonMachineType(MachineType type1, MachineType type2) { return (type1 == type2) ? type1 : ((type1.IsTagged() && type2.IsTagged()) ? MachineType::AnyTagged() : MachineType::None()); } template <class Type, class Enable = void> struct MachineTypeOf { static constexpr MachineType value = Type::kMachineType; }; template <class Type, class Enable> constexpr MachineType MachineTypeOf<Type, Enable>::value; template <> struct MachineTypeOf<Object> { static constexpr MachineType value = MachineType::AnyTagged(); }; template <> struct MachineTypeOf<MaybeObject> { static constexpr MachineType value = MachineType::AnyTagged(); }; template <> struct MachineTypeOf<MaybeWeak<HeapObject>> { // TODO(leszeks): Can this be TaggedPointer? static constexpr MachineType value = MachineType::AnyTagged(); }; template <> struct MachineTypeOf<HeapObject> { static constexpr MachineType value = MachineType::TaggedPointer(); }; template <> struct MachineTypeOf<Smi> { static constexpr MachineType value = MachineType::TaggedSigned(); }; template <> struct MachineTypeOf<TaggedIndex> { static constexpr MachineType value = MachineType::Pointer(); }; template <class HeapObjectSubtype> struct MachineTypeOf< HeapObjectSubtype, std::enable_if_t<std::is_base_of_v<HeapObject, HeapObjectSubtype> || std::is_base_of_v<HeapObjectLayout, HeapObjectSubtype>>> { static constexpr MachineType value = MachineType::TaggedPointer(); }; template <class HeapObjectSubtype> constexpr MachineType MachineTypeOf< HeapObjectSubtype, std::enable_if_t<std::is_base_of_v<HeapObject, HeapObjectSubtype> || std::is_base_of_v<HeapObjectLayout, HeapObjectSubtype>>>:: value; template <> struct MachineTypeOf<ExternalReference> { static constexpr MachineType value = MachineType::Pointer(); }; template <class T> struct MachineTypeOf<Union<T>> { static constexpr MachineType value = MachineTypeOf<T>::value; }; template <class T, class... Ts> struct MachineTypeOf<Union<T, Ts...>> { static constexpr MachineType value = CommonMachineType( MachineTypeOf<T>::value, MachineTypeOf<Union<Ts...>>::value); static_assert(value.representation() != MachineRepresentation::kNone, "no common representation"); }; // Special case for Union<HeapObject,TaggedIndex>, which torque uses for // TaggedZeroPattern and can be treated as an AnyTagged template <> struct MachineTypeOf<Union<HeapObject, TaggedIndex>> { static constexpr MachineType value = MachineType::AnyTagged(); }; template <class Type, class Enable = void> struct MachineRepresentationOf { static const MachineRepresentation value = Type::kMachineRepresentation; }; // If T defines kMachineType, then we take the machine representation from // there. template <class T> struct MachineRepresentationOf<T, std::void_t<decltype(T::kMachineType)>> { static constexpr MachineRepresentation value = T::kMachineType.representation(); }; template <class T> struct MachineRepresentationOf<T, std::enable_if_t<is_taggable_v<T>>> { static constexpr MachineRepresentation value = MachineTypeOf<T>::value.representation(); }; template <> struct MachineRepresentationOf<ExternalReference> { static constexpr MachineRepresentation value = RawPtrT::kMachineRepresentation; }; template <typename T> constexpr bool IsMachineRepresentationOf(MachineRepresentation r) { return MachineRepresentationOf<T>::value == r; } template <class T> constexpr MachineRepresentation PhiMachineRepresentationOf = std::is_base_of_v<Word32T, T> ? MachineRepresentation::kWord32 : MachineRepresentationOf<T>::value; template <class T> struct is_valid_type_tag { static const bool value = is_taggable_v<T> || std::is_base_of_v<UntaggedT, T> || std::is_same_v<ExternalReference, T>; static const bool is_tagged = is_taggable_v<T>; }; template <class T1, class T2> struct is_valid_type_tag<PairT<T1, T2>> { static const bool value = is_valid_type_tag<T1>::value && is_valid_type_tag<T2>::value; static const bool is_tagged = false; }; template <class... T> struct is_valid_type_tag<Union<T...>> { static const bool is_tagged = (is_valid_type_tag<T>::is_tagged && ...); static const bool value = is_tagged; static_assert(is_tagged, "union types are only possible for tagged values"); }; using AnyTaggedT = UnionOf<Object, MaybeObject>; using ContextOrEmptyContext = UnionOf<Context, Smi>; // A pointer to a builtin function, used by Torque's function pointers. using BuiltinPtr = Smi; template <> struct is_subtype<ExternalReference, RawPtrT> { static const bool value = true; }; template <> struct is_subtype<IntPtrT, RawPtrT> { static const bool value = true; }; template <class T, class U> struct types_have_common_values { static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value; }; template <class U> struct types_have_common_values<BoolT, U> { static const bool value = types_have_common_values<Word32T, U>::value; }; template <class U> struct types_have_common_values<Uint32T, U> { static const bool value = types_have_common_values<Word32T, U>::value; }; template <class U> struct types_have_common_values<Int32T, U> { static const bool value = types_have_common_values<Word32T, U>::value; }; template <class U> struct types_have_common_values<Uint64T, U> { static const bool value = types_have_common_values<Word64T, U>::value; }; template <class U> struct types_have_common_values<AdditiveSafeIntegerT, U> { static const bool value = types_have_common_values<Word64T, U>::value; }; template <class U> struct types_have_common_values<Int64T, U> { static const bool value = types_have_common_values<Word64T, U>::value; }; template <class U> struct types_have_common_values<IntPtrT, U> { static const bool value = types_have_common_values<WordT, U>::value; }; template <class U> struct types_have_common_values<UintPtrT, U> { static const bool value = types_have_common_values<WordT, U>::value; }; template <class... Ts, class U> struct types_have_common_values<Union<Ts...>, U> { static const bool value = std::disjunction_v<types_have_common_values<Ts, U>...>; }; template <class T, class... Us> struct types_have_common_values<T, Union<Us...>> { static const bool value = std::disjunction_v<types_have_common_values<T, Us>...>; }; template <class... Ts, class... Us> struct types_have_common_values<Union<Ts...>, Union<Us...>> { static const bool value = std::disjunction_v<types_have_common_values<Ts, Union<Us...>>...>; }; // TNode<T> is an SSA value with the static type tag T, which is one of the // following: // - MaybeObject> represents the type of all tagged values, including weak // pointers. // - a subclass of internal::Object represents a non-weak tagged type. // - a subclass of internal::UntaggedT represents an untagged type // - ExternalReference // - PairT<T1, T2> for an operation returning two values, with types T1 // and T2 // - UnionOf<T1, T2, ...> represents a value of one of types T1, T2, etc. template <class T> class TNode { public: template <class U> TNode(const TNode<U>& other) V8_NOEXCEPT requires(is_subtype<U, T>::value) : node_(other.node_) { LazyTemplateChecks(); } TNode(const TNode& other) V8_NOEXCEPT : node_(other.node_) {} TNode() : node_(nullptr) {} TNode operator=(TNode other) { DCHECK_NOT_NULL(other.node_); node_ = other.node_; return *this; } operator compiler::Node*() const { return node_; } explicit operator bool() const { return node_ != nullptr; } static TNode UncheckedCast(compiler::Node* node) { return TNode(node); } protected: template <typename U> friend class TNode; explicit TNode(compiler::Node* node) : node_(node) { LazyTemplateChecks(); } // These checks shouldn't be checked before TNode is actually used. void LazyTemplateChecks() const { static_assert(is_valid_type_tag<T>::value, "invalid type tag"); } compiler::Node* node_; }; template <class T> class TNode<Tagged<T>> { static_assert(!std::is_same_v<T, T>, "Don't write TNode<Tagged<T>>, just write TNode<T> directly."); }; // SloppyTNode<T> is a variant of TNode<T> and allows implicit casts from // Node*. It is intended for function arguments as long as some call sites // still use untyped Node* arguments. // TODO(turbofan): Delete this class once transition is finished. template <class T> class SloppyTNode : public TNode<T> { public: SloppyTNode(compiler::Node* node) // NOLINT(runtime/explicit) : TNode<T>(node) {} template <class U> SloppyTNode(const TNode<U>& other) V8_NOEXCEPT // NOLINT(runtime/explicit) requires(is_subtype<U, T>::value) : TNode<T>(other) {} }; } // namespace internal } // namespace v8 #endif // V8_CODEGEN_TNODE_H_