From 847cfa07c57e10f200329ac2c6eca16a8c2d93bb Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Thu, 1 Dec 2022 21:42:47 +0000 Subject: [PATCH] Move allocator into TypeManager Currently the TypeManger is a UniqueAllocator. This works as long as the TypeManager only manages one specific thing. In order to support ArrayCount, which is type related, but not a type, the TypeManager will need to be able to store two types of things. This CL changes the TypeManager to contain a UniqueAllocator and proxies the needed Get, Find and iteration methods to that allocator. This will allow another allocator to be added for ArrayCount later. Bug: tint:1718 Change-Id: I0f952eb5c3ef90a7c85dead14d11b657dceba951 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112640 Commit-Queue: Dan Sinclair Reviewed-by: Ben Clayton Kokoro: Kokoro --- src/tint/sem/type_manager.h | 42 ++++++++++++++++++------------- src/tint/utils/unique_allocator.h | 34 ++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/tint/sem/type_manager.h b/src/tint/sem/type_manager.h index 636b7a04e6..72f843ad5b 100644 --- a/src/tint/sem/type_manager.h +++ b/src/tint/sem/type_manager.h @@ -25,10 +25,10 @@ namespace tint::sem { /// The type manager holds all the pointers to the known types. -class TypeManager final : public utils::UniqueAllocator { +class TypeManager final { public: /// Iterator is the type returned by begin() and end() - using Iterator = utils::BlockAllocator::ConstIterator; + using TypeIterator = utils::BlockAllocator::ConstIterator; /// Constructor TypeManager(); @@ -55,30 +55,38 @@ class TypeManager final : public utils::UniqueAllocator { /// @return the Manager that wraps `inner` static TypeManager Wrap(const TypeManager& inner) { TypeManager out; - out.items = inner.items; + out.types_.Wrap(inner.types_); return out; } - /// @param args the arguments used to create the temporary type used for the search. - /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the type + /// @param args the arguments used to construct the object. + /// @return a pointer to an instance of `T` with the provided arguments. + /// If an existing instance of `T` has been constructed, then the same + /// pointer is returned. + template >, + typename... ARGS> + TYPE* Get(ARGS&&... args) { + return types_.Get(std::forward(args)...); + } + + /// @param args the arguments used to create the temporary used for the search. + /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item /// was not found. - template + template >, + typename... ARGS> TYPE* Find(ARGS&&... args) const { - // Create a temporary T instance on the stack so that we can hash it, and - // use it for equality lookup for the std::unordered_set. - TYPE key{args...}; - auto hash = Hasher{}(key); - auto it = items.find(Entry{hash, &key}); - if (it != items.end()) { - return static_cast(it->ptr); - } - return nullptr; + return types_.Find(std::forward(args)...); } /// @returns an iterator to the beginning of the types - Iterator begin() const { return allocator.Objects().begin(); } + TypeIterator begin() const { return types_.begin(); } /// @returns an iterator to the end of the types - Iterator end() const { return allocator.Objects().end(); } + TypeIterator end() const { return types_.end(); } + + private: + utils::UniqueAllocator types_; }; } // namespace tint::sem diff --git a/src/tint/utils/unique_allocator.h b/src/tint/utils/unique_allocator.h index 129770113b..25681cdfff 100644 --- a/src/tint/utils/unique_allocator.h +++ b/src/tint/utils/unique_allocator.h @@ -28,6 +28,9 @@ namespace tint::utils { template , typename EQUAL = std::equal_to> class UniqueAllocator { public: + /// Iterator is the type returned by begin() and end() + using Iterator = typename BlockAllocator::ConstIterator; + /// @param args the arguments used to construct the object. /// @return a pointer to an instance of `T` with the provided arguments. /// If an existing instance of `T` has been constructed, then the same @@ -49,7 +52,36 @@ class UniqueAllocator { return ptr; } - protected: + /// @param args the arguments used to create the temporary used for the search. + /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item + /// was not found. + template + TYPE* Find(ARGS&&... args) const { + // Create a temporary T instance on the stack so that we can hash it, and + // use it for equality lookup for the std::unordered_set. + TYPE key{args...}; + auto hash = Hasher{}(key); + auto it = items.find(Entry{hash, &key}); + if (it != items.end()) { + return static_cast(it->ptr); + } + return nullptr; + } + + /// Wrap sets this allocator to the objects created with the content of `inner`. + /// The allocator after Wrap is intended to temporarily extend the objects + /// of an existing immutable UniqueAllocator. + /// As the copied objects are owned by `inner`, `inner` must not be destructed + /// or assigned while using this allocator. + /// @param o the immutable UniqueAlllocator to extend + void Wrap(const UniqueAllocator& o) { items = o.items; } + + /// @returns an iterator to the beginning of the types + Iterator begin() const { return allocator.Objects().begin(); } + /// @returns an iterator to the end of the types + Iterator end() const { return allocator.Objects().end(); } + + private: /// The hash function using Hasher = HASH; /// The equality function