| ... | @@ -162,6 +162,10 @@ pub const Config = struct { | ... | @@ -162,6 +162,10 @@ pub const Config = struct { |
| 162 | | 162 | |
| 163 | /// Tell whether the backing allocator returns already-zeroed memory. | 163 | /// Tell whether the backing allocator returns already-zeroed memory. |
| 164 | backing_allocator_zeroes: bool = true, | 164 | backing_allocator_zeroes: bool = true, |
| | 165 | |
| | 166 | /// Magic value that distinguishes allocations owned by this allocator from |
| | 167 | /// other regions of memory. |
| | 168 | canary: usize = @truncate(0x9232a6ff85dff10f), |
| 165 | }; | 169 | }; |
| 166 | | 170 | |
| 167 | pub const Check = enum { ok, leak }; | 171 | pub const Check = enum { ok, leak }; |
| ... | @@ -266,6 +270,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -266,6 +270,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 266 | allocated_count: SlotIndex, | 270 | allocated_count: SlotIndex, |
| 267 | freed_count: SlotIndex, | 271 | freed_count: SlotIndex, |
| 268 | prev: ?*BucketHeader, | 272 | prev: ?*BucketHeader, |
| | 273 | canary: usize = config.canary, |
| 269 | | 274 | |
| 270 | fn fromPage(page_addr: usize, slot_count: usize) *BucketHeader { | 275 | fn fromPage(page_addr: usize, slot_count: usize) *BucketHeader { |
| 271 | const unaligned = page_addr + page_size - bucketSize(slot_count); | 276 | const unaligned = page_addr + page_size - bucketSize(slot_count); |
| ... | @@ -832,6 +837,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -832,6 +837,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 832 | const freed_addr = @intFromPtr(old_memory.ptr); | 837 | const freed_addr = @intFromPtr(old_memory.ptr); |
| 833 | const page_addr = freed_addr & ~(page_size - 1); | 838 | const page_addr = freed_addr & ~(page_size - 1); |
| 834 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); | 839 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); |
| | 840 | if (bucket.canary != config.canary) @panic("Invalid free"); |
| 835 | const page_offset = freed_addr - page_addr; | 841 | const page_offset = freed_addr - page_addr; |
| 836 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 842 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); |
| 837 | const slot_index: SlotIndex = @intCast(page_offset / size_class); | 843 | const slot_index: SlotIndex = @intCast(page_offset / size_class); |