From f1717777a2ce12905f86e75a11ff6388332d6926 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 3 Feb 2025 21:07:49 -0800 Subject: [PATCH] std.heap: delete LoggingAllocator and friends I don't think these belong in std, at least not in their current form. If someone wants to add these back I'd like to review the patch before it lands. Reverts 629e2e784495dd8ac91493fa7bb11e1772698e42 --- lib/std/heap.zig | 8 -- lib/std/heap/log_to_writer_allocator.zig | 145 ----------------------- lib/std/heap/logging_allocator.zig | 133 --------------------- test/compare_output.zig | 43 ------- 4 files changed, 329 deletions(-) delete mode 100644 lib/std/heap/log_to_writer_allocator.zig delete mode 100644 lib/std/heap/logging_allocator.zig diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 2abe00c7a0..bec7c9149f 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -8,11 +8,6 @@ const c = std.c; const Allocator = std.mem.Allocator; const windows = std.os.windows; -pub const LoggingAllocator = @import("heap/logging_allocator.zig").LoggingAllocator; -pub const loggingAllocator = @import("heap/logging_allocator.zig").loggingAllocator; -pub const ScopedLoggingAllocator = @import("heap/logging_allocator.zig").ScopedLoggingAllocator; -pub const LogToWriterAllocator = @import("heap/log_to_writer_allocator.zig").LogToWriterAllocator; -pub const logToWriterAllocator = @import("heap/log_to_writer_allocator.zig").logToWriterAllocator; pub const ArenaAllocator = @import("heap/arena_allocator.zig").ArenaAllocator; pub const GeneralPurposeAllocatorConfig = @import("heap/general_purpose_allocator.zig").Config; pub const GeneralPurposeAllocator = @import("heap/general_purpose_allocator.zig").GeneralPurposeAllocator; @@ -1062,9 +1057,6 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) { }; test { - _ = LoggingAllocator; - _ = LogToWriterAllocator; - _ = ScopedLoggingAllocator; _ = @import("heap/memory_pool.zig"); _ = ArenaAllocator; _ = GeneralPurposeAllocator; diff --git a/lib/std/heap/log_to_writer_allocator.zig b/lib/std/heap/log_to_writer_allocator.zig deleted file mode 100644 index 239a580f9b..0000000000 --- a/lib/std/heap/log_to_writer_allocator.zig +++ /dev/null @@ -1,145 +0,0 @@ -const std = @import("../std.zig"); -const Allocator = std.mem.Allocator; - -/// This allocator is used in front of another allocator and logs to the provided writer -/// on every call to the allocator. Writer errors are ignored. -pub fn LogToWriterAllocator(comptime Writer: type) type { - return struct { - parent_allocator: Allocator, - writer: Writer, - - const Self = @This(); - - pub fn init(parent_allocator: Allocator, writer: Writer) Self { - return Self{ - .parent_allocator = parent_allocator, - .writer = writer, - }; - } - - pub fn allocator(self: *Self) Allocator { - return .{ - .ptr = self, - .vtable = &.{ - .alloc = alloc, - .resize = resize, - .remap = remap, - .free = free, - }, - }; - } - - fn alloc( - ctx: *anyopaque, - len: usize, - alignment: std.mem.Alignment, - ra: usize, - ) ?[*]u8 { - const self: *Self = @ptrCast(@alignCast(ctx)); - self.writer.print("alloc : {}", .{len}) catch {}; - const result = self.parent_allocator.rawAlloc(len, alignment, ra); - if (result != null) { - self.writer.print(" success!\n", .{}) catch {}; - } else { - self.writer.print(" failure!\n", .{}) catch {}; - } - return result; - } - - fn resize( - ctx: *anyopaque, - buf: []u8, - alignment: std.mem.Alignment, - new_len: usize, - ra: usize, - ) bool { - const self: *Self = @ptrCast(@alignCast(ctx)); - if (new_len <= buf.len) { - self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {}; - } else { - self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {}; - } - - if (self.parent_allocator.rawResize(buf, alignment, new_len, ra)) { - if (new_len > buf.len) { - self.writer.print(" success!\n", .{}) catch {}; - } - return true; - } - - std.debug.assert(new_len > buf.len); - self.writer.print(" failure!\n", .{}) catch {}; - return false; - } - - fn remap( - ctx: *anyopaque, - buf: []u8, - alignment: std.mem.Alignment, - new_len: usize, - ra: usize, - ) ?[*]u8 { - const self: *Self = @ptrCast(@alignCast(ctx)); - if (new_len <= buf.len) { - self.writer.print("shrink: {} to {}\n", .{ buf.len, new_len }) catch {}; - } else { - self.writer.print("expand: {} to {}", .{ buf.len, new_len }) catch {}; - } - - if (self.parent_allocator.rawRemap(buf, alignment, new_len, ra)) |new_memory| { - if (new_len > buf.len) { - self.writer.print(" success!\n", .{}) catch {}; - } - return new_memory; - } - - std.debug.assert(new_len > buf.len); - self.writer.print(" failure!\n", .{}) catch {}; - return null; - } - - fn free( - ctx: *anyopaque, - buf: []u8, - alignment: std.mem.Alignment, - ra: usize, - ) void { - const self: *Self = @ptrCast(@alignCast(ctx)); - self.writer.print("free : {}\n", .{buf.len}) catch {}; - self.parent_allocator.rawFree(buf, alignment, ra); - } - }; -} - -/// This allocator is used in front of another allocator and logs to the provided writer -/// on every call to the allocator. Writer errors are ignored. -pub fn logToWriterAllocator( - parent_allocator: Allocator, - writer: anytype, -) LogToWriterAllocator(@TypeOf(writer)) { - return LogToWriterAllocator(@TypeOf(writer)).init(parent_allocator, writer); -} - -test "LogToWriterAllocator" { - var log_buf: [255]u8 = undefined; - var fbs = std.io.fixedBufferStream(&log_buf); - - var allocator_buf: [10]u8 = undefined; - var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf)); - var allocator_state = logToWriterAllocator(fixedBufferAllocator.allocator(), fbs.writer()); - const allocator = allocator_state.allocator(); - - var a = try allocator.alloc(u8, 10); - try std.testing.expect(allocator.resize(a, 5)); - a = a[0..5]; - try std.testing.expect(!allocator.resize(a, 20)); - allocator.free(a); - - try std.testing.expectEqualSlices(u8, - \\alloc : 10 success! - \\shrink: 10 to 5 - \\expand: 5 to 20 failure! - \\free : 5 - \\ - , fbs.getWritten()); -} diff --git a/lib/std/heap/logging_allocator.zig b/lib/std/heap/logging_allocator.zig deleted file mode 100644 index 706f2ac544..0000000000 --- a/lib/std/heap/logging_allocator.zig +++ /dev/null @@ -1,133 +0,0 @@ -const std = @import("../std.zig"); -const Allocator = std.mem.Allocator; - -/// This allocator is used in front of another allocator and logs to `std.log` -/// on every call to the allocator. -/// For logging to a `std.io.Writer` see `std.heap.LogToWriterAllocator` -pub fn LoggingAllocator( - comptime success_log_level: std.log.Level, - comptime failure_log_level: std.log.Level, -) type { - return ScopedLoggingAllocator(.default, success_log_level, failure_log_level); -} - -/// This allocator is used in front of another allocator and logs to `std.log` -/// with the given scope on every call to the allocator. -/// For logging to a `std.io.Writer` see `std.heap.LogToWriterAllocator` -pub fn ScopedLoggingAllocator( - comptime scope: @Type(.enum_literal), - comptime success_log_level: std.log.Level, - comptime failure_log_level: std.log.Level, -) type { - const log = std.log.scoped(scope); - - return struct { - parent_allocator: Allocator, - - const Self = @This(); - - pub fn init(parent_allocator: Allocator) Self { - return .{ - .parent_allocator = parent_allocator, - }; - } - - pub fn allocator(self: *Self) Allocator { - return .{ - .ptr = self, - .vtable = &.{ - .alloc = alloc, - .resize = resize, - .free = free, - }, - }; - } - - // This function is required as the `std.log.log` function is not public - inline fn logHelper(comptime log_level: std.log.Level, comptime format: []const u8, args: anytype) void { - switch (log_level) { - .err => log.err(format, args), - .warn => log.warn(format, args), - .info => log.info(format, args), - .debug => log.debug(format, args), - } - } - - fn alloc( - ctx: *anyopaque, - len: usize, - log2_ptr_align: u8, - ra: usize, - ) ?[*]u8 { - const self: *Self = @ptrCast(@alignCast(ctx)); - const result = self.parent_allocator.rawAlloc(len, log2_ptr_align, ra); - if (result != null) { - logHelper( - success_log_level, - "alloc - success - len: {}, ptr_align: {}", - .{ len, log2_ptr_align }, - ); - } else { - logHelper( - failure_log_level, - "alloc - failure: OutOfMemory - len: {}, ptr_align: {}", - .{ len, log2_ptr_align }, - ); - } - return result; - } - - fn resize( - ctx: *anyopaque, - buf: []u8, - log2_buf_align: u8, - new_len: usize, - ra: usize, - ) bool { - const self: *Self = @ptrCast(@alignCast(ctx)); - if (self.parent_allocator.rawResize(buf, log2_buf_align, new_len, ra)) { - if (new_len <= buf.len) { - logHelper( - success_log_level, - "shrink - success - {} to {}, buf_align: {}", - .{ buf.len, new_len, log2_buf_align }, - ); - } else { - logHelper( - success_log_level, - "expand - success - {} to {}, buf_align: {}", - .{ buf.len, new_len, log2_buf_align }, - ); - } - - return true; - } - - std.debug.assert(new_len > buf.len); - logHelper( - failure_log_level, - "expand - failure - {} to {}, buf_align: {}", - .{ buf.len, new_len, log2_buf_align }, - ); - return false; - } - - fn free( - ctx: *anyopaque, - buf: []u8, - log2_buf_align: u8, - ra: usize, - ) void { - const self: *Self = @ptrCast(@alignCast(ctx)); - self.parent_allocator.rawFree(buf, log2_buf_align, ra); - logHelper(success_log_level, "free - len: {}", .{buf.len}); - } - }; -} - -/// This allocator is used in front of another allocator and logs to `std.log` -/// on every call to the allocator. -/// For logging to a `std.io.Writer` see `std.heap.LogToWriterAllocator` -pub fn loggingAllocator(parent_allocator: Allocator) LoggingAllocator(.debug, .err) { - return LoggingAllocator(.debug, .err).init(parent_allocator); -} diff --git a/test/compare_output.zig b/test/compare_output.zig index e766641cde..3603163a2d 100644 --- a/test/compare_output.zig +++ b/test/compare_output.zig @@ -493,49 +493,6 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\ ); - // It is required to override the log function in order to print to stdout instead of stderr - cases.add("std.heap.LoggingAllocator logs to std.log", - \\const std = @import("std"); - \\ - \\pub const std_options: std.Options = .{ - \\ .log_level = .debug, - \\ .logFn = log, - \\}; - \\ - \\pub fn main() !void { - \\ var allocator_buf: [10]u8 = undefined; - \\ const fba = std.heap.FixedBufferAllocator.init(&allocator_buf); - \\ var fba_wrapped = std.mem.validationWrap(fba); - \\ var logging_allocator = std.heap.loggingAllocator(fba_wrapped.allocator()); - \\ const allocator = logging_allocator.allocator(); - \\ - \\ var a = try allocator.alloc(u8, 10); - \\ try std.testing.expect(allocator.resize(a, 5)); - \\ a = a[0..5]; - \\ try std.testing.expect(a.len == 5); - \\ try std.testing.expect(!allocator.resize(a, 20)); - \\ allocator.free(a); - \\} - \\ - \\pub fn log( - \\ comptime level: std.log.Level, - \\ comptime scope: @TypeOf(.EnumLiteral), - \\ comptime format: []const u8, - \\ args: anytype, - \\) void { - \\ const level_txt = comptime level.asText(); - \\ const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): "; - \\ const stdout = std.io.getStdOut().writer(); - \\ nosuspend stdout.print(level_txt ++ prefix2 ++ format ++ "\n", args) catch return; - \\} - , - \\debug: alloc - success - len: 10, ptr_align: 0 - \\debug: shrink - success - 10 to 5, buf_align: 0 - \\error: expand - failure - 5 to 20, buf_align: 0 - \\debug: free - len: 5 - \\ - ); - cases.add("valid carriage return example", "const io = @import(\"std\").io;\r\n" ++ // Testing CRLF line endings are valid "\r\n" ++ "pub \r fn main() void {\r\n" ++ // Testing isolated carriage return as whitespace is valid