feat(allocator): add per-thread caches to FreeList

Refactored FreeList allocator to use per-thread caches for improved scalability and performance, with configurable max concurrency and overflow cache. AllocationManager debug layer is now compile-time via ENABLE_DEBUG_LAYER. MemoryUtility methods no longer catch exceptions. Argument validation standardized with ThrowIfNegative. JobScheduler passes maxConcurrencyLevel to allocator. CollectionUtility's GetElementUnsafe returns mutable ref. AssemblyVersion incremented. Added comprehensive FreeList unit tests. Improved robustness and error handling in allocation classes.

BREAKING CHANGE: Debug layer APIs removed; FreeList allocator interface changed for thread cache support.
This commit is contained in:
2026-03-17 20:58:31 +09:00
parent 7ffe8bc0d1
commit 9cee32aa83
15 changed files with 772 additions and 482 deletions

View File

@@ -87,12 +87,19 @@ public unsafe partial struct Stack : IDisposable
private void Init(nuint size)
{
ArgumentOutOfRangeException.ThrowIfNegative(size);
if (_buffer != null)
{
Free(_buffer);
}
_buffer = (byte*)Malloc(size);
if (_buffer == null)
{
throw new OutOfMemoryException("Failed to allocate memory for the stack.");
}
_size = size;
_offset = 0;
_activeScopeCount = 0;
@@ -103,15 +110,15 @@ public unsafe partial struct Stack : IDisposable
s_locker.Enter(ref token);
if (s_pStackBuffers == null)
{
s_pStackBuffers = (void**)Malloc((nuint)sizeof(void*) * 4u);
s_stackCapacity = 4;
s_pStackBuffers = (void**)Malloc((nuint)(sizeof(void*) * Environment.ProcessorCount));
s_stackCapacity = Environment.ProcessorCount;
}
if (s_stackCount >= s_stackCapacity)
{
var pOld = s_pStackBuffers;
var newCapacity = s_stackCapacity * 2;
var pNew = (void**)Realloc(pOld, (nuint)sizeof(void*) * (nuint)newCapacity);
var pNew = (void**)Realloc(pOld, (nuint)(sizeof(void*) * newCapacity));
s_pStackBuffers = pNew;
s_stackCapacity = newCapacity;