From 0ec453e62af34dc04526a8f2c29216be4875790b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 01:37:26 +0000 Subject: [PATCH] Update HLSF allocator documentation to reflect v8 behavior Co-authored-by: Nitload-NSI <105042599+Nitload-NSI@users.noreply.github.com> --- .../HighPerformance/Memory/InroductionToHLSF.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md b/StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md index e8a09593..8472fa79 100644 --- a/StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md +++ b/StgSharp.Common/HighPerformance/Memory/InroductionToHLSF.md @@ -6,7 +6,7 @@ A constant-time (O(1)) allocator for real-time, high-throughput scenarios. It us - O(1) allocate/free with 10 levels: 64B x 16MB; each level split into 1x/2x/3x segments - External metadata (`Entry`, `BucketNode`) in dedicated SLABs; user blocks have no headers -- Configurable alignment (>=16B); large block cap per allocation: 32MB +- Configurable alignment (>=16B); maximum block size is configurable at construction time via the `maxBlockSize` parameter (default 32MB, 10 levels). The level array and bucket table are dynamically extended when a larger `maxBlockSize` is specified. There is no implicit fallback to `NativeMemory` for oversized requests. - Single-threaded implementation (external sync required for multi-threaded use) ## Quick Use @@ -23,13 +23,13 @@ hlsf.Free(h); ### Alloc(uint size) - Purpose: Allocate a block of at least `size` bytes. -- Input: `size` in bytes (<= 32MB for internal path; >32MB uses native large allocation). +- Input: `size` in bytes. Must not exceed the `maxBlockSize` configured at construction time (default 32MB). If `size > _maxSize`, an `InvalidOperationException` is thrown. - Output: `HybridLayerSegregatedFitAllocationHandle` with pointer access and `Span`. - Behavior: - Classify into level/segment and pop a matching bucket; escalate segments and levels if empty. - Fallback to overflow bucket or carve 32MB from spare memory if all buckets are empty. - Mark selected `Entry` as Alloc; slice any remainder into `Empty` entries and push to buckets. - - For >32MB requests, use `NativeMemory.AlignedAlloc` and mark `EntryState.Large`. + - There is no implicit fallback to `NativeMemory.AlignedAlloc` for oversized requests — all allocations are served from the pre-allocated arena. The level array and bucket table are dynamically sized based on the `maxBlockSize` parameter. ### Free(HybridLayerSegregatedFitAllocationHandle handle) @@ -90,7 +90,7 @@ Interpretation: HLSF matches libc allocation throughput under the same workload, ## Detailed Design (summary) - -- Size classes: levelSizeArray = [64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216] (64B x 4^level) +- Size classes: The default level size array is [64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216] (10 levels, 64B × 4^level). When `maxBlockSize` is specified at construction and exceeds the default range, additional levels are appended (each 4× the previous) to cover the requested maximum block size. - Segments per level: 1x, 2x, 3x - Buckets: index = 3 * level + segment (overflow bucket for level > 9) - Metadata: Entry (external SLAB, position chain), BucketNode (user region, bucket chain) @@ -143,8 +143,8 @@ Interpretation: HLSF matches libc allocation throughput under the same workload, ### Large Allocations and Spare Memory -- Requests > 32MB use `NativeMemory.AlignedAlloc(size, align)` and mark `State.Large` -- When buckets are empty, `TryAllocateNew32MBBlock` carves a 32MB region from `_spareMemory`, builds an `Empty` entry, and advances the spare pointer +- Requests exceeding the configured `maxBlockSize` are rejected with `InvalidOperationException`. All allocations are served from the pre-allocated arena. +- When all buckets are empty, `TryAllocateNew32MBBlock` carves a region (up to 32MB) from `_spareMemory` to replenish the bucket system, builds an `Empty` entry, and advances the spare pointer ### Alignment