Allow SkSL compilers to reuse SkSL Pools without reallocating.
When a Program is freed, rather than immediately disposing of its Pool,
it now sends it to Pool::Recycle, which holds onto it. If Pool::Create
is called, it satisfies the request by simply handing back the recycled
pool. Only one pool is kept in recycle storage at a time--recycling
more than one pool in a row will cause all but one to be freed. To avoid
holding onto Pool memory indefinitely, pool recycle storage is cleaned
up whenever a Compiler is destroyed.
Change-Id: I21c1ccde84507e344102d05506d869e62ca095a6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329175
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLPool.h b/src/sksl/SkSLPool.h
index f7338ac..2933fd0 100644
--- a/src/sksl/SkSLPool.h
+++ b/src/sksl/SkSLPool.h
@@ -19,21 +19,28 @@
public:
~Pool();
- // Creates a pool to store newly-created IRNodes during program creation and attaches it to the
- // current thread. When your program is complete, call pool->detachFromThread() to transfer
- // ownership of those nodes. Before destroying any of the program's nodes, reattach the pool via
- // pool->attachToThread(). It is an error to call CreatePoolOnThread if a pool is already
- // attached to the current thread.
- static std::unique_ptr<Pool> CreatePoolOnThread(int nodesInPool);
+ // Creates a pool to store IRNodes during program creation. Call attachToThread() to start using
+ // the pool for IRNode allocations. When your program is complete, call pool->detachFromThread()
+ // to take ownership of the pool and its nodes. Before destroying any of the program's nodes,
+ // make sure to reattach the pool by calling pool->attachToThread() again.
+ static std::unique_ptr<Pool> Create();
- // Once a pool has been created and the ephemeral work has completed, detach it from its thread.
+ // Gives up ownership of a pool; conceptually, this deletes it. In practice, on some platforms,
+ // it is expensive to free and reallocate pools, so this gives us an opportunity to reuse the
+ // allocation for future CreatePoolOnThread calls.
+ static void Recycle(std::unique_ptr<Pool> pool);
+
+ // Explicitly frees a previously recycled pool (if any), reclaiming the memory.
+ static void FreeRecycledPool() { Recycle(nullptr); }
+
+ // Attaches a pool to the current thread.
+ // It is an error to call this while a pool is already attached.
+ void attachToThread();
+
+ // Once you are done creating or destroying IRNodes in the pool, detach it from the thread.
// It is an error to call this while no pool is attached.
void detachFromThread();
- // Reattaches a pool to the current thread. It is an error to call this while a pool is already
- // attached.
- void attachToThread();
-
// Retrieves a node from the thread pool. If the pool is exhausted, this will allocate a node.
static void* AllocIRNode();
@@ -42,6 +49,8 @@
static void FreeIRNode(void* node_v);
private:
+ void checkForLeaks();
+
Pool() = default; // use CreatePoolOnThread to make a pool
PoolData* fData = nullptr;
};