| ... | ... | @@ -98,7 +98,7 @@ |
| 98 | 98 | //! in a `std.HashMap` using the backing allocator. |
| 99 | 99 | |
| 100 | 100 | const std = @import("std"); |
| 101 | | const log = std.log.scoped(.std); |
| 101 | const log = std.log.scoped(.gpa); |
| 102 | 102 | const math = std.math; |
| 103 | 103 | const assert = std.debug.assert; |
| 104 | 104 | const mem = std.mem; |
| ... | ... | @@ -162,6 +162,9 @@ pub const Config = struct { |
| 162 | 162 | /// logged error messages with stack trace details. The downside is that every allocation |
| 163 | 163 | /// will be leaked! |
| 164 | 164 | never_unmap: bool = false, |
| 165 | |
| 166 | /// Enables emitting info messages with the size and address of every allocation. |
| 167 | verbose_log: bool = false, |
| 165 | 168 | }; |
| 166 | 169 | |
| 167 | 170 | pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| ... | ... | @@ -454,10 +457,19 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 454 | 457 | const result_len = try self.backing_allocator.resizeFn(self.backing_allocator, old_mem, old_align, new_size, len_align, ret_addr); |
| 455 | 458 | |
| 456 | 459 | if (result_len == 0) { |
| 460 | if (config.verbose_log) { |
| 461 | log.info("large free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr }); |
| 462 | } |
| 463 | |
| 457 | 464 | self.large_allocations.removeAssertDiscard(@ptrToInt(old_mem.ptr)); |
| 458 | 465 | return 0; |
| 459 | 466 | } |
| 460 | 467 | |
| 468 | if (config.verbose_log) { |
| 469 | log.info("large resize {d} bytes at {*} to {d}", .{ |
| 470 | old_mem.len, old_mem.ptr, new_size, |
| 471 | }); |
| 472 | } |
| 461 | 473 | entry.value.bytes = old_mem.ptr[0..result_len]; |
| 462 | 474 | collectStackTrace(ret_addr, &entry.value.stack_addresses); |
| 463 | 475 | return result_len; |
| ... | ... | @@ -568,6 +580,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 568 | 580 | } else { |
| 569 | 581 | @memset(old_mem.ptr, undefined, old_mem.len); |
| 570 | 582 | } |
| 583 | if (config.verbose_log) { |
| 584 | log.info("small free {d} bytes at {*}", .{ old_mem.len, old_mem.ptr }); |
| 585 | } |
| 571 | 586 | return @as(usize, 0); |
| 572 | 587 | } |
| 573 | 588 | const new_aligned_size = math.max(new_size, old_align); |
| ... | ... | @@ -576,6 +591,11 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 576 | 591 | if (old_mem.len > new_size) { |
| 577 | 592 | @memset(old_mem.ptr + new_size, undefined, old_mem.len - new_size); |
| 578 | 593 | } |
| 594 | if (config.verbose_log) { |
| 595 | log.info("small resize {d} bytes at {*} to {d}", .{ |
| 596 | old_mem.len, old_mem.ptr, new_size, |
| 597 | }); |
| 598 | } |
| 579 | 599 | return new_size; |
| 580 | 600 | } |
| 581 | 601 | return error.OutOfMemory; |
| ... | ... | @@ -623,6 +643,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 623 | 643 | gop.entry.value.bytes = slice; |
| 624 | 644 | collectStackTrace(ret_addr, &gop.entry.value.stack_addresses); |
| 625 | 645 | |
| 646 | if (config.verbose_log) { |
| 647 | log.info("large alloc {d} bytes at {*}", .{ slice.len, slice.ptr }); |
| 648 | } |
| 626 | 649 | return slice; |
| 627 | 650 | } |
| 628 | 651 | |
| ... | ... | @@ -632,6 +655,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 632 | 655 | |
| 633 | 656 | const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); |
| 634 | 657 | const ptr = try self.allocSlot(new_size_class, ret_addr); |
| 658 | if (config.verbose_log) { |
| 659 | log.info("small alloc {d} bytes at {*}", .{ len, ptr }); |
| 660 | } |
| 635 | 661 | return ptr[0..len]; |
| 636 | 662 | } |
| 637 | 663 | |