diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-08-07 22:35:15 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-08-07 22:45:45 -0700 |
| commit | cc17f84cccc540143f3fd19fe32218478d4a0c6f (patch) | |
| tree | 7cfd3d3c9e5a9bd17347b4ec7093aadf464b74de /lib/std/testing/leak_count_allocator.zig | |
| parent | 30bace66d4336ebc9f27d68e5807a80ab3b68d67 (diff) | |
| download | zig-cc17f84cccc540143f3fd19fe32218478d4a0c6f.tar.gz zig-cc17f84cccc540143f3fd19fe32218478d4a0c6f.zip | |
std: introduce GeneralPurposeAllocator
`std.GeneralPurposeAllocator` is now available. It is a function that
takes a configuration struct (with default field values) and returns an
allocator. There is a detailed description of this allocator in the
doc comments at the top of the new file.
The main feature of this allocator is that it is *safe*. It
prevents double-free, use-after-free, and detects leaks.
Some deprecation compile errors are removed.
The Allocator interface gains `old_align` as a new parameter to
`resizeFn`. This is useful to quickly look up allocations.
`std.heap.page_allocator` is improved to use mmap address hints to avoid
obtaining the same virtual address pages when unmapping and mapping
pages. The new general purpose allocator uses the page allocator as its
backing allocator by default.
`std.testing.allocator` is replaced with usage of this new allocator,
which does leak checking, and so the LeakCheckAllocator is retired.
stage1 is improved so that the `@typeInfo` of a pointer has a lazy value
for the alignment of the child type, to avoid false dependency loops
when dealing with pointers to async function frames.
The `std.mem.Allocator` interface is refactored to be in its own file.
`std.Mutex` now exposes the dummy mutex with `std.Mutex.Dummy`.
This allocator is great for debug mode, however it needs some work to
have better performance in release modes. The next step will be setting
up a series of tests in ziglang/gotta-go-fast and then making
improvements to the implementation.
Diffstat (limited to 'lib/std/testing/leak_count_allocator.zig')
| -rw-r--r-- | lib/std/testing/leak_count_allocator.zig | 51 |
1 files changed, 0 insertions, 51 deletions
diff --git a/lib/std/testing/leak_count_allocator.zig b/lib/std/testing/leak_count_allocator.zig deleted file mode 100644 index 87564aeea7..0000000000 --- a/lib/std/testing/leak_count_allocator.zig +++ /dev/null @@ -1,51 +0,0 @@ -const std = @import("../std.zig"); - -/// This allocator is used in front of another allocator and counts the numbers of allocs and frees. -/// The test runner asserts every alloc has a corresponding free at the end of each test. -/// -/// The detection algorithm is incredibly primitive and only accounts for number of calls. -/// This should be replaced by the general purpose debug allocator. -pub const LeakCountAllocator = struct { - count: usize, - allocator: std.mem.Allocator, - internal_allocator: *std.mem.Allocator, - - pub fn init(allocator: *std.mem.Allocator) LeakCountAllocator { - return .{ - .count = 0, - .allocator = .{ - .allocFn = alloc, - .resizeFn = resize, - }, - .internal_allocator = allocator, - }; - } - - fn alloc(allocator: *std.mem.Allocator, len: usize, ptr_align: u29, len_align: u29) error{OutOfMemory}![]u8 { - const self = @fieldParentPtr(LeakCountAllocator, "allocator", allocator); - const ptr = try self.internal_allocator.callAllocFn(len, ptr_align, len_align); - self.count += 1; - return ptr; - } - - fn resize(allocator: *std.mem.Allocator, old_mem: []u8, new_size: usize, len_align: u29) error{OutOfMemory}!usize { - const self = @fieldParentPtr(LeakCountAllocator, "allocator", allocator); - if (new_size == 0) { - if (self.count == 0) { - std.debug.panic("error - too many calls to free, most likely double free", .{}); - } - self.count -= 1; - } - return self.internal_allocator.callResizeFn(old_mem, new_size, len_align) catch |e| { - std.debug.assert(new_size > old_mem.len); - return e; - }; - } - - pub fn validate(self: LeakCountAllocator) !void { - if (self.count > 0) { - std.debug.warn("error - detected leaked allocations without matching free: {}\n", .{self.count}); - return error.Leak; - } - } -}; |
