alloc_fixed.Fallback
Internal implementation documentation
Defined in alloc_fixed.
A two-tier allocator that serves small work from bytes the caller already has and lets larger work reach the allocator behind it without the caller choosing between them.
API (4)
Actions
Public operations.
allocator: Returns a borrowedstd.mem.Allocatorhandle pointing atselfto pass to code that allocates.init: Starts aFallbackinstance over a fixed storage buffer the caller supplies and a backing allocator.
Fields and members
Public fields and members.
Source
Source: lib/alloc/fixed/src/fixed.zig:1014
zig
/// A two-tier allocator that serves small work from bytes the caller already/// has and lets larger work reach the allocator behind it without the caller/// choosing between them. It serves a request from `fixed` while the room and/// the alignment fit, and hands the request to `backing` otherwise.////// ### Bounds and provenance routing/// - The `backing` allocator is any allocator the caller chooses, and/// `Fallback` adds no memory bound of its own, so a bounded backing allocator/// bounds the pair./// - The `free` operation asks `fixed.ownsSlice(memory)`, and calls/// `fixed.allocator().rawFree()` for memory the fixed buffer owns and/// `backing.rawFree()` for the rest./// - The `resize` operation tries to grow or shrink in place in the tier that/// owns the memory./// - The `remap` operation on memory that started in `fixed` and cannot be/// resized in place allocates elsewhere, which may spill to `backing`, copies/// the bytes over, and frees the old memory from `fixed`, while memory that/// started in `backing` has its remap handed straight to `backing`.pub const Fallback = struct { /// Primary fixed-buffer storage owner that serves allocation requests /// first. fixed: FixedBuffer, /// Secondary backing allocator that takes requests once the primary fixed /// storage cannot fit them. backing: Allocator, const Self = @This(); /// Starts a `Fallback` instance over a fixed storage buffer the caller /// supplies and a backing allocator. pub fn init(storage_bytes: []u8, backing: Allocator) Self { return .{ .fixed = FixedBuffer.init(storage_bytes), .backing = backing, }; } /// Returns a borrowed `std.mem.Allocator` handle pointing at `self` to pass /// to code that allocates. The `self` instance stays alive at one memory /// address while the handle is in use. pub fn allocator(self: *Self) Allocator { return .{ .ptr = self, .vtable = &vtable }; } fn rawAlloc( context: *anyopaque, len: usize, alignment: Alignment, return_address: usize, ) ?[*]u8 { const self: *Self = @ptrCast(@alignCast(context)); if (fits(&self.fixed, len, alignment)) { return self.fixed.allocator().rawAlloc( len, alignment, return_address, ) orelse unreachable; } return self.backing.rawAlloc( len, alignment, return_address, ); } fn rawResize( context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize, ) bool { const self: *Self = @ptrCast(@alignCast(context)); if (self.fixed.ownsSlice(memory)) { return self.fixed.allocator().rawResize( memory, alignment, new_len, return_address, ); } return self.backing.rawResize( memory, alignment, new_len, return_address, ); } fn rawRemap( context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize, ) ?[*]u8 { const self: *Self = @ptrCast(@alignCast(context)); if (!self.fixed.ownsSlice(memory)) { return self.backing.rawRemap( memory, alignment, new_len, return_address, ); } if (self.fixed.allocator().rawRemap( memory, alignment, new_len, return_address, )) |result| return result; const result = rawAlloc( self, new_len, alignment, return_address, ) orelse return null; @memcpy(result[0..@min(memory.len, new_len)], memory[0..@min(memory.len, new_len)]); self.fixed.allocator().rawFree( memory, alignment, return_address, ); return result; } fn rawFree( context: *anyopaque, memory: []u8, alignment: Alignment, return_address: usize, ) void { const self: *Self = @ptrCast(@alignCast(context)); if (self.fixed.ownsSlice(memory)) { self.fixed.allocator().rawFree( memory, alignment, return_address, ); return; } self.backing.rawFree( memory, alignment, return_address, ); } const vtable: Allocator.VTable = .{ .alloc = rawAlloc, .resize = rawResize, .remap = rawRemap, .free = rawFree, };};Source: lib/alloc/fixed/src/root.zig:414
zig
/// When small work can run on the stack while larger requests spill to the/// heap, `Fallback` tries a fixed storage buffer first and falls back to a/// backing allocator. It adds no memory bound of its own, so the bound is/// whatever the backing allocator imposes. Provenance routing sends every later/// `free`, `resize`, or `remap` to the tier that owns the slice.pub const Fallback = fixed.Fallback;Audit
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 2 |
| Version | 26.7.0 |
| Revision | daab053ee433 |