mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std: GPA deinit return an enum instead of a bool
This commit is contained in:
parent
3f259d3550
commit
bd801dc489
@ -16,6 +16,7 @@ pub const LogToWriterAllocator = @import("heap/log_to_writer_allocator.zig").Log
|
||||
pub const logToWriterAllocator = @import("heap/log_to_writer_allocator.zig").logToWriterAllocator;
|
||||
pub const ArenaAllocator = @import("heap/arena_allocator.zig").ArenaAllocator;
|
||||
pub const GeneralPurposeAllocator = @import("heap/general_purpose_allocator.zig").GeneralPurposeAllocator;
|
||||
pub const Check = @import("heap/general_purpose_allocator.zig").Check;
|
||||
pub const WasmAllocator = @import("heap/WasmAllocator.zig");
|
||||
pub const WasmPageAllocator = @import("heap/WasmPageAllocator.zig");
|
||||
pub const PageAllocator = @import("heap/PageAllocator.zig");
|
||||
|
||||
@ -155,6 +155,8 @@ pub const Config = struct {
|
||||
verbose_log: bool = false,
|
||||
};
|
||||
|
||||
pub const Check = enum { ok, leak };
|
||||
|
||||
pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
return struct {
|
||||
backing_allocator: Allocator = std.heap.page_allocator,
|
||||
@ -431,7 +433,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
} else struct {};
|
||||
|
||||
/// Returns true if there were leaks; false otherwise.
|
||||
pub fn deinit(self: *Self) bool {
|
||||
pub fn deinit(self: *Self) Check {
|
||||
const leaks = if (config.safety) self.detectLeaks() else false;
|
||||
if (config.retain_metadata) {
|
||||
self.freeRetainedMetadata();
|
||||
@ -441,7 +443,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
self.small_allocations.deinit(self.backing_allocator);
|
||||
}
|
||||
self.* = undefined;
|
||||
return leaks;
|
||||
return @intToEnum(Check, @boolToInt(leaks));
|
||||
}
|
||||
|
||||
fn collectStackTrace(first_trace_addr: usize, addresses: *[stack_n]usize) void {
|
||||
@ -1024,7 +1026,7 @@ const test_config = Config{};
|
||||
|
||||
test "small allocations - free in same order" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var list = std.ArrayList(*u64).init(std.testing.allocator);
|
||||
@ -1043,7 +1045,7 @@ test "small allocations - free in same order" {
|
||||
|
||||
test "small allocations - free in reverse order" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var list = std.ArrayList(*u64).init(std.testing.allocator);
|
||||
@ -1062,7 +1064,7 @@ test "small allocations - free in reverse order" {
|
||||
|
||||
test "large allocations" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const ptr1 = try allocator.alloc(u64, 42768);
|
||||
@ -1075,7 +1077,7 @@ test "large allocations" {
|
||||
|
||||
test "very large allocation" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
try std.testing.expectError(error.OutOfMemory, allocator.alloc(u8, math.maxInt(usize)));
|
||||
@ -1083,7 +1085,7 @@ test "very large allocation" {
|
||||
|
||||
test "realloc" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alignedAlloc(u8, @alignOf(u32), 1);
|
||||
@ -1105,7 +1107,7 @@ test "realloc" {
|
||||
|
||||
test "shrink" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alloc(u8, 20);
|
||||
@ -1130,7 +1132,7 @@ test "shrink" {
|
||||
|
||||
test "large object - grow" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice1 = try allocator.alloc(u8, page_size * 2 - 20);
|
||||
@ -1148,7 +1150,7 @@ test "large object - grow" {
|
||||
|
||||
test "realloc small object to large object" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alloc(u8, 70);
|
||||
@ -1165,7 +1167,7 @@ test "realloc small object to large object" {
|
||||
|
||||
test "shrink large object to large object" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alloc(u8, page_size * 2 + 50);
|
||||
@ -1190,7 +1192,7 @@ test "shrink large object to large object" {
|
||||
|
||||
test "shrink large object to large object with larger alignment" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var debug_buffer: [1000]u8 = undefined;
|
||||
@ -1226,7 +1228,7 @@ test "shrink large object to large object with larger alignment" {
|
||||
|
||||
test "realloc large object to small object" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alloc(u8, page_size * 2 + 50);
|
||||
@ -1244,7 +1246,7 @@ test "overrideable mutexes" {
|
||||
.backing_allocator = std.testing.allocator,
|
||||
.mutex = std.Thread.Mutex{},
|
||||
};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const ptr = try allocator.create(i32);
|
||||
@ -1253,7 +1255,7 @@ test "overrideable mutexes" {
|
||||
|
||||
test "non-page-allocator backing allocator" {
|
||||
var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const ptr = try allocator.create(i32);
|
||||
@ -1262,7 +1264,7 @@ test "non-page-allocator backing allocator" {
|
||||
|
||||
test "realloc large object to larger alignment" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var debug_buffer: [1000]u8 = undefined;
|
||||
@ -1304,7 +1306,7 @@ test "realloc large object to larger alignment" {
|
||||
test "large object shrinks to small but allocation fails during shrink" {
|
||||
var failing_allocator = std.testing.FailingAllocator.init(std.heap.page_allocator, 3);
|
||||
var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = failing_allocator.allocator() };
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var slice = try allocator.alloc(u8, page_size * 2 + 50);
|
||||
@ -1322,7 +1324,7 @@ test "large object shrinks to small but allocation fails during shrink" {
|
||||
|
||||
test "objects of size 1024 and 2048" {
|
||||
var gpa = GeneralPurposeAllocator(test_config){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
const slice = try allocator.alloc(u8, 1025);
|
||||
@ -1334,7 +1336,7 @@ test "objects of size 1024 and 2048" {
|
||||
|
||||
test "setting a memory cap" {
|
||||
var gpa = GeneralPurposeAllocator(.{ .enable_memory_limit = true }){};
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
gpa.setRequestedMemoryLimit(1010);
|
||||
@ -1361,11 +1363,11 @@ test "setting a memory cap" {
|
||||
test "double frees" {
|
||||
// use a GPA to back a GPA to check for leaks of the latter's metadata
|
||||
var backing_gpa = GeneralPurposeAllocator(.{ .safety = true }){};
|
||||
defer std.testing.expect(!backing_gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(backing_gpa.deinit() == .ok) catch @panic("leak");
|
||||
|
||||
const GPA = GeneralPurposeAllocator(.{ .safety = true, .never_unmap = true, .retain_metadata = true });
|
||||
var gpa = GPA{ .backing_allocator = backing_gpa.allocator() };
|
||||
defer std.testing.expect(!gpa.deinit()) catch @panic("leak");
|
||||
defer std.testing.expect(gpa.deinit() == .ok) catch @panic("leak");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
// detect a small allocation double free, even though bucket is emptied
|
||||
|
||||
@ -56,7 +56,7 @@ fn mainServer() !void {
|
||||
},
|
||||
.query_test_metadata => {
|
||||
std.testing.allocator_instance = .{};
|
||||
defer if (std.testing.allocator_instance.deinit()) {
|
||||
defer if (std.testing.allocator_instance.deinit() == .leak) {
|
||||
@panic("internal test runner memory leak");
|
||||
};
|
||||
|
||||
@ -108,7 +108,7 @@ fn mainServer() !void {
|
||||
}
|
||||
},
|
||||
};
|
||||
leak = std.testing.allocator_instance.deinit();
|
||||
leak = std.testing.allocator_instance.deinit() == .leak;
|
||||
try server.serveTestResults(.{
|
||||
.index = index,
|
||||
.flags = .{
|
||||
@ -148,7 +148,7 @@ fn mainTerminal() void {
|
||||
for (test_fn_list, 0..) |test_fn, i| {
|
||||
std.testing.allocator_instance = .{};
|
||||
defer {
|
||||
if (std.testing.allocator_instance.deinit()) {
|
||||
if (std.testing.allocator_instance.deinit() == .leak) {
|
||||
leaks += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ const utf16Literal = std.unicode.utf8ToUtf16LeStringLiteral;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer if (gpa.deinit()) @panic("found memory leaks");
|
||||
defer if (gpa.deinit() == .leak) @panic("found memory leaks");
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var it = try std.process.argsWithAllocator(allocator);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user