feat(memory): improve oversized alloc handling & cleanup
Enhanced FreeList to handle oversized allocations by bypassing chunk management and allocating directly from the OS, with proper header assignment and immediate release on free. Updated IUnsafeCollection<T> documentation, removed unnecessary array clearing in Clear() methods, refined UnsafeSlotMap initialization logic, and removed redundant default element addition. Bumped assembly version to 1.5.1.
This commit is contained in:
@@ -540,10 +540,15 @@ public unsafe struct FreeList : IDisposable
|
|||||||
ptr = TryPopFromBucket(cache, cacheIndex, bucketIndex);
|
ptr = TryPopFromBucket(cache, cacheIndex, bucketIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (ptr == null)
|
|
||||||
{
|
{
|
||||||
ptr = AllocateFromChunk(cacheIndex, totalSize, alignment);
|
// Oversized block: Bypass chunk linking entirely and go straight to the OS
|
||||||
|
ptr = AlignedAlloc(totalSize, alignment);
|
||||||
|
if (ptr != null)
|
||||||
|
{
|
||||||
|
// Pass null for ownerChunk so 'Free' knows this is a standalone allocation
|
||||||
|
AssignBlockHeader((BlockHeader*)ptr, null, totalSize, cacheIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr == null)
|
if (ptr == null)
|
||||||
@@ -604,10 +609,10 @@ public unsafe struct FreeList : IDisposable
|
|||||||
|
|
||||||
if (bucketIndex < 0)
|
if (bucketIndex < 0)
|
||||||
{
|
{
|
||||||
header->ownerChunk = null;
|
// This is an oversized allocation. It doesn't belong to a bucket or a chunk.
|
||||||
header->blockSize = 0;
|
// Erase the magic number for safety and instantly yield it back to the OS.
|
||||||
header->magicNumber = 0;
|
header->magicNumber = 0;
|
||||||
header->ownerCacheIndex = 0;
|
AlignedFree(blockStartPtr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public interface IUnsafeCollection<T> : IUnsafeCollection, IEnumerable<T>
|
|||||||
where T : unmanaged
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of elements in a collection. The value is read-only.
|
/// Gets the number of elements in a collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int Count
|
int Count
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -467,7 +467,6 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_array.Clear();
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ public unsafe struct UnsafeQueue<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_array.Clear();
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ public unsafe struct UnsafeSlotMap<T> : IUnsafeCollection<T>
|
|||||||
if (!allocationOption.HasFlag(AllocationOption.Clear))
|
if (!allocationOption.HasFlag(AllocationOption.Clear))
|
||||||
{
|
{
|
||||||
_generations.AsSpan().Clear();
|
_generations.AsSpan().Clear();
|
||||||
|
_validBits.ClearAll();
|
||||||
}
|
}
|
||||||
_validBits.ClearAll();
|
|
||||||
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
_capacity = capacity;
|
_capacity = capacity;
|
||||||
@@ -324,8 +324,6 @@ public unsafe struct UnsafeSlotMap<T> : IUnsafeCollection<T>
|
|||||||
_validBits.ClearAll();
|
_validBits.ClearAll();
|
||||||
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
|
|
||||||
Add(default, out _);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly void* GetUnsafePtr()
|
public readonly void* GetUnsafePtr()
|
||||||
|
|||||||
@@ -396,8 +396,6 @@ public unsafe struct UnsafeSparseSet<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
_nextId = 0;
|
_nextId = 0;
|
||||||
|
|
||||||
Add(default, out _);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ public unsafe struct UnsafeStack<T> : IUnsafeCollection<T>
|
|||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
_array.Clear();
|
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>Misaki</Authors>
|
<Authors>Misaki</Authors>
|
||||||
<AssemblyVersion>1.5.0</AssemblyVersion>
|
<AssemblyVersion>1.5.1</AssemblyVersion>
|
||||||
<Version>$(AssemblyVersion)</Version>
|
<Version>$(AssemblyVersion)</Version>
|
||||||
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>
|
||||||
|
|||||||
Reference in New Issue
Block a user