authorgravatar for leecannon@leecannon.xyzLee Cannon <leecannon@leecannon.xyz> 2021-11-07 01:40:06+00:00
committergravatar for leecannon@leecannon.xyzLee Cannon <leecannon@leecannon.xyz> 2021-11-30 23:45:01+00:00
log066eaa5e9cbfde172449f6d95bb884c7d86ac10c
tree7829767fd8b421f6a1c58798692f45ebec43746d
parentf68cda738ad0d3e9bc0f328befad301d9e23756e
signaturelock-open Commit is signed but in an unrecognized format.

allocgate: change resize to return optional instead of error


15 files changed, 112 insertions(+), 196 deletions(-)

lib/std/build/OptionsStep.zig+1-1
...@@ -350,5 +350,5 @@ test "OptionsStep" {...@@ -350,5 +350,5 @@ test "OptionsStep" {
350 \\350 \\
351 , options.contents.items);351 , options.contents.items);
352352
353 _ = try std.zig.parse(&arena.allocator, try options.contents.toOwnedSliceSentinel(0));353 _ = try std.zig.parse(arena.allocator(), try options.contents.toOwnedSliceSentinel(0));
354}354}
lib/std/heap.zig+16-18
...@@ -129,7 +129,7 @@ const CAllocator = struct {...@@ -129,7 +129,7 @@ const CAllocator = struct {
129 new_len: usize,129 new_len: usize,
130 len_align: u29,130 len_align: u29,
131 return_address: usize,131 return_address: usize,
132 ) Allocator.Error!usize {132 ) ?usize {
133 _ = buf_align;133 _ = buf_align;
134 _ = return_address;134 _ = return_address;
135 if (new_len <= buf.len) {135 if (new_len <= buf.len) {
...@@ -141,7 +141,7 @@ const CAllocator = struct {...@@ -141,7 +141,7 @@ const CAllocator = struct {
141 return mem.alignAllocLen(full_len, new_len, len_align);141 return mem.alignAllocLen(full_len, new_len, len_align);
142 }142 }
143 }143 }
144 return error.OutOfMemory;144 return null;
145 }145 }
146146
147 fn free(147 fn free(
...@@ -205,13 +205,13 @@ fn rawCResize(...@@ -205,13 +205,13 @@ fn rawCResize(
205 new_len: usize,205 new_len: usize,
206 len_align: u29,206 len_align: u29,
207 ret_addr: usize,207 ret_addr: usize,
208) Allocator.Error!usize {208) ?usize {
209 _ = old_align;209 _ = old_align;
210 _ = ret_addr;210 _ = ret_addr;
211 if (new_len <= buf.len) {211 if (new_len <= buf.len) {
212 return mem.alignAllocLen(buf.len, new_len, len_align);212 return mem.alignAllocLen(buf.len, new_len, len_align);
213 }213 }
214 return error.OutOfMemory;214 return null;
215}215}
216216
217fn rawCFree(217fn rawCFree(
...@@ -361,7 +361,7 @@ const PageAllocator = struct {...@@ -361,7 +361,7 @@ const PageAllocator = struct {
361 new_size: usize,361 new_size: usize,
362 len_align: u29,362 len_align: u29,
363 return_address: usize,363 return_address: usize,
364 ) Allocator.Error!usize {364 ) ?usize {
365 _ = buf_align;365 _ = buf_align;
366 _ = return_address;366 _ = return_address;
367 const new_size_aligned = mem.alignForward(new_size, mem.page_size);367 const new_size_aligned = mem.alignForward(new_size, mem.page_size);
...@@ -387,7 +387,7 @@ const PageAllocator = struct {...@@ -387,7 +387,7 @@ const PageAllocator = struct {
387 if (new_size_aligned <= old_size_aligned) {387 if (new_size_aligned <= old_size_aligned) {
388 return alignPageAllocLen(new_size_aligned, new_size, len_align);388 return alignPageAllocLen(new_size_aligned, new_size, len_align);
389 }389 }
390 return error.OutOfMemory;390 return null;
391 }391 }
392392
393 const buf_aligned_len = mem.alignForward(buf_unaligned.len, mem.page_size);393 const buf_aligned_len = mem.alignForward(buf_unaligned.len, mem.page_size);
...@@ -403,7 +403,7 @@ const PageAllocator = struct {...@@ -403,7 +403,7 @@ const PageAllocator = struct {
403403
404 // TODO: call mremap404 // TODO: call mremap
405 // TODO: if the next_mmap_addr_hint is within the remapped range, update it405 // TODO: if the next_mmap_addr_hint is within the remapped range, update it
406 return error.OutOfMemory;406 return null;
407 }407 }
408408
409 fn free(_: *c_void, buf_unaligned: []u8, buf_align: u29, return_address: usize) void {409 fn free(_: *c_void, buf_unaligned: []u8, buf_align: u29, return_address: usize) void {
...@@ -579,11 +579,11 @@ const WasmPageAllocator = struct {...@@ -579,11 +579,11 @@ const WasmPageAllocator = struct {
579 new_len: usize,579 new_len: usize,
580 len_align: u29,580 len_align: u29,
581 return_address: usize,581 return_address: usize,
582 ) error{OutOfMemory}!usize {582 ) ?usize {
583 _ = buf_align;583 _ = buf_align;
584 _ = return_address;584 _ = return_address;
585 const aligned_len = mem.alignForward(buf.len, mem.page_size);585 const aligned_len = mem.alignForward(buf.len, mem.page_size);
586 if (new_len > aligned_len) return error.OutOfMemory;586 if (new_len > aligned_len) return null;
587 const current_n = nPages(aligned_len);587 const current_n = nPages(aligned_len);
588 const new_n = nPages(new_len);588 const new_n = nPages(new_len);
589 if (new_n != current_n) {589 if (new_n != current_n) {
...@@ -674,7 +674,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -674,7 +674,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
674 new_size: usize,674 new_size: usize,
675 len_align: u29,675 len_align: u29,
676 return_address: usize,676 return_address: usize,
677 ) error{OutOfMemory}!usize {677 ) ?usize {
678 _ = buf_align;678 _ = buf_align;
679 _ = return_address;679 _ = return_address;
680680
...@@ -686,7 +686,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {...@@ -686,7 +686,7 @@ pub const HeapAllocator = switch (builtin.os.tag) {
686 os.windows.HEAP_REALLOC_IN_PLACE_ONLY,686 os.windows.HEAP_REALLOC_IN_PLACE_ONLY,
687 @intToPtr(*c_void, root_addr),687 @intToPtr(*c_void, root_addr),
688 amt,688 amt,
689 ) orelse return error.OutOfMemory;689 ) orelse return null;
690 assert(new_ptr == @intToPtr(*c_void, root_addr));690 assert(new_ptr == @intToPtr(*c_void, root_addr));
691 const return_len = init: {691 const return_len = init: {
692 if (len_align == 0) break :init new_size;692 if (len_align == 0) break :init new_size;
...@@ -788,14 +788,13 @@ pub const FixedBufferAllocator = struct {...@@ -788,14 +788,13 @@ pub const FixedBufferAllocator = struct {
788 new_size: usize,788 new_size: usize,
789 len_align: u29,789 len_align: u29,
790 return_address: usize,790 return_address: usize,
791 ) Allocator.Error!usize {791 ) ?usize {
792 _ = buf_align;792 _ = buf_align;
793 _ = return_address;793 _ = return_address;
794 assert(self.ownsSlice(buf)); // sanity check794 assert(self.ownsSlice(buf)); // sanity check
795795
796 if (!self.isLastAllocation(buf)) {796 if (!self.isLastAllocation(buf)) {
797 if (new_size > buf.len)797 if (new_size > buf.len) return null;
798 return error.OutOfMemory;
799 return mem.alignAllocLen(buf.len, new_size, len_align);798 return mem.alignAllocLen(buf.len, new_size, len_align);
800 }799 }
801800
...@@ -806,9 +805,8 @@ pub const FixedBufferAllocator = struct {...@@ -806,9 +805,8 @@ pub const FixedBufferAllocator = struct {
806 }805 }
807806
808 const add = new_size - buf.len;807 const add = new_size - buf.len;
809 if (add + self.end_index > self.buffer.len) {808 if (add + self.end_index > self.buffer.len) return null;
810 return error.OutOfMemory;809
811 }
812 self.end_index += add;810 self.end_index += add;
813 return new_size;811 return new_size;
814 }812 }
...@@ -891,7 +889,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type {...@@ -891,7 +889,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type {
891 new_len: usize,889 new_len: usize,
892 len_align: u29,890 len_align: u29,
893 return_address: usize,891 return_address: usize,
894 ) error{OutOfMemory}!usize {892 ) ?usize {
895 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {893 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
896 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, buf_align, new_len, len_align, return_address);894 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, buf_align, new_len, len_align, return_address);
897 } else {895 } else {
lib/std/heap/arena_allocator.zig+8-11
...@@ -78,26 +78,23 @@ pub const ArenaAllocator = struct {...@@ -78,26 +78,23 @@ pub const ArenaAllocator = struct {
7878
79 const bigger_buf_size = @sizeOf(BufNode) + new_end_index;79 const bigger_buf_size = @sizeOf(BufNode) + new_end_index;
80 // Try to grow the buffer in-place80 // Try to grow the buffer in-place
81 cur_node.data = self.child_allocator.resize(cur_node.data, bigger_buf_size) catch |err| switch (err) {81 cur_node.data = self.child_allocator.resize(cur_node.data, bigger_buf_size) orelse {
82 error.OutOfMemory => {82 // Allocate a new node if that's not possible
83 // Allocate a new node if that's not possible83 cur_node = try self.createNode(cur_buf.len, n + ptr_align);
84 cur_node = try self.createNode(cur_buf.len, n + ptr_align);84 continue;
85 continue;
86 },
87 };85 };
88 }86 }
89 }87 }
9088
91 fn resize(self: *ArenaAllocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Allocator.Error!usize {89 fn resize(self: *ArenaAllocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
92 _ = buf_align;90 _ = buf_align;
93 _ = len_align;91 _ = len_align;
94 _ = ret_addr;92 _ = ret_addr;
9593
96 const cur_node = self.state.buffer_list.first orelse return error.OutOfMemory;94 const cur_node = self.state.buffer_list.first orelse return null;
97 const cur_buf = cur_node.data[@sizeOf(BufNode)..];95 const cur_buf = cur_node.data[@sizeOf(BufNode)..];
98 if (@ptrToInt(cur_buf.ptr) + self.state.end_index != @ptrToInt(buf.ptr) + buf.len) {96 if (@ptrToInt(cur_buf.ptr) + self.state.end_index != @ptrToInt(buf.ptr) + buf.len) {
99 if (new_len > buf.len)97 if (new_len > buf.len) return null;
100 return error.OutOfMemory;
101 return new_len;98 return new_len;
102 }99 }
103100
...@@ -108,7 +105,7 @@ pub const ArenaAllocator = struct {...@@ -108,7 +105,7 @@ pub const ArenaAllocator = struct {
108 self.state.end_index += new_len - buf.len;105 self.state.end_index += new_len - buf.len;
109 return new_len;106 return new_len;
110 } else {107 } else {
111 return error.OutOfMemory;108 return null;
112 }109 }
113 }110 }
114111
lib/std/heap/general_purpose_allocator.zig+10-10
...@@ -517,7 +517,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -517,7 +517,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
517 new_size: usize,517 new_size: usize,
518 len_align: u29,518 len_align: u29,
519 ret_addr: usize,519 ret_addr: usize,
520 ) Error!usize {520 ) ?usize {
521 const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse {521 const entry = self.large_allocations.getEntry(@ptrToInt(old_mem.ptr)) orelse {
522 if (config.safety) {522 if (config.safety) {
523 @panic("Invalid free");523 @panic("Invalid free");
...@@ -557,7 +557,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -557,7 +557,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
557 if (config.enable_memory_limit) {557 if (config.enable_memory_limit) {
558 const new_req_bytes = prev_req_bytes + new_size - entry.value_ptr.requested_size;558 const new_req_bytes = prev_req_bytes + new_size - entry.value_ptr.requested_size;
559 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {559 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {
560 return error.OutOfMemory;560 return null;
561 }561 }
562 self.total_requested_bytes = new_req_bytes;562 self.total_requested_bytes = new_req_bytes;
563 }563 }
...@@ -565,7 +565,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -565,7 +565,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
565 self.total_requested_bytes = prev_req_bytes;565 self.total_requested_bytes = prev_req_bytes;
566 };566 };
567567
568 const result_len = try self.backing_allocator.rawResize(old_mem, old_align, new_size, len_align, ret_addr);568 const result_len = self.backing_allocator.rawResize(old_mem, old_align, new_size, len_align, ret_addr) orelse return null;
569569
570 if (config.enable_memory_limit) {570 if (config.enable_memory_limit) {
571 entry.value_ptr.requested_size = new_size;571 entry.value_ptr.requested_size = new_size;
...@@ -650,7 +650,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -650,7 +650,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
650 new_size: usize,650 new_size: usize,
651 len_align: u29,651 len_align: u29,
652 ret_addr: usize,652 ret_addr: usize,
653 ) Error!usize {653 ) ?usize {
654 self.mutex.lock();654 self.mutex.lock();
655 defer self.mutex.unlock();655 defer self.mutex.unlock();
656656
...@@ -705,7 +705,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -705,7 +705,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
705 if (config.enable_memory_limit) {705 if (config.enable_memory_limit) {
706 const new_req_bytes = prev_req_bytes + new_size - old_mem.len;706 const new_req_bytes = prev_req_bytes + new_size - old_mem.len;
707 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {707 if (new_req_bytes > prev_req_bytes and new_req_bytes > self.requested_memory_limit) {
708 return error.OutOfMemory;708 return null;
709 }709 }
710 self.total_requested_bytes = new_req_bytes;710 self.total_requested_bytes = new_req_bytes;
711 }711 }
...@@ -726,7 +726,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -726,7 +726,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
726 }726 }
727 return new_size;727 return new_size;
728 }728 }
729 return error.OutOfMemory;729 return null;
730 }730 }
731731
732 fn free(732 fn free(
...@@ -735,8 +735,8 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -735,8 +735,8 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
735 old_align: u29,735 old_align: u29,
736 ret_addr: usize,736 ret_addr: usize,
737 ) void {737 ) void {
738 const held = self.mutex.acquire();738 self.mutex.lock();
739 defer held.release();739 defer self.mutex.unlock();
740740
741 assert(old_mem.len != 0);741 assert(old_mem.len != 0);
742742
...@@ -850,7 +850,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {...@@ -850,7 +850,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
850 return true;850 return true;
851 }851 }
852852
853 fn alloc(self: Allocator, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {853 fn alloc(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8 {
854 self.mutex.lock();854 self.mutex.lock();
855 defer self.mutex.unlock();855 defer self.mutex.unlock();
856856
...@@ -1065,7 +1065,7 @@ test "shrink large object to large object" {...@@ -1065,7 +1065,7 @@ test "shrink large object to large object" {
1065 slice[0] = 0x12;1065 slice[0] = 0x12;
1066 slice[60] = 0x34;1066 slice[60] = 0x34;
10671067
1068 slice = try allocator.resize(slice, page_size * 2 + 1);1068 slice = allocator.resize(slice, page_size * 2 + 1) orelse return;
1069 try std.testing.expect(slice[0] == 0x12);1069 try std.testing.expect(slice[0] == 0x12);
1070 try std.testing.expect(slice[60] == 0x34);1070 try std.testing.expect(slice[60] == 0x34);
10711071
lib/std/heap/log_to_writer_allocator.zig+7-6
...@@ -45,22 +45,23 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {...@@ -45,22 +45,23 @@ pub fn LogToWriterAllocator(comptime Writer: type) type {
45 new_len: usize,45 new_len: usize,
46 len_align: u29,46 len_align: u29,
47 ra: usize,47 ra: usize,
48 ) error{OutOfMemory}!usize {48 ) ?usize {
49 if (new_len <= buf.len) {49 if (new_len <= buf.len) {
50 self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {};50 self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {};
51 } else {51 } else {
52 self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {};52 self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {};
53 }53 }
54
54 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {55 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {
55 if (new_len > buf.len) {56 if (new_len > buf.len) {
56 self.writer.print(" success!\n", .{}) catch {};57 self.writer.print(" success!\n", .{}) catch {};
57 }58 }
58 return resized_len;59 return resized_len;
59 } else |e| {
60 std.debug.assert(new_len > buf.len);
61 self.writer.print(" failure!\n", .{}) catch {};
62 return e;
63 }60 }
61
62 std.debug.assert(new_len > buf.len);
63 self.writer.print(" failure!\n", .{}) catch {};
64 return null;
64 }65 }
6566
66 fn free(67 fn free(
...@@ -95,7 +96,7 @@ test "LogToWriterAllocator" {...@@ -95,7 +96,7 @@ test "LogToWriterAllocator" {
95 var a = try allocator.alloc(u8, 10);96 var a = try allocator.alloc(u8, 10);
96 a = allocator.shrink(a, 5);97 a = allocator.shrink(a, 5);
97 try std.testing.expect(a.len == 5);98 try std.testing.expect(a.len == 5);
98 try std.testing.expectError(error.OutOfMemory, allocator.resize(a, 20));99 try std.testing.expect(allocator.resize(a, 20) == null);
99 allocator.free(a);100 allocator.free(a);
100101
101 try std.testing.expectEqualSlices(u8,102 try std.testing.expectEqualSlices(u8,
lib/std/heap/logging_allocator.zig+9-9
...@@ -77,7 +77,7 @@ pub fn ScopedLoggingAllocator(...@@ -77,7 +77,7 @@ pub fn ScopedLoggingAllocator(
77 new_len: usize,77 new_len: usize,
78 len_align: u29,78 len_align: u29,
79 ra: usize,79 ra: usize,
80 ) error{OutOfMemory}!usize {80 ) ?usize {
81 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {81 if (self.parent_allocator.rawResize(buf, buf_align, new_len, len_align, ra)) |resized_len| {
82 if (new_len <= buf.len) {82 if (new_len <= buf.len) {
83 logHelper(83 logHelper(
...@@ -94,15 +94,15 @@ pub fn ScopedLoggingAllocator(...@@ -94,15 +94,15 @@ pub fn ScopedLoggingAllocator(
94 }94 }
9595
96 return resized_len;96 return resized_len;
97 } else |err| {
98 std.debug.assert(new_len > buf.len);
99 logHelper(
100 failure_log_level,
101 "expand - failure: {s} - {} to {}, len_align: {}, buf_align: {}",
102 .{ @errorName(err), buf.len, new_len, len_align, buf_align },
103 );
104 return err;
105 }97 }
98
99 std.debug.assert(new_len > buf.len);
100 logHelper(
101 failure_log_level,
102 "expand - failure - {} to {}, len_align: {}, buf_align: {}",
103 .{ buf.len, new_len, len_align, buf_align },
104 );
105 return null;
106 }106 }
107107
108 fn free(108 fn free(
lib/std/mem.zig+4-4
...@@ -88,14 +88,14 @@ pub fn ValidationAllocator(comptime T: type) type {...@@ -88,14 +88,14 @@ pub fn ValidationAllocator(comptime T: type) type {
88 new_len: usize,88 new_len: usize,
89 len_align: u29,89 len_align: u29,
90 ret_addr: usize,90 ret_addr: usize,
91 ) Allocator.Error!usize {91 ) ?usize {
92 assert(buf.len > 0);92 assert(buf.len > 0);
93 if (len_align != 0) {93 if (len_align != 0) {
94 assert(mem.isAlignedAnyAlign(new_len, len_align));94 assert(mem.isAlignedAnyAlign(new_len, len_align));
95 assert(new_len >= len_align);95 assert(new_len >= len_align);
96 }96 }
97 const underlying = self.getUnderlyingAllocatorPtr();97 const underlying = self.getUnderlyingAllocatorPtr();
98 const result = try underlying.rawResize(buf, buf_align, new_len, len_align, ret_addr);98 const result = underlying.rawResize(buf, buf_align, new_len, len_align, ret_addr) orelse return null;
99 if (len_align == 0) {99 if (len_align == 0) {
100 assert(result == new_len);100 assert(result == new_len);
101 } else {101 } else {
...@@ -188,7 +188,7 @@ test "Allocator.resize" {...@@ -188,7 +188,7 @@ test "Allocator.resize" {
188 defer testing.allocator.free(values);188 defer testing.allocator.free(values);
189189
190 for (values) |*v, i| v.* = @intCast(T, i);190 for (values) |*v, i| v.* = @intCast(T, i);
191 values = try testing.allocator.resize(values, values.len + 10);191 values = testing.allocator.resize(values, values.len + 10) orelse return error.OutOfMemory;
192 try testing.expect(values.len == 110);192 try testing.expect(values.len == 110);
193 }193 }
194194
...@@ -203,7 +203,7 @@ test "Allocator.resize" {...@@ -203,7 +203,7 @@ test "Allocator.resize" {
203 defer testing.allocator.free(values);203 defer testing.allocator.free(values);
204204
205 for (values) |*v, i| v.* = @intToFloat(T, i);205 for (values) |*v, i| v.* = @intToFloat(T, i);
206 values = try testing.allocator.resize(values, values.len + 10);206 values = testing.allocator.resize(values, values.len + 10) orelse return error.OutOfMemory;
207 try testing.expect(values.len == 110);207 try testing.expect(values.len == 110);
208 }208 }
209}209}
lib/std/mem/Allocator.zig+38-110
...@@ -29,9 +29,9 @@ pub const VTable = struct {...@@ -29,9 +29,9 @@ pub const VTable = struct {
29 /// length returned by `alloc` or `resize`. `buf_align` must equal the same value29 /// length returned by `alloc` or `resize`. `buf_align` must equal the same value
30 /// that was passed as the `ptr_align` parameter to the original `alloc` call.30 /// that was passed as the `ptr_align` parameter to the original `alloc` call.
31 ///31 ///
32 /// error.OutOfMemory can only be returned if `new_len` is greater than `buf.len`.32 /// `null` can only be returned if `new_len` is greater than `buf.len`.
33 /// If `buf` cannot be expanded to accomodate `new_len`, then the allocation MUST be33 /// If `buf` cannot be expanded to accomodate `new_len`, then the allocation MUST be
34 /// unmodified and error.OutOfMemory MUST be returned.34 /// unmodified and `null` MUST be returned.
35 ///35 ///
36 /// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,36 /// If `len_align` is `0`, then the length returned MUST be exactly `len` bytes,
37 /// otherwise, the length must be aligned to `len_align`. Note that `len_align` does *not*37 /// otherwise, the length must be aligned to `len_align`. Note that `len_align` does *not*
...@@ -42,7 +42,7 @@ pub const VTable = struct {...@@ -42,7 +42,7 @@ pub const VTable = struct {
42 ///42 ///
43 /// `ret_addr` is optionally provided as the first return address of the allocation call stack.43 /// `ret_addr` is optionally provided as the first return address of the allocation call stack.
44 /// If the value is `0` it means no return address has been provided.44 /// If the value is `0` it means no return address has been provided.
45 resize: fn (ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Error!usize,45 resize: fn (ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize,
4646
47 /// Free and invalidate a buffer. `buf.len` must equal the most recent length returned by `alloc` or `resize`. 47 /// Free and invalidate a buffer. `buf.len` must equal the most recent length returned by `alloc` or `resize`.
48 /// `buf_align` must equal the same value that was passed as the `ptr_align` parameter to the original `alloc` call.48 /// `buf_align` must equal the same value that was passed as the `ptr_align` parameter to the original `alloc` call.
...@@ -55,7 +55,7 @@ pub const VTable = struct {...@@ -55,7 +55,7 @@ pub const VTable = struct {
55pub fn init(55pub fn init(
56 pointer: anytype,56 pointer: anytype,
57 comptime allocFn: fn (ptr: @TypeOf(pointer), len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8,57 comptime allocFn: fn (ptr: @TypeOf(pointer), len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) Error![]u8,
58 comptime resizeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Error!usize,58 comptime resizeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize,
59 comptime freeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, ret_addr: usize) void,59 comptime freeFn: fn (ptr: @TypeOf(pointer), buf: []u8, buf_align: u29, ret_addr: usize) void,
60) Allocator {60) Allocator {
61 const Ptr = @TypeOf(pointer);61 const Ptr = @TypeOf(pointer);
...@@ -71,7 +71,7 @@ pub fn init(...@@ -71,7 +71,7 @@ pub fn init(
71 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));71 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
72 return @call(.{ .modifier = .always_inline }, allocFn, .{ self, len, ptr_align, len_align, ret_addr });72 return @call(.{ .modifier = .always_inline }, allocFn, .{ self, len, ptr_align, len_align, ret_addr });
73 }73 }
74 fn resize(ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Error!usize {74 fn resize(ptr: *c_void, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
75 assert(new_len != 0);75 assert(new_len != 0);
76 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));76 const self = @ptrCast(Ptr, @alignCast(alignment, ptr));
77 return @call(.{ .modifier = .always_inline }, resizeFn, .{ self, buf, buf_align, new_len, len_align, ret_addr });77 return @call(.{ .modifier = .always_inline }, resizeFn, .{ self, buf, buf_align, new_len, len_align, ret_addr });
...@@ -104,14 +104,12 @@ pub fn NoResize(comptime AllocatorType: type) type {...@@ -104,14 +104,12 @@ pub fn NoResize(comptime AllocatorType: type) type {
104 new_len: usize,104 new_len: usize,
105 len_align: u29,105 len_align: u29,
106 ret_addr: usize,106 ret_addr: usize,
107 ) Error!usize {107 ) ?usize {
108 _ = self;108 _ = self;
109 _ = buf_align;109 _ = buf_align;
110 _ = len_align;110 _ = len_align;
111 _ = ret_addr;111 _ = ret_addr;
112 if (new_len > buf.len)112 return if (new_len > buf.len) null else new_len;
113 return error.OutOfMemory;
114 return new_len;
115 }113 }
116 };114 };
117}115}
...@@ -157,7 +155,7 @@ pub inline fn rawAlloc(self: Allocator, len: usize, ptr_align: u29, len_align: u...@@ -157,7 +155,7 @@ pub inline fn rawAlloc(self: Allocator, len: usize, ptr_align: u29, len_align: u
157}155}
158156
159/// This function is not intended to be called except from within the implementation of an Allocator157/// This function is not intended to be called except from within the implementation of an Allocator
160pub inline fn rawResize(self: Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) Error!usize {158pub inline fn rawResize(self: Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, ret_addr: usize) ?usize {
161 return self.vtable.resize(self.ptr, buf, buf_align, new_len, len_align, ret_addr);159 return self.vtable.resize(self.ptr, buf, buf_align, new_len, len_align, ret_addr);
162}160}
163161
...@@ -166,99 +164,6 @@ pub inline fn rawFree(self: Allocator, buf: []u8, buf_align: u29, ret_addr: usiz...@@ -166,99 +164,6 @@ pub inline fn rawFree(self: Allocator, buf: []u8, buf_align: u29, ret_addr: usiz
166 return self.vtable.free(self.ptr, buf, buf_align, ret_addr);164 return self.vtable.free(self.ptr, buf, buf_align, ret_addr);
167}165}
168166
169/// Realloc is used to modify the size or alignment of an existing allocation,
170/// as well as to provide the allocator with an opportunity to move an allocation
171/// to a better location.
172/// When the size/alignment is greater than the previous allocation, this function
173/// returns `error.OutOfMemory` when the requested new allocation could not be granted.
174/// When the size/alignment is less than or equal to the previous allocation,
175/// this function returns `error.OutOfMemory` when the allocator decides the client
176/// would be better off keeping the extra alignment/size. Clients will call
177/// `vtable.resize` when they require the allocator to track a new alignment/size,
178/// and so this function should only return success when the allocator considers
179/// the reallocation desirable from the allocator's perspective.
180/// As an example, `std.ArrayList` tracks a "capacity", and therefore can handle
181/// reallocation failure, even when `new_n` <= `old_mem.len`. A `FixedBufferAllocator`
182/// would always return `error.OutOfMemory` for `reallocFn` when the size/alignment
183/// is less than or equal to the old allocation, because it cannot reclaim the memory,
184/// and thus the `std.ArrayList` would be better off retaining its capacity.
185/// When `reallocFn` returns,
186/// `return_value[0..min(old_mem.len, new_byte_count)]` must be the same
187/// as `old_mem` was when `reallocFn` is called. The bytes of
188/// `return_value[old_mem.len..]` have undefined values.
189/// The returned slice must have its pointer aligned at least to `new_alignment` bytes.
190fn reallocBytes(
191 self: Allocator,
192 /// Guaranteed to be the same as what was returned from most recent call to
193 /// `vtable.alloc` or `vtable.resize`.
194 /// If `old_mem.len == 0` then this is a new allocation and `new_byte_count`
195 /// is guaranteed to be >= 1.
196 old_mem: []u8,
197 /// If `old_mem.len == 0` then this is `undefined`, otherwise:
198 /// Guaranteed to be the same as what was passed to `allocFn`.
199 /// Guaranteed to be >= 1.
200 /// Guaranteed to be a power of 2.
201 old_alignment: u29,
202 /// `new_byte_count` must be greater than zero
203 new_byte_count: usize,
204 /// Guaranteed to be >= 1.
205 /// Guaranteed to be a power of 2.
206 /// Returned slice's pointer must have this alignment.
207 new_alignment: u29,
208 /// 0 indicates the length of the slice returned MUST match `new_byte_count` exactly
209 /// non-zero means the length of the returned slice must be aligned by `len_align`
210 /// `new_len` must be aligned by `len_align`
211 len_align: u29,
212 return_address: usize,
213) Error![]u8 {
214 if (old_mem.len == 0) {
215 const new_mem = try self.rawAlloc(new_byte_count, new_alignment, len_align, return_address);
216 // TODO: https://github.com/ziglang/zig/issues/4298
217 @memset(new_mem.ptr, undefined, new_byte_count);
218 return new_mem;
219 }
220
221 assert(new_byte_count > 0); // `new_byte_count` must greater than zero, this is a resize not a free
222
223 if (mem.isAligned(@ptrToInt(old_mem.ptr), new_alignment)) {
224 if (new_byte_count <= old_mem.len) {
225 const shrunk_len = self.shrinkBytes(old_mem, old_alignment, new_byte_count, len_align, return_address);
226 return old_mem.ptr[0..shrunk_len];
227 }
228 if (self.rawResize(old_mem, old_alignment, new_byte_count, len_align, return_address)) |resized_len| {
229 assert(resized_len >= new_byte_count);
230 // TODO: https://github.com/ziglang/zig/issues/4298
231 @memset(old_mem.ptr + new_byte_count, undefined, resized_len - new_byte_count);
232 return old_mem.ptr[0..resized_len];
233 } else |_| {}
234 }
235 if (new_byte_count <= old_mem.len and new_alignment <= old_alignment) {
236 return error.OutOfMemory;
237 }
238 return self.moveBytes(old_mem, old_alignment, new_byte_count, new_alignment, len_align, return_address);
239}
240
241/// Move the given memory to a new location in the given allocator to accomodate a new
242/// size and alignment.
243fn moveBytes(
244 self: Allocator,
245 old_mem: []u8,
246 old_align: u29,
247 new_len: usize,
248 new_alignment: u29,
249 len_align: u29,
250 return_address: usize,
251) Error![]u8 {
252 assert(old_mem.len > 0);
253 assert(new_len > 0);
254 const new_mem = try self.rawAlloc(new_len, new_alignment, len_align, return_address);
255 @memcpy(new_mem.ptr, old_mem.ptr, math.min(new_len, old_mem.len));
256 // TODO https://github.com/ziglang/zig/issues/4298
257 @memset(old_mem.ptr, undefined, old_mem.len);
258 self.rawFree(old_mem, old_align, return_address);
259 return new_mem;
260}
261
262/// Returns a pointer to undefined memory.167/// Returns a pointer to undefined memory.
263/// Call `destroy` with the result to free the memory.168/// Call `destroy` with the result to free the memory.
264pub fn create(self: Allocator, comptime T: type) Error!*T {169pub fn create(self: Allocator, comptime T: type) Error!*T {
...@@ -409,7 +314,7 @@ pub fn allocAdvancedWithRetAddr(...@@ -409,7 +314,7 @@ pub fn allocAdvancedWithRetAddr(
409}314}
410315
411/// Increases or decreases the size of an allocation. It is guaranteed to not move the pointer.316/// Increases or decreases the size of an allocation. It is guaranteed to not move the pointer.
412pub fn resize(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old_mem) {317pub fn resize(self: Allocator, old_mem: anytype, new_n: usize) ?@TypeOf(old_mem) {
413 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;318 const Slice = @typeInfo(@TypeOf(old_mem)).Pointer;
414 const T = Slice.child;319 const T = Slice.child;
415 if (new_n == 0) {320 if (new_n == 0) {
...@@ -417,8 +322,8 @@ pub fn resize(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old...@@ -417,8 +322,8 @@ pub fn resize(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old
417 return &[0]T{};322 return &[0]T{};
418 }323 }
419 const old_byte_slice = mem.sliceAsBytes(old_mem);324 const old_byte_slice = mem.sliceAsBytes(old_mem);
420 const new_byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;325 const new_byte_count = math.mul(usize, @sizeOf(T), new_n) catch return null;
421 const rc = try self.rawResize(old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress());326 const rc = self.rawResize(old_byte_slice, Slice.alignment, new_byte_count, 0, @returnAddress()) orelse return null;
422 assert(rc == new_byte_count);327 assert(rc == new_byte_count);
423 const new_byte_slice = old_byte_slice.ptr[0..new_byte_count];328 const new_byte_slice = old_byte_slice.ptr[0..new_byte_count];
424 return mem.bytesAsSlice(T, new_byte_slice);329 return mem.bytesAsSlice(T, new_byte_slice);
...@@ -488,8 +393,31 @@ pub fn reallocAdvancedWithRetAddr(...@@ -488,8 +393,31 @@ pub fn reallocAdvancedWithRetAddr(
488 .exact => 0,393 .exact => 0,
489 .at_least => @sizeOf(T),394 .at_least => @sizeOf(T),
490 };395 };
491 const new_byte_slice = try self.reallocBytes(old_byte_slice, Slice.alignment, byte_count, new_alignment, len_align, return_address);396
492 return mem.bytesAsSlice(T, @alignCast(new_alignment, new_byte_slice));397 if (mem.isAligned(@ptrToInt(old_byte_slice.ptr), new_alignment)) {
398 if (byte_count <= old_byte_slice.len) {
399 const shrunk_len = self.shrinkBytes(old_byte_slice, Slice.alignment, byte_count, len_align, return_address);
400 return mem.bytesAsSlice(T, @alignCast(new_alignment, old_byte_slice.ptr[0..shrunk_len]));
401 }
402
403 if (self.rawResize(old_byte_slice, Slice.alignment, byte_count, len_align, return_address)) |resized_len| {
404 // TODO: https://github.com/ziglang/zig/issues/4298
405 @memset(old_byte_slice.ptr + byte_count, undefined, resized_len - byte_count);
406 return mem.bytesAsSlice(T, @alignCast(new_alignment, old_byte_slice.ptr[0..resized_len]));
407 }
408 }
409
410 if (byte_count <= old_byte_slice.len and new_alignment <= Slice.alignment) {
411 return error.OutOfMemory;
412 }
413
414 const new_mem = try self.rawAlloc(byte_count, new_alignment, len_align, return_address);
415 @memcpy(new_mem.ptr, old_byte_slice.ptr, math.min(byte_count, old_byte_slice.len));
416 // TODO https://github.com/ziglang/zig/issues/4298
417 @memset(old_byte_slice.ptr, undefined, old_byte_slice.len);
418 self.rawFree(old_byte_slice, Slice.alignment, return_address);
419
420 return mem.bytesAsSlice(T, @alignCast(new_alignment, new_mem));
493}421}
494422
495/// Prefer calling realloc to shrink if you can tolerate failure, such as423/// Prefer calling realloc to shrink if you can tolerate failure, such as
...@@ -580,7 +508,7 @@ pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) ![:0]T {...@@ -580,7 +508,7 @@ pub fn dupeZ(allocator: Allocator, comptime T: type, m: []const T) ![:0]T {
580}508}
581509
582/// Call `vtable.resize`, but caller guarantees that `new_len` <= `buf.len` meaning510/// Call `vtable.resize`, but caller guarantees that `new_len` <= `buf.len` meaning
583/// error.OutOfMemory should be impossible.511/// than a `null` return value should be impossible.
584/// This function allows a runtime `buf_align` value. Callers should generally prefer512/// This function allows a runtime `buf_align` value. Callers should generally prefer
585/// to call `shrink` directly.513/// to call `shrink` directly.
586pub fn shrinkBytes(514pub fn shrinkBytes(
...@@ -592,5 +520,5 @@ pub fn shrinkBytes(...@@ -592,5 +520,5 @@ pub fn shrinkBytes(
592 return_address: usize,520 return_address: usize,
593) usize {521) usize {
594 assert(new_len <= buf.len);522 assert(new_len <= buf.len);
595 return self.rawResize(buf, buf_align, new_len, len_align, return_address) catch unreachable;523 return self.rawResize(buf, buf_align, new_len, len_align, return_address) orelse unreachable;
596}524}
lib/std/testing/failing_allocator.zig+2-5
...@@ -68,11 +68,8 @@ pub const FailingAllocator = struct {...@@ -68,11 +68,8 @@ pub const FailingAllocator = struct {
68 new_len: usize,68 new_len: usize,
69 len_align: u29,69 len_align: u29,
70 ra: usize,70 ra: usize,
71 ) error{OutOfMemory}!usize {71 ) ?usize {
72 const r = self.internal_allocator.rawResize(old_mem, old_align, new_len, len_align, ra) catch |e| {72 const r = self.internal_allocator.rawResize(old_mem, old_align, new_len, len_align, ra) orelse return null;
73 std.debug.assert(new_len > old_mem.len);
74 return e;
75 };
76 if (r < old_mem.len) {73 if (r < old_mem.len) {
77 self.freed_bytes += old_mem.len - r;74 self.freed_bytes += old_mem.len - r;
78 } else {75 } else {
src/link/MachO.zig+1-1
...@@ -1288,7 +1288,7 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any...@@ -1288,7 +1288,7 @@ fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: any
1288 // TODO this should not be performed if the user specifies `-flat_namespace` flag.1288 // TODO this should not be performed if the user specifies `-flat_namespace` flag.
1289 // See ld64 manpages.1289 // See ld64 manpages.
1290 var arena_alloc = std.heap.ArenaAllocator.init(self.base.allocator);1290 var arena_alloc = std.heap.ArenaAllocator.init(self.base.allocator);
1291 const arena = &arena_alloc.allocator;1291 const arena = arena_alloc.allocator();
1292 defer arena_alloc.deinit();1292 defer arena_alloc.deinit();
12931293
1294 while (dependent_libs.readItem()) |*id| {1294 while (dependent_libs.readItem()) |*id| {
src/link/tapi.zig+1-1
...@@ -138,7 +138,7 @@ pub const LibStub = struct {...@@ -138,7 +138,7 @@ pub const LibStub = struct {
138 err: {138 err: {
139 log.debug("trying to parse as []TbdV3", .{});139 log.debug("trying to parse as []TbdV3", .{});
140 const inner = lib_stub.yaml.parse([]TbdV3) catch break :err;140 const inner = lib_stub.yaml.parse([]TbdV3) catch break :err;
141 var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, inner.len);141 var out = try lib_stub.yaml.arena.allocator().alloc(Tbd, inner.len);
142 for (inner) |doc, i| {142 for (inner) |doc, i| {
143 out[i] = .{ .v3 = doc };143 out[i] = .{ .v3 = doc };
144 }144 }
src/main.zig+1-1
...@@ -159,7 +159,7 @@ pub fn main() anyerror!void {...@@ -159,7 +159,7 @@ pub fn main() anyerror!void {
159159
160 if (tracy.enable_allocation) {160 if (tracy.enable_allocation) {
161 var gpa_tracy = tracy.tracyAllocator(gpa);161 var gpa_tracy = tracy.tracyAllocator(gpa);
162 return mainArgs(&gpa_tracy.allocator, arena, args);162 return mainArgs(gpa_tracy.allocator(), arena, args);
163 }163 }
164164
165 return mainArgs(gpa, arena, args);165 return mainArgs(gpa, arena, args);
src/tracy.zig+10-15
...@@ -113,20 +113,16 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {...@@ -113,20 +113,16 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
113113
114 const Self = @This();114 const Self = @This();
115115
116 pub fn allocator(self: *Self) std.mem.Allocator {116 pub fn init(parent_allocator: std.mem.Allocator) Self {
117 return std.mem.Allocator.init(self, allocFn, resizeFn);
118 }
119
120 pub fn init(allocator: std.mem.Allocator) Self {
121 return .{117 return .{
122 .parent_allocator = allocator,118 .parent_allocator = parent_allocator,
123 .allocator = .{
124 .allocFn = allocFn,
125 .resizeFn = resizeFn,
126 },
127 };119 };
128 }120 }
129121
122 pub fn allocator(self: *Self) std.mem.Allocator {
123 return std.mem.Allocator.init(self, allocFn, resizeFn, freeFn);
124 }
125
130 fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {126 fn allocFn(self: *Self, len: usize, ptr_align: u29, len_align: u29, ret_addr: usize) std.mem.Allocator.Error![]u8 {
131 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ret_addr);127 const result = self.parent_allocator.allocFn(self.parent_allocator, len, ptr_align, len_align, ret_addr);
132 if (result) |data| {128 if (result) |data| {
...@@ -162,12 +158,11 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {...@@ -162,12 +158,11 @@ pub fn TracyAllocator(comptime name: ?[:0]const u8) type {
162 }158 }
163159
164 return resized_len;160 return resized_len;
165 } else |err| {
166 // this is not really an error condition, during normal operation the compiler hits this case thousands of times
167 // due to this emitting messages for it is both slow and causes clutter
168 // messageColor("allocation resize failed", 0xFF0000);
169 return err;
170 }161 }
162
163 // during normal operation the compiler hits this case thousands of times due to this
164 // emitting messages for it is both slow and causes clutter
165 return null;
171 }166 }
172167
173 fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void {168 fn freeFn(self: *Self, buf: []u8, buf_align: u29, ret_addr: usize) void {
test/compare_output.zig+3-3
...@@ -496,7 +496,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -496,7 +496,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
496 \\ var a = try allocator.alloc(u8, 10);496 \\ var a = try allocator.alloc(u8, 10);
497 \\ a = allocator.shrink(a, 5);497 \\ a = allocator.shrink(a, 5);
498 \\ try std.testing.expect(a.len == 5);498 \\ try std.testing.expect(a.len == 5);
499 \\ try std.testing.expectError(error.OutOfMemory, allocator.resize(a, 20));499 \\ try std.testing.expect(allocator.resize(a, 20) == null);
500 \\ allocator.free(a);500 \\ allocator.free(a);
501 \\}501 \\}
502 \\502 \\
...@@ -514,8 +514,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -514,8 +514,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
514 ,514 ,
515 \\debug: alloc - success - len: 10, ptr_align: 1, len_align: 0515 \\debug: alloc - success - len: 10, ptr_align: 1, len_align: 0
516 \\debug: shrink - success - 10 to 5, len_align: 0, buf_align: 1516 \\debug: shrink - success - 10 to 5, len_align: 0, buf_align: 1
517 \\error: expand - failure: OutOfMemory - 5 to 20, len_align: 0, buf_align: 1517 \\error: expand - failure - 5 to 20, len_align: 0, buf_align: 1
518 \\debug: free - success - len: 5518 \\debug: free - len: 5
519 \\519 \\
520 );520 );
521}521}
tools/update-linux-headers.zig+1-1
...@@ -131,7 +131,7 @@ const PathTable = std.StringHashMap(*TargetToHash);...@@ -131,7 +131,7 @@ const PathTable = std.StringHashMap(*TargetToHash);
131131
132pub fn main() !void {132pub fn main() !void {
133 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);133 var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
134 const arena = &arena_state.allocator;134 const arena = arena_state.allocator();
135 const args = try std.process.argsAlloc(arena);135 const args = try std.process.argsAlloc(arena);
136 var search_paths = std.ArrayList([]const u8).init(arena);136 var search_paths = std.ArrayList([]const u8).init(arena);
137 var opt_out_dir: ?[]const u8 = null;137 var opt_out_dir: ?[]const u8 = null;