diff --git a/ets2panda/checker/checker.cpp b/ets2panda/checker/checker.cpp index 39c4be1b5982acc392442724bc58a9d76b98126a..74c90e74523571418b8f7cc915ef8b67ecacfd9b 100644 --- a/ets2panda/checker/checker.cpp +++ b/ets2panda/checker/checker.cpp @@ -183,11 +183,11 @@ void Checker::CleanUp() } context_ = CheckerContext(this, CheckerStatus::NO_OPTS); relation_ = allocator_->New(this); - identicalResults_.cached.clear(); - assignableResults_.cached.clear(); - comparableResults_.cached.clear(); - uncheckedCastableResults_.cached.clear(); - supertypeResults_.cached.clear(); + identicalResults_.Clear(); + assignableResults_.Clear(); + comparableResults_.Clear(); + uncheckedCastableResults_.Clear(); + supertypeResults_.Clear(); typeStack_.clear(); namedTypeStack_.clear(); } diff --git a/ets2panda/checker/checker.h b/ets2panda/checker/checker.h index c41af2dbd818e3aa0df7266e0b115847fb411979..475bf73ce83e54f349f866bf91b38f483c3af048 100644 --- a/ets2panda/checker/checker.h +++ b/ets2panda/checker/checker.h @@ -255,11 +255,11 @@ private: varbinder::Scope *scope_ {}; util::DiagnosticEngine &diagnosticEngine_; - RelationHolder identicalResults_ {Allocator(), RelationType::IDENTICAL}; - RelationHolder assignableResults_ {Allocator(), RelationType::ASSIGNABLE}; - RelationHolder comparableResults_ {Allocator(), RelationType::COMPARABLE}; - RelationHolder uncheckedCastableResults_ {Allocator(), RelationType::UNCHECKED_CASTABLE}; - RelationHolder supertypeResults_ {Allocator(), RelationType::SUPERTYPE}; + RelationHolder identicalResults_ {Allocator()}; + RelationHolder assignableResults_ {Allocator()}; + RelationHolder comparableResults_ {Allocator()}; + RelationHolder uncheckedCastableResults_ {Allocator()}; + RelationHolder supertypeResults_ {Allocator()}; std::unordered_map typeStack_; std::unordered_set namedTypeStack_; diff --git a/ets2panda/checker/types/type.h b/ets2panda/checker/types/type.h index d3f83e9d37094cd16ce4d49ef9be620eae5bd5ae..76571861aab3aebc2c9935f3abf251032d2206f2 100644 --- a/ets2panda/checker/types/type.h +++ b/ets2panda/checker/types/type.h @@ -50,7 +50,8 @@ public: explicit Type(TypeFlag flag) : typeFlags_(flag) { std::lock_guard lock(idLock_); - static uint64_t typeId = 0; + static uint32_t typeId = 0; + ES2PANDA_ASSERT(typeId < std::numeric_limits::max()); id_ = ++typeId; } @@ -180,7 +181,7 @@ public: typeFlags_ &= ~typeFlag; } - uint64_t Id() const + uint32_t Id() const { return id_; } @@ -272,7 +273,7 @@ protected: // NOLINTBEGIN(misc-non-private-member-variables-in-classes) TypeFlag typeFlags_; varbinder::Variable *variable_ {}; // Variable associated with the type if any - uint64_t id_; + uint32_t id_; // NOLINTEND(misc-non-private-member-variables-in-classes) }; diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index a9a9e59d95903550d32426390fe01194d1a9a34f..130fa19dbbf95318c6de95f56091dc5d28084585 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -36,17 +36,17 @@ RelationResult TypeRelation::CacheLookup(const Type *source, const Type *target, ES2PANDA_ASSERT(source != nullptr); ES2PANDA_ASSERT(target != nullptr); - RelationKey relationKey {source->Id(), target->Id()}; - auto res = holder.cached.find(relationKey); - if (res == holder.cached.end()) { + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + auto res = holder.Find(key); + if (res == nullptr) { return RelationResult::CACHE_MISS; } - if (res->second.type >= type && res->second.result == RelationResult::TRUE) { + if (res->type >= type && res->result == RelationResult::TRUE) { return RelationResult::TRUE; } - if (res->second.type <= type && res->second.result == RelationResult::FALSE) { + if (res->type <= type && res->result == RelationResult::FALSE) { return RelationResult::FALSE; } @@ -69,7 +69,8 @@ bool TypeRelation::IsIdenticalTo(Type *source, Type *target) checker_->ResolveStructuredTypeMembers(target); result_ = RelationResult::FALSE; target->Identical(this, source); - checker_->IdenticalResults().cached.insert({{source->Id(), target->Id()}, {result_, RelationType::IDENTICAL}}); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->IdenticalResults().Insert(key, {result_, RelationType::IDENTICAL}); } return IsTrue(); @@ -143,8 +144,8 @@ bool TypeRelation::IsAssignableTo(Type *source, Type *target) } if (flags_ == TypeRelationFlag::NONE) { - checker_->AssignableResults().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::ASSIGNABLE}}); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->AssignableResults().Insert(key, {result_, RelationType::ASSIGNABLE}); } } @@ -161,8 +162,8 @@ bool TypeRelation::IsComparableTo(Type *source, Type *target) result_ = RelationResult::FALSE; target->Compare(this, source); - checker_->ComparableResults().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::COMPARABLE}}); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->ComparableResults().Insert(key, {result_, RelationType::COMPARABLE}); } return result_ == RelationResult::TRUE; @@ -185,8 +186,8 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) } if (UncheckedCast() && !node_->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { - checker_->UncheckedCastableResult().cached.insert( - {{source->Id(), target->Id()}, {result_, RelationType::UNCHECKED_CASTABLE}}); + auto key = RelationHolder::MakeKey(source->Id(), target->Id()); + checker_->UncheckedCastableResult().Insert(key, {result_, RelationType::UNCHECKED_CASTABLE}); } return true; @@ -270,7 +271,8 @@ bool TypeRelation::IsSupertypeOf(Type *super, Type *sub) } if (flags_ == TypeRelationFlag::NONE) { - checker_->SupertypeResults().cached.insert({{super->Id(), sub->Id()}, {result_, RelationType::SUPERTYPE}}); + auto key = RelationHolder::MakeKey(super->Id(), sub->Id()); + checker_->SupertypeResults().Insert(key, {result_, RelationType::SUPERTYPE}); } } diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index c5abfa2e85516d6e9f262ae4fea83702a2c7a99c..ac87200fbce06c222e7618258bcee72f2aa1a2a8 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -71,9 +71,9 @@ enum class TypeRelationFlag : uint32_t { CASTING_CONTEXT = WIDENING | BOXING | UNBOXING | UNCHECKED_CAST, }; -enum class RelationResult { TRUE, FALSE, UNKNOWN, MAYBE, CACHE_MISS, ERROR }; +enum class RelationResult : uint8_t { TRUE, FALSE, UNKNOWN, MAYBE, CACHE_MISS, ERROR }; -enum class RelationType { COMPARABLE, ASSIGNABLE, IDENTICAL, UNCHECKED_CASTABLE, SUPERTYPE }; +enum class RelationType : uint8_t { COMPARABLE, ASSIGNABLE, IDENTICAL, UNCHECKED_CASTABLE, SUPERTYPE }; enum class VarianceFlag { COVARIANT, CONTRAVARIANT, INVARIANT }; @@ -85,47 +85,45 @@ struct enumbitops::IsAllowedType : std namespace ark::es2panda::checker { -class RelationKey { +class RelationHolder { public: - uint64_t sourceId; - uint64_t targetId; -}; + using RelationKey = uint64_t; -class RelationKeyHasher { -public: - size_t operator()(const RelationKey &key) const noexcept + class RelationEntry { + public: + RelationResult result; + RelationType type; + }; + + explicit RelationHolder(ThreadSafeArenaAllocator *allocator) : cached_(allocator->Adapter()) {} + + static RelationKey MakeKey(uint32_t sourceId, uint32_t targetId) { - return static_cast(key.sourceId ^ key.targetId); + constexpr size_t U32_NR_BITS = 32; // CC-OFF(G.NAM.03-CPP) project code style + return (static_cast(sourceId) << U32_NR_BITS) | targetId; } -}; -class RelationKeyComparator { -public: - bool operator()(const RelationKey &lhs, const RelationKey &rhs) const + const RelationEntry *Find(RelationKey key) const { - return lhs.sourceId == rhs.sourceId && lhs.targetId == rhs.targetId; + auto it = cached_.find(key); + if (it == cached_.cend()) { + return nullptr; + } + return &it->second; } -}; -class RelationEntry { -public: - RelationResult result; - RelationType type; -}; - -using RelationMap = ArenaUnorderedMap; + void Insert(RelationKey key, RelationEntry entry) + { + cached_.insert({key, entry}); + } -class RelationHolder { -public: - RelationHolder(ThreadSafeArenaAllocator *allocator, RelationType relationType) - : cached(allocator->Adapter()), type(relationType) + void Clear() { + cached_.clear(); } - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - RelationMap cached; - // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) - RelationType type {}; +private: + ArenaUnorderedMap cached_; }; class TypeRelation {