type::Manager: Simplify interface and use BlockAllocator

Internally use BlockAllocator to allocate the types.
When we optimize the allocation patterns of BlockAllocator, this will now benefit both AST nodes and types.

Remove Reset(). It was not used.

Remove type::Manager::Get(std::unique_ptr<type::Type>) - this was used (via Module::unique_type) in one place, which has easily been migrated to using the standard Module::create<>.

Replace all remaining uses of std::unique_ptr<> of types in tests with the standard create<> so we can guarantee uniqueness of the types.

Change-Id: Ib0e1fe94e492b31816450df5de0c839a0aefcb9e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38362
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton
2021-01-21 16:35:10 +00:00
committed by Commit Bot service account
parent 1e29f4beb0
commit 281b602f59
11 changed files with 138 additions and 172 deletions

View File

@@ -24,18 +24,5 @@ Manager::Manager(Manager&&) = default;
Manager& Manager::operator=(Manager&& rhs) = default;
Manager::~Manager() = default;
void Manager::Reset() {
types_.clear();
}
type::Type* Manager::Get(std::unique_ptr<type::Type> type) {
auto name = type->type_name();
if (types_.find(name) == types_.end()) {
types_[name] = std::move(type);
}
return types_.find(name)->second.get();
}
} // namespace type
} // namespace tint

View File

@@ -15,11 +15,11 @@
#ifndef SRC_TYPE_TYPE_MANAGER_H_
#define SRC_TYPE_TYPE_MANAGER_H_
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include "src/block_allocator.h"
#include "src/type/type.h"
namespace tint {
@@ -28,6 +28,9 @@ namespace type {
/// The type manager holds all the pointers to the known types.
class Manager {
public:
/// Iterator is the type returned by begin() and end()
using Iterator = BlockAllocator<type::Type>::ConstIterator;
/// Constructor
Manager();
@@ -42,31 +45,38 @@ class Manager {
/// Destructor
~Manager();
/// Clears all registered types.
void Reset();
/// Get the given type from the type manager
/// @param type The type to register
/// @return the pointer to the registered type
type::Type* Get(std::unique_ptr<type::Type> type);
/// Get the given type `T` from the type manager
/// @param args the arguments to pass to the type constructor
/// @return the pointer to the registered type
template <typename T, typename... ARGS>
T* Get(ARGS&&... args) {
auto ty = Get(std::make_unique<T>(std::forward<ARGS>(args)...));
return static_cast<T*>(ty);
// Note: We do not use std::forward here, as we may need to use the
// arguments again for the call to Create<T>() below.
auto name = T(args...).type_name();
auto it = by_name_.find(name);
if (it != by_name_.end()) {
return static_cast<T*>(it->second);
}
auto* type = types_.Create<T>(std::forward<ARGS>(args)...);
by_name_.emplace(name, type);
return type;
}
/// Returns the type map
/// @returns the mapping from name string to type.
const std::unordered_map<std::string, std::unique_ptr<type::Type>>& types() {
return types_;
const std::unordered_map<std::string, type::Type*>& types() {
return by_name_;
}
/// @returns an iterator to the beginning of the types
Iterator begin() const { return types_.Objects().begin(); }
/// @returns an iterator to the end of the types
Iterator end() const { return types_.Objects().end(); }
private:
std::unordered_map<std::string, std::unique_ptr<type::Type>> types_;
std::unordered_map<std::string, type::Type*> by_name_;
BlockAllocator<type::Type> types_;
};
} // namespace type

View File

@@ -26,46 +26,33 @@ using TypeManagerTest = testing::Test;
TEST_F(TypeManagerTest, GetUnregistered) {
Manager tm;
auto* t = tm.Get(std::make_unique<I32>());
auto* t = tm.Get<I32>();
ASSERT_NE(t, nullptr);
EXPECT_TRUE(t->Is<I32>());
}
TEST_F(TypeManagerTest, GetSameTypeReturnsSamePtr) {
Manager tm;
auto* t = tm.Get(std::make_unique<I32>());
auto* t = tm.Get<I32>();
ASSERT_NE(t, nullptr);
EXPECT_TRUE(t->Is<I32>());
auto* t2 = tm.Get(std::make_unique<I32>());
auto* t2 = tm.Get<I32>();
EXPECT_EQ(t, t2);
}
TEST_F(TypeManagerTest, GetDifferentTypeReturnsDifferentPtr) {
Manager tm;
auto* t = tm.Get(std::make_unique<I32>());
Type* t = tm.Get<I32>();
ASSERT_NE(t, nullptr);
EXPECT_TRUE(t->Is<I32>());
auto* t2 = tm.Get(std::make_unique<U32>());
Type* t2 = tm.Get<U32>();
ASSERT_NE(t2, nullptr);
EXPECT_NE(t, t2);
EXPECT_TRUE(t2->Is<U32>());
}
TEST_F(TypeManagerTest, ResetClearsPreviousData) {
Manager tm;
auto* t = tm.Get(std::make_unique<I32>());
ASSERT_NE(t, nullptr);
EXPECT_FALSE(tm.types().empty());
tm.Reset();
EXPECT_TRUE(tm.types().empty());
auto* t2 = tm.Get(std::make_unique<I32>());
ASSERT_NE(t2, nullptr);
}
} // namespace
} // namespace type
} // namespace tint