From 8d5ed30c5d51eda55218e14ce313b5ed88a294af Mon Sep 17 00:00:00 2001 From: Misaki Date: Thu, 2 Apr 2026 20:49:17 +0900 Subject: [PATCH] feat(buffer): improve Free safety and refactor tests Stack and VirtualStack Free methods now check pointer bounds and update offsets only when appropriate, improving safety. Program.cs refactored to use MemoryPool with VirtualStack and new test methods. Assembly version bumped to 1.6.7. --- .../Buffer/Stack.cs | 11 ++++++- .../Buffer/VirtualStack.cs | 11 ++++++- .../Misaki.HighPerformance.LowLevel.csproj | 2 +- Misaki.HighPerformance.Test/Program.cs | 33 +++++++++++++++---- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Misaki.HighPerformance.LowLevel/Buffer/Stack.cs b/Misaki.HighPerformance.LowLevel/Buffer/Stack.cs index 18cc87b..5d28ea3 100644 --- a/Misaki.HighPerformance.LowLevel/Buffer/Stack.cs +++ b/Misaki.HighPerformance.LowLevel/Buffer/Stack.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Buffer; @@ -141,8 +142,16 @@ public unsafe partial struct Stack : IMemoryAllocator } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly void Free(void* ptr) + public void Free(void* ptr) { + if (ptr < _buffer && ptr >= _buffer + _size) + { + Debug.Fail("Attempting to free a pointer that is out of bounds of the current stack allocation."); + return; // Pointer is out of bounds, ignore + } + + var offset = (nuint)((byte*)ptr - _buffer); + _offset = offset < _offset ? offset : _offset; } /// diff --git a/Misaki.HighPerformance.LowLevel/Buffer/VirtualStack.cs b/Misaki.HighPerformance.LowLevel/Buffer/VirtualStack.cs index 3174ad9..f06e4e7 100644 --- a/Misaki.HighPerformance.LowLevel/Buffer/VirtualStack.cs +++ b/Misaki.HighPerformance.LowLevel/Buffer/VirtualStack.cs @@ -1,4 +1,5 @@ using Misaki.HighPerformance.LowLevel.Utilities; +using System.Diagnostics; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Buffer; @@ -161,8 +162,16 @@ public unsafe struct VirtualStack : IMemoryAllocator= _baseAddress + _committedSize) + { + Debug.Fail("Attempting to free a pointer that is out of bounds of the current stack allocation."); + return; // Pointer is out of bounds, ignore + } + + var offset = (nuint)((byte*)ptr - _baseAddress); + _allocatedOffset = offset < _allocatedOffset ? offset : _allocatedOffset; } public void Dispose() diff --git a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj index f4c8ad0..f677728 100644 --- a/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj +++ b/Misaki.HighPerformance.LowLevel/Misaki.HighPerformance.LowLevel.csproj @@ -7,7 +7,7 @@ true true Misaki - 1.6.6 + 1.6.7 $(AssemblyVersion) https://git.personalnas.com/Misaki/Misaki.HighPerformance.git https://git.personalnas.com/Misaki/Misaki.HighPerformance.git diff --git a/Misaki.HighPerformance.Test/Program.cs b/Misaki.HighPerformance.Test/Program.cs index b432621..77541d2 100644 --- a/Misaki.HighPerformance.Test/Program.cs +++ b/Misaki.HighPerformance.Test/Program.cs @@ -10,14 +10,33 @@ var opts = new AllocationManagerInitOpts FreeListConcurrencyLevel = 1 }; -AllocationManager.Initialize(opts); +var pool = new MemoryPool(new VirtualStack.CreationOpts +{ + reserveCapacity = 1024 * 1024 +}); -var arr = new UnsafeArray(10, Allocator.Persistent); -var arrcpy = arr; +var arr = new UnsafeArray(1000, pool.AllocationHandle); + +Test(in pool); arr.Dispose(); -arrcpy.Dispose(); -Console.WriteLine(arr.IsCreated); -Console.WriteLine(arrcpy.IsCreated); +Console.WriteLine("Done."); -AllocationManager.Dispose(); +void Test(ref readonly MemoryPool pool) +{ + using var arr = new UnsafeArray(1000, pool.AllocationHandle); + if (true) + { + using var arr1 = new UnsafeArray(1000, pool.AllocationHandle); + } + + using var arr3 = Test2(in pool); + using var arr2 = new UnsafeArray(1000, pool.AllocationHandle); +} + +UnsafeArray Test2(ref readonly MemoryPool pool) +{ + using var arr = new UnsafeArray(1000, pool.AllocationHandle); + var arr1 = new UnsafeArray(1000, pool.AllocationHandle); + return arr1; +}