From 766b315b3888f0f9ac1ece69131cdf23f98b2c14 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 30 Jan 2021 20:15:26 -0700 Subject: [PATCH] std.GeneralPurposeAllocator: logging improvements It now uses the log scope "gpa" instead of "std". Additionally, there is a new config option `verbose_log` which enables info log messages for every allocation. Can be useful when debugging. This option is off by default. --- lib/std/heap/general_purpose_allocator.zig | 28 +++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index fb340edfd3..c731f22d66 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -98,7 +98,7 @@ //! in a `std.HashMap` using the backing allocator. const std = @import("std"); -const log = std.log.scoped(.std); +const log = std.log.scoped(.gpa); const math = std.math; const assert = std.debug.assert; const mem = std.mem; @@ -162,6 +162,9 @@ pub const Config = struct { /// logged error messages with stack trace details. The downside is that every allocation /// will be leaked! never_unmap: bool = false, + + /// Enables emitting info messages with the size and address of every allocation. + verbose_log: bool = false, }; pub fn GeneralPurposeAllocator(comptime config: Config) type { @@ -454,10 +457,19 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { const result_len = try self.backing_allocator.resizeFn(self.backing_allocator, old_mem, old_align, new_size, len_align, ret_addr); if (result_len == 0) { + if (config.verbose_log) { + log.info("large free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr }); + } + self.large_allocations.removeAssertDiscard(@ptrToInt(old_mem.ptr)); return 0; } + if (config.verbose_log) { + log.info("large resize {d} bytes at {*} to {d}", .{ + old_mem.len, old_mem.ptr, new_size, + }); + } entry.value.bytes = old_mem.ptr[0..result_len]; collectStackTrace(ret_addr, &entry.value.stack_addresses); return result_len; @@ -568,6 +580,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { } else { @memset(old_mem.ptr, undefined, old_mem.len); } + if (config.verbose_log) { + log.info("small free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr }); + } return @as(usize, 0); } const new_aligned_size = math.max(new_size, old_align); @@ -576,6 +591,11 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { if (old_mem.len > new_size) { @memset(old_mem.ptr + new_size, undefined, old_mem.len - new_size); } + if (config.verbose_log) { + log.info("small resize {d} bytes at {*} to {d}", .{ + old_mem.len, old_mem.ptr, new_size, + }); + } return new_size; } return error.OutOfMemory; @@ -623,6 +643,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { gop.entry.value.bytes = slice; collectStackTrace(ret_addr, &gop.entry.value.stack_addresses); + if (config.verbose_log) { + log.info("large alloc {d} bytes at {*}", .{ slice.len, slice.ptr }); + } return slice; } @@ -632,6 +655,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); const ptr = try self.allocSlot(new_size_class, ret_addr); + if (config.verbose_log) { + log.info("small alloc {d} bytes at {*}", .{ len, ptr }); + } return ptr[0..len]; }