| ... | @@ -521,10 +521,16 @@ pub fn StackFallbackAllocator(comptime size: usize) type { | ... | @@ -521,10 +521,16 @@ pub fn StackFallbackAllocator(comptime size: usize) type { |
| 521 | buffer: [size]u8, | 521 | buffer: [size]u8, |
| 522 | fallback_allocator: Allocator, | 522 | fallback_allocator: Allocator, |
| 523 | fixed_buffer_allocator: FixedBufferAllocator, | 523 | fixed_buffer_allocator: FixedBufferAllocator, |
| | 524 | get_called: if (std.debug.runtime_safety) bool else void = |
| | 525 | if (std.debug.runtime_safety) false else {}, |
| 524 | | 526 | |
| 525 | /// This function both fetches a `Allocator` interface to this | 527 | /// This function both fetches a `Allocator` interface to this |
| 526 | /// allocator *and* resets the internal buffer allocator. | 528 | /// allocator *and* resets the internal buffer allocator. |
| 527 | pub fn get(self: *Self) Allocator { | 529 | pub fn get(self: *Self) Allocator { |
| | 530 | if (std.debug.runtime_safety) { |
| | 531 | assert(!self.get_called); // `get` called multiple times; instead use `const allocator = stackFallback(N).get();` |
| | 532 | self.get_called = true; |
| | 533 | } |
| 528 | self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]); | 534 | self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]); |
| 529 | return .{ | 535 | return .{ |
| 530 | .ptr = self, | 536 | .ptr = self, |
| ... | @@ -536,6 +542,12 @@ pub fn StackFallbackAllocator(comptime size: usize) type { | ... | @@ -536,6 +542,12 @@ pub fn StackFallbackAllocator(comptime size: usize) type { |
| 536 | }; | 542 | }; |
| 537 | } | 543 | } |
| 538 | | 544 | |
| | 545 | /// Unlike most std allocators `StackFallbackAllocator` modifies |
| | 546 | /// its internal state before returning an implementation of |
| | 547 | /// the`Allocator` interface and therefore also doesn't use |
| | 548 | /// the usual `.allocator()` method. |
| | 549 | pub const allocator = @compileError("use 'const allocator = stackFallback(N).get();' instead"); |
| | 550 | |
| 539 | fn alloc( | 551 | fn alloc( |
| 540 | ctx: *anyopaque, | 552 | ctx: *anyopaque, |
| 541 | len: usize, | 553 | len: usize, |
| ... | @@ -675,13 +687,22 @@ test "FixedBufferAllocator.reset" { | ... | @@ -675,13 +687,22 @@ test "FixedBufferAllocator.reset" { |
| 675 | } | 687 | } |
| 676 | | 688 | |
| 677 | test "StackFallbackAllocator" { | 689 | test "StackFallbackAllocator" { |
| 678 | const fallback_allocator = page_allocator; | 690 | { |
| 679 | var stack_allocator = stackFallback(4096, fallback_allocator); | 691 | var stack_allocator = stackFallback(4096, std.testing.allocator); |
| 680 | | 692 | try testAllocator(stack_allocator.get()); |
| 681 | try testAllocator(stack_allocator.get()); | 693 | } |
| 682 | try testAllocatorAligned(stack_allocator.get()); | 694 | { |
| 683 | try testAllocatorLargeAlignment(stack_allocator.get()); | 695 | var stack_allocator = stackFallback(4096, std.testing.allocator); |
| 684 | try testAllocatorAlignedShrink(stack_allocator.get()); | 696 | try testAllocatorAligned(stack_allocator.get()); |
| | 697 | } |
| | 698 | { |
| | 699 | var stack_allocator = stackFallback(4096, std.testing.allocator); |
| | 700 | try testAllocatorLargeAlignment(stack_allocator.get()); |
| | 701 | } |
| | 702 | { |
| | 703 | var stack_allocator = stackFallback(4096, std.testing.allocator); |
| | 704 | try testAllocatorAlignedShrink(stack_allocator.get()); |
| | 705 | } |
| 685 | } | 706 | } |
| 686 | | 707 | |
| 687 | test "FixedBufferAllocator Reuse memory on realloc" { | 708 | test "FixedBufferAllocator Reuse memory on realloc" { |