std.mem.Allocator: allow shrink to fail

closes #13535
This commit is contained in:
Andrew Kelley
2022-11-27 01:07:35 -07:00
parent deda6b5146
commit ceb0a632cf
57 changed files with 950 additions and 1279 deletions

View File

@@ -47,16 +47,23 @@ pub const FailingAllocator = struct {
}
pub fn allocator(self: *FailingAllocator) mem.Allocator {
return mem.Allocator.init(self, alloc, resize, free);
return .{
.ptr = self,
.vtable = &.{
.alloc = alloc,
.resize = resize,
.free = free,
},
};
}
fn alloc(
self: *FailingAllocator,
ctx: *anyopaque,
len: usize,
ptr_align: u29,
len_align: u29,
log2_ptr_align: u8,
return_address: usize,
) error{OutOfMemory}![]u8 {
) ?[*]u8 {
const self = @ptrCast(*FailingAllocator, @alignCast(@alignOf(FailingAllocator), ctx));
if (self.index == self.fail_index) {
if (!self.has_induced_failure) {
mem.set(usize, &self.stack_addresses, 0);
@@ -67,39 +74,42 @@ pub const FailingAllocator = struct {
std.debug.captureStackTrace(return_address, &stack_trace);
self.has_induced_failure = true;
}
return error.OutOfMemory;
return null;
}
const result = try self.internal_allocator.rawAlloc(len, ptr_align, len_align, return_address);
self.allocated_bytes += result.len;
const result = self.internal_allocator.rawAlloc(len, log2_ptr_align, return_address) orelse
return null;
self.allocated_bytes += len;
self.allocations += 1;
self.index += 1;
return result;
}
fn resize(
self: *FailingAllocator,
ctx: *anyopaque,
old_mem: []u8,
old_align: u29,
log2_old_align: u8,
new_len: usize,
len_align: u29,
ra: usize,
) ?usize {
const r = self.internal_allocator.rawResize(old_mem, old_align, new_len, len_align, ra) orelse return null;
if (r < old_mem.len) {
self.freed_bytes += old_mem.len - r;
) bool {
const self = @ptrCast(*FailingAllocator, @alignCast(@alignOf(FailingAllocator), ctx));
if (!self.internal_allocator.rawResize(old_mem, log2_old_align, new_len, ra))
return false;
if (new_len < old_mem.len) {
self.freed_bytes += old_mem.len - new_len;
} else {
self.allocated_bytes += r - old_mem.len;
self.allocated_bytes += new_len - old_mem.len;
}
return r;
return true;
}
fn free(
self: *FailingAllocator,
ctx: *anyopaque,
old_mem: []u8,
old_align: u29,
log2_old_align: u8,
ra: usize,
) void {
self.internal_allocator.rawFree(old_mem, old_align, ra);
const self = @ptrCast(*FailingAllocator, @alignCast(@alignOf(FailingAllocator), ctx));
self.internal_allocator.rawFree(old_mem, log2_old_align, ra);
self.deallocations += 1;
self.freed_bytes += old_mem.len;
}