mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-15 16:16:08 +00:00
Slab-allocate Metal bind groups
Bug: dawn:340 Change-Id: I6185e41d9c71c49953a4de91e5f3042968679fd6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15862 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
0338b7ae19
commit
459c2f930f
@@ -17,6 +17,7 @@
|
||||
#include "common/Assert.h"
|
||||
#include "common/Math.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
@@ -37,9 +38,13 @@ SlabAllocatorImpl::Slab::Slab(std::unique_ptr<char[]> allocation, IndexLinkNode*
|
||||
blocksInUse(0) {
|
||||
}
|
||||
|
||||
SlabAllocatorImpl::Slab::Slab(Slab&& rhs) = default;
|
||||
|
||||
SlabAllocatorImpl::SentinelSlab::SentinelSlab() : Slab(nullptr, nullptr) {
|
||||
}
|
||||
|
||||
SlabAllocatorImpl::SentinelSlab::SentinelSlab(SentinelSlab&& rhs) = default;
|
||||
|
||||
SlabAllocatorImpl::SentinelSlab::~SentinelSlab() {
|
||||
Slab* slab = this->next;
|
||||
while (slab != nullptr) {
|
||||
@@ -56,14 +61,12 @@ SlabAllocatorImpl::Index SlabAllocatorImpl::kInvalidIndex =
|
||||
std::numeric_limits<SlabAllocatorImpl::Index>::max();
|
||||
|
||||
SlabAllocatorImpl::SlabAllocatorImpl(Index blocksPerSlab,
|
||||
uint32_t allocationAlignment,
|
||||
uint32_t slabBlocksOffset,
|
||||
uint32_t blockStride,
|
||||
uint32_t indexLinkNodeOffset)
|
||||
: mAllocationAlignment(allocationAlignment),
|
||||
mSlabBlocksOffset(slabBlocksOffset),
|
||||
mBlockStride(blockStride),
|
||||
mIndexLinkNodeOffset(indexLinkNodeOffset),
|
||||
uint32_t objectSize,
|
||||
uint32_t objectAlignment)
|
||||
: mAllocationAlignment(std::max(static_cast<uint32_t>(alignof(Slab)), objectAlignment)),
|
||||
mSlabBlocksOffset(Align(sizeof(Slab), objectAlignment)),
|
||||
mIndexLinkNodeOffset(Align(objectSize, alignof(IndexLinkNode))),
|
||||
mBlockStride(Align(mIndexLinkNodeOffset + sizeof(IndexLinkNode), objectAlignment)),
|
||||
mBlocksPerSlab(blocksPerSlab),
|
||||
mTotalAllocationSize(
|
||||
// required allocation size
|
||||
@@ -74,6 +77,18 @@ SlabAllocatorImpl::SlabAllocatorImpl(Index blocksPerSlab,
|
||||
ASSERT(IsPowerOfTwo(mAllocationAlignment));
|
||||
}
|
||||
|
||||
SlabAllocatorImpl::SlabAllocatorImpl(SlabAllocatorImpl&& rhs)
|
||||
: mAllocationAlignment(rhs.mAllocationAlignment),
|
||||
mSlabBlocksOffset(rhs.mSlabBlocksOffset),
|
||||
mIndexLinkNodeOffset(rhs.mIndexLinkNodeOffset),
|
||||
mBlockStride(rhs.mBlockStride),
|
||||
mBlocksPerSlab(rhs.mBlocksPerSlab),
|
||||
mTotalAllocationSize(rhs.mTotalAllocationSize),
|
||||
mAvailableSlabs(std::move(rhs.mAvailableSlabs)),
|
||||
mFullSlabs(std::move(rhs.mFullSlabs)),
|
||||
mRecycledSlabs(std::move(rhs.mRecycledSlabs)) {
|
||||
}
|
||||
|
||||
SlabAllocatorImpl::~SlabAllocatorImpl() = default;
|
||||
|
||||
SlabAllocatorImpl::IndexLinkNode* SlabAllocatorImpl::OffsetFrom(
|
||||
|
||||
@@ -60,6 +60,8 @@ class SlabAllocatorImpl {
|
||||
// TODO(enga): Is uint8_t sufficient?
|
||||
using Index = uint16_t;
|
||||
|
||||
SlabAllocatorImpl(SlabAllocatorImpl&& rhs);
|
||||
|
||||
protected:
|
||||
// This is essentially a singly linked list using indices instead of pointers,
|
||||
// so we store the index of "this" in |this->index|.
|
||||
@@ -76,6 +78,7 @@ class SlabAllocatorImpl {
|
||||
// | ---------- allocation --------- |
|
||||
// | pad | Slab | data ------------> |
|
||||
Slab(std::unique_ptr<char[]> allocation, IndexLinkNode* head);
|
||||
Slab(Slab&& rhs);
|
||||
|
||||
void Splice();
|
||||
|
||||
@@ -86,11 +89,7 @@ class SlabAllocatorImpl {
|
||||
Index blocksInUse;
|
||||
};
|
||||
|
||||
SlabAllocatorImpl(Index blocksPerSlab,
|
||||
uint32_t allocationAlignment,
|
||||
uint32_t slabBlocksOffset,
|
||||
uint32_t blockStride,
|
||||
uint32_t indexLinkNodeOffset);
|
||||
SlabAllocatorImpl(Index blocksPerSlab, uint32_t objectSize, uint32_t objectAlignment);
|
||||
~SlabAllocatorImpl();
|
||||
|
||||
// Allocate a new block of memory.
|
||||
@@ -136,13 +135,13 @@ class SlabAllocatorImpl {
|
||||
// the offset to the start of the aligned memory region.
|
||||
const uint32_t mSlabBlocksOffset;
|
||||
|
||||
// The IndexLinkNode is stored after the Allocation itself. This is the offset to it.
|
||||
const uint32_t mIndexLinkNodeOffset;
|
||||
|
||||
// Because alignment of allocations may introduce padding, |mBlockStride| is the
|
||||
// distance between aligned blocks of (Allocation + IndexLinkNode)
|
||||
const uint32_t mBlockStride;
|
||||
|
||||
// The IndexLinkNode is stored after the Allocation itself. This is the offset to it.
|
||||
const uint32_t mIndexLinkNodeOffset;
|
||||
|
||||
const Index mBlocksPerSlab; // The total number of blocks in a slab.
|
||||
|
||||
const size_t mTotalAllocationSize;
|
||||
@@ -151,6 +150,8 @@ class SlabAllocatorImpl {
|
||||
SentinelSlab();
|
||||
~SentinelSlab();
|
||||
|
||||
SentinelSlab(SentinelSlab&& rhs);
|
||||
|
||||
void Prepend(Slab* slab);
|
||||
};
|
||||
|
||||
@@ -160,32 +161,13 @@ class SlabAllocatorImpl {
|
||||
// we don't thrash the current "active" slab.
|
||||
};
|
||||
|
||||
template <typename T, size_t ObjectSize = 0>
|
||||
template <typename T>
|
||||
class SlabAllocator : public SlabAllocatorImpl {
|
||||
// Helper struct for computing alignments
|
||||
struct Storage {
|
||||
Slab slab;
|
||||
struct Block {
|
||||
// If the size is unspecified, use sizeof(T) as default. Defined here and not as a
|
||||
// default template parameter because T may be an incomplete type at the time of
|
||||
// declaration.
|
||||
static constexpr size_t kSize = ObjectSize == 0 ? sizeof(T) : ObjectSize;
|
||||
static_assert(kSize >= sizeof(T), "");
|
||||
|
||||
alignas(alignof(T)) char object[kSize];
|
||||
IndexLinkNode node;
|
||||
} blocks[];
|
||||
};
|
||||
|
||||
public:
|
||||
SlabAllocator(Index blocksPerSlab)
|
||||
: SlabAllocatorImpl(
|
||||
blocksPerSlab,
|
||||
alignof(Storage), // allocationAlignment
|
||||
offsetof(Storage, blocks[0]), // slabBlocksOffset
|
||||
offsetof(Storage, blocks[1]) - offsetof(Storage, blocks[0]), // blockStride
|
||||
offsetof(typename Storage::Block, node) // indexLinkNodeOffset
|
||||
) {
|
||||
SlabAllocator(size_t totalObjectBytes,
|
||||
uint32_t objectSize = sizeof(T),
|
||||
uint32_t objectAlignment = alignof(T))
|
||||
: SlabAllocatorImpl(totalObjectBytes / objectSize, objectSize, objectAlignment) {
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
|
||||
Reference in New Issue
Block a user