authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-09-25 00:21:57+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-09-25 10:58:07+02:00
logbd9003ed5b16a6e187999fb1190d89eb80bd587b
treef5b125d1f2bf1065223de6526dbba3ae33caf17c
parentbd89bd6fdbcc0ce5ea7763a8043fd46099022b19

std: ArenaAllocator tries to resize before allocating

Closes #5116

2 files changed, 22 insertions(+), 6 deletions(-)

lib/std/heap.zig+7
...@@ -919,6 +919,13 @@ pub fn testAllocator(base_allocator: *mem.Allocator) !void {...@@ -919,6 +919,13 @@ pub fn testAllocator(base_allocator: *mem.Allocator) !void {
919 const zero_bit_ptr = try allocator.create(u0);919 const zero_bit_ptr = try allocator.create(u0);
920 zero_bit_ptr.* = 0;920 zero_bit_ptr.* = 0;
921 allocator.destroy(zero_bit_ptr);921 allocator.destroy(zero_bit_ptr);
922
923 const oversize = try allocator.allocAdvanced(u32, null, 5, .at_least);
924 testing.expect(oversize.len >= 5);
925 for (oversize) |*item| {
926 item.* = 0xDEADBEEF;
927 }
928 allocator.free(oversize);
922}929}
923930
924pub fn testAllocatorAligned(base_allocator: *mem.Allocator, comptime alignment: u29) !void {931pub fn testAllocatorAligned(base_allocator: *mem.Allocator, comptime alignment: u29) !void {
lib/std/heap/arena_allocator.zig+15-6
...@@ -75,13 +75,22 @@ pub const ArenaAllocator = struct {...@@ -75,13 +75,22 @@ pub const ArenaAllocator = struct {
75 const adjusted_addr = mem.alignForward(addr, ptr_align);75 const adjusted_addr = mem.alignForward(addr, ptr_align);
76 const adjusted_index = self.state.end_index + (adjusted_addr - addr);76 const adjusted_index = self.state.end_index + (adjusted_addr - addr);
77 const new_end_index = adjusted_index + n;77 const new_end_index = adjusted_index + n;
78 if (new_end_index > cur_buf.len) {78
79 cur_node = try self.createNode(cur_buf.len, n + ptr_align);79 if (new_end_index <= cur_buf.len) {
80 continue;80 const result = cur_buf[adjusted_index..new_end_index];
81 self.state.end_index = new_end_index;
82 return result;
81 }83 }
82 const result = cur_buf[adjusted_index..new_end_index];84
83 self.state.end_index = new_end_index;85 const bigger_buf_size = @sizeOf(BufNode) + new_end_index;
84 return result;86 // Try to grow the buffer in-place
87 cur_node.data = self.child_allocator.resize(cur_node.data, bigger_buf_size) catch |err| switch (err) {
88 error.OutOfMemory => {
89 // Allocate a new node if that's not possible
90 cur_node = try self.createNode(cur_buf.len, n + ptr_align);
91 continue;
92 },
93 };
85 }94 }
86 }95 }
8796