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 629e2e7844
This commit is contained in:
Andrew Kelley 2025-02-03 21:07:49 -08:00
parent 0d8166be3f
commit f1717777a2
4 changed files with 0 additions and 329 deletions

View file

@ -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;

View file

@ -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());
}

View file

@ -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);
}

View file

@ -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