From 22ef2257c8624e2383876c6fbb641162fe520228 Mon Sep 17 00:00:00 2001 From: John Stiles Date: Tue, 27 Oct 2020 10:48:15 -0400 Subject: [PATCH] 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 Commit-Queue: Brian Osman Auto-Submit: John Stiles --- src/sksl/SkSLPool.cpp | 40 ++++++++++++++++++++++------------------ src/sksl/SkSLPool.h | 5 +++-- src/sksl/ir/SkSLIRNode.h | 5 +---- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/sksl/SkSLPool.cpp b/src/sksl/SkSLPool.cpp index fcf04076f2..ec02ef478d 100644 --- a/src/sksl/SkSLPool.cpp +++ b/src/sksl/SkSLPool.cpp @@ -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::Create() { - constexpr int kNodesInPool = 512; - SkAutoMutexExclusive lock(recycled_pool_mutex()); std::unique_ptr 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); diff --git a/src/sksl/SkSLPool.h b/src/sksl/SkSLPool.h index 2933fd0279..69da9a133e 100644 --- a/src/sksl/SkSLPool.h +++ b/src/sksl/SkSLPool.h @@ -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. diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h index 7a26e4cf9a..060113afcf 100644 --- a/src/sksl/ir/SkSLIRNode.h +++ b/src/sksl/ir/SkSLIRNode.h @@ -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) {