Slab Allocator
Relevant source files
This document covers the SlabByteAllocator
implementation, which provides byte-granularity memory allocation using the slab allocation algorithm. The slab allocator is designed for efficient allocation and deallocation of fixed-size objects by pre-allocating chunks of memory organized into "slabs."
For information about other byte-level allocators, see Buddy System Allocator and TLSF Allocator. For page-granularity allocation, see Bitmap Page Allocator. For the overall trait architecture that this allocator implements, see Architecture and Design.
Architecture and Design
Trait Implementation Hierarchy
The SlabByteAllocator
implements both core allocator traits defined in the crate's trait system:
flowchart TD BaseAlloc["BaseAllocator"] ByteAlloc["ByteAllocator"] SlabImpl["SlabByteAllocator"] HeapWrapper["slab_allocator::Heap"] BaseInit["init(start, size)"] BaseAdd["add_memory(start, size)"] ByteAllocMethod["alloc(layout)"] ByteDealloc["dealloc(pos, layout)"] ByteStats["total_bytes(), used_bytes(), available_bytes()"] SlabNew["new()"] SlabInner["inner_mut(), inner()"] BaseAlloc --> BaseAdd BaseAlloc --> BaseInit BaseAlloc --> SlabImpl ByteAlloc --> ByteAllocMethod ByteAlloc --> ByteDealloc ByteAlloc --> ByteStats ByteAlloc --> SlabImpl SlabImpl --> HeapWrapper SlabImpl --> SlabInner SlabImpl --> SlabNew
Sources: src/slab.rs(L5 - L68)
External Dependency Integration
The SlabByteAllocator
serves as a wrapper around the external slab_allocator
crate, specifically the Heap
type:
flowchart TD UserCode["User Code"] SlabWrapper["SlabByteAllocator"] InternalHeap["Option"] ExternalCrate["slab_allocator v0.3.1"] TraitMethods["BaseAllocator + ByteAllocator methods"] HeapMethods["Heap::new(), allocate(), deallocate()"] InternalHeap --> ExternalCrate InternalHeap --> HeapMethods SlabWrapper --> InternalHeap SlabWrapper --> TraitMethods UserCode --> SlabWrapper
Sources: src/slab.rs(L8) src/slab.rs(L14)
Implementation Details
Struct Definition and State Management
The SlabByteAllocator
maintains minimal internal state, delegating the actual allocation logic to the wrapped Heap
:
Component | Type | Purpose |
---|---|---|
inner | Option | Wrapped slab allocator instance |
The Option
wrapper allows for lazy initialization through the BaseAllocator::init
method.
Sources: src/slab.rs(L13 - L15)
Construction and Initialization
sequenceDiagram participant User as User participant SlabByteAllocator as SlabByteAllocator participant Heap as Heap User ->> SlabByteAllocator: new() Note over Heap,SlabByteAllocator: inner = None User ->> SlabByteAllocator: init(start, size) SlabByteAllocator ->> Heap: unsafe Heap::new(start, size) Heap -->> SlabByteAllocator: heap instance Note over Heap,SlabByteAllocator: inner = Some(heap)
The allocator follows a two-phase initialization pattern:
new()
creates an uninitialized allocator withinner = None
init(start, size)
creates the underlyingHeap
instance
Sources: src/slab.rs(L18 - L21) src/slab.rs(L33 - L35)
Memory Management Operations
The allocator provides internal accessor methods for safe access to the initialized heap:
flowchart TD AccessMethods["Accessor Methods"] InnerMut["inner_mut() -> &mut Heap"] Inner["inner() -> &Heap"] Unwrap["Option::as_mut().unwrap()"] MutOperations["alloc(), dealloc(), add_memory()"] ReadOperations["total_bytes(), used_bytes(), available_bytes()"] AccessMethods --> Inner AccessMethods --> InnerMut Inner --> ReadOperations Inner --> Unwrap InnerMut --> MutOperations InnerMut --> Unwrap
Sources: src/slab.rs(L23 - L29)
Memory Allocation API
BaseAllocator Implementation
The BaseAllocator
trait provides fundamental memory region management:
Method | Parameters | Behavior |
---|---|---|
init | start: usize, size: usize | Creates newHeapinstance for memory region |
add_memory | start: usize, size: usize | Adds additional memory region to existing heap |
Both methods work with raw memory addresses and sizes in bytes.
Sources: src/slab.rs(L32 - L43)
ByteAllocator Implementation
The ByteAllocator
trait provides fine-grained allocation operations:
flowchart TD ByteAllocator["ByteAllocator Trait"] AllocMethod["alloc(layout: Layout)"] DeallocMethod["dealloc(pos: NonNull, layout: Layout)"] StatsGroup["Memory Statistics"] AllocResult["AllocResult>"] ErrorMap["map_err(|_| AllocError::NoMemory)"] UnsafeDealloc["unsafe deallocate(ptr, layout)"] TotalBytes["total_bytes()"] UsedBytes["used_bytes()"] AvailableBytes["available_bytes()"] AllocMethod --> AllocResult AllocMethod --> ErrorMap ByteAllocator --> AllocMethod ByteAllocator --> DeallocMethod ByteAllocator --> StatsGroup DeallocMethod --> UnsafeDealloc StatsGroup --> AvailableBytes StatsGroup --> TotalBytes StatsGroup --> UsedBytes
Error Handling
The allocation method converts internal allocation failures to the standardized AllocError::NoMemory
variant, providing consistent error semantics across all allocator implementations in the crate.
Sources: src/slab.rs(L45 - L68)
Memory Statistics
The allocator exposes three memory statistics through delegation to the underlying Heap
:
Statistic | Description |
---|---|
total_bytes() | Total memory managed by allocator |
used_bytes() | Currently allocated memory |
available_bytes() | Free memory available for allocation |
Sources: src/slab.rs(L57 - L67)
Slab Allocation Characteristics
The slab allocator is particularly efficient for workloads involving:
- Frequent allocation and deallocation of similar-sized objects
- Scenarios where memory fragmentation needs to be minimized
- Applications requiring predictable allocation performance
The underlying slab_allocator::Heap
implementation handles the complexity of slab management, chunk organization, and free list maintenance, while the wrapper provides integration with the crate's trait system and error handling conventions.