Update the SkSL pool interface to take an allocation size.
Since our end goal no longer has all IRNodes ending up as the exact same size in memory, it makes sense for the allocator function to take in a desired size. This also opens the door to separate "small" and "large" pools, if we want to add pooling support for large but semi-common things like Variables. Change-Id: If3dbe31588adeedede327c5967c344a19507b6fa Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329961 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
5567a6091c
commit
22ef2257c8
@ -14,9 +14,12 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
static constexpr int kSmallNodeSize = 120;
|
||||
static constexpr int kNodesInPool = 512;
|
||||
|
||||
namespace { struct IRNodeData {
|
||||
union {
|
||||
uint8_t fBuffer[sizeof(IRNode)];
|
||||
uint8_t fBuffer[kSmallNodeSize];
|
||||
IRNodeData* fFreeListNext;
|
||||
};
|
||||
}; }
|
||||
@ -116,8 +119,6 @@ Pool::~Pool() {
|
||||
}
|
||||
|
||||
std::unique_ptr<Pool> Pool::Create() {
|
||||
constexpr int kNodesInPool = 512;
|
||||
|
||||
SkAutoMutexExclusive lock(recycled_pool_mutex());
|
||||
std::unique_ptr<Pool> pool;
|
||||
if (sRecycledPool) {
|
||||
@ -159,23 +160,26 @@ void Pool::detachFromThread() {
|
||||
set_thread_local_pool_data(nullptr);
|
||||
}
|
||||
|
||||
void* Pool::AllocIRNode() {
|
||||
// Is a pool attached?
|
||||
PoolData* poolData = get_thread_local_pool_data();
|
||||
if (poolData) {
|
||||
// Does the pool contain a free node?
|
||||
IRNodeData* node = poolData->fFreeListHead;
|
||||
if (node) {
|
||||
// Yes. Take a node from the freelist.
|
||||
poolData->fFreeListHead = node->fFreeListNext;
|
||||
VLOG("ALLOC Pool:0x%016llX Index:%04d 0x%016llX\n",
|
||||
(uint64_t)poolData, poolData->nodeIndex(node), (uint64_t)node);
|
||||
return node->fBuffer;
|
||||
void* Pool::AllocIRNode(size_t size) {
|
||||
// Can the requested size fit in a pool node?
|
||||
if (size <= kSmallNodeSize) {
|
||||
// Is a pool attached?
|
||||
PoolData* poolData = get_thread_local_pool_data();
|
||||
if (poolData) {
|
||||
// Does the pool contain a free node?
|
||||
IRNodeData* node = poolData->fFreeListHead;
|
||||
if (node) {
|
||||
// Yes. Take a node from the freelist.
|
||||
poolData->fFreeListHead = node->fFreeListNext;
|
||||
VLOG("ALLOC Pool:0x%016llX Index:%04d 0x%016llX\n",
|
||||
(uint64_t)poolData, poolData->nodeIndex(node), (uint64_t)node);
|
||||
return node->fBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The pool is detached or full; allocate nodes using malloc.
|
||||
void* ptr = ::operator new(sizeof(IRNode));
|
||||
// The pool can't be used for this allocation. Allocate nodes using the system allocator.
|
||||
void* ptr = ::operator new(size);
|
||||
VLOG("ALLOC Pool:0x%016llX Index:____ malloc 0x%016llX\n",
|
||||
(uint64_t)poolData, (uint64_t)ptr);
|
||||
return ptr;
|
||||
@ -197,7 +201,7 @@ void Pool::FreeIRNode(void* node_v) {
|
||||
}
|
||||
}
|
||||
|
||||
// No pool is attached or the node was malloced; it must be freed.
|
||||
// We couldn't associate this node with our pool. Free it using the system allocator.
|
||||
VLOG("FREE Pool:0x%016llX Index:____ free 0x%016llX\n",
|
||||
(uint64_t)poolData, (uint64_t)node_v);
|
||||
::operator delete(node_v);
|
||||
|
@ -41,8 +41,9 @@ public:
|
||||
// It is an error to call this while no pool is attached.
|
||||
void detachFromThread();
|
||||
|
||||
// Retrieves a node from the thread pool. If the pool is exhausted, this will allocate a node.
|
||||
static void* AllocIRNode();
|
||||
// Retrieves a node from the thread pool. If the pool is exhausted, or if the requested size
|
||||
// exceeds the size that we can deliver from a pool, this will just allocate memory.
|
||||
static void* AllocIRNode(size_t size);
|
||||
|
||||
// Releases a node that was created by AllocIRNode. This will return it to the pool, or free it,
|
||||
// as appropriate. Make sure to free all nodes, since some of them may be real allocations.
|
||||
|
@ -67,10 +67,7 @@ public:
|
||||
|
||||
// Override operator new and delete to allow us to control allocation behavior.
|
||||
static void* operator new(const size_t size) {
|
||||
if (size == sizeof(IRNode)) {
|
||||
return Pool::AllocIRNode();
|
||||
}
|
||||
return ::operator new(size);
|
||||
return Pool::AllocIRNode(size);
|
||||
}
|
||||
|
||||
static void operator delete(void* ptr) {
|
||||
|
Loading…
Reference in New Issue
Block a user