Add Leak Detection to Ona Heap Allocator #15

Merged
kayomn merged 12 commits from ona-allocator-safety-tracker into main 2023-06-04 16:07:47 +02:00
1 changed files with 25 additions and 24 deletions
Showing only changes of commit 3794259949 - Show all commits

View File

@ -170,13 +170,13 @@ pub fn check(self: *Self, condition: bool, failure_message: []const u8) !void {
}
pub fn deinit(self: *Self) void {
self.discard(.{.object = self.global_object});
self.object_release(self.global_object);
{
var interned_iterable = InternTable.Iterable{.hashed_map = &self.interned};
while (interned_iterable.next()) |entry| {
self.discard(.{.object = entry.value});
self.object_release(entry.value);
kayomn marked this conversation as resolved Outdated

Perhaps discard could have an internal complimentary function specifically for discarding objects to save on the effort of wrapping a known type in a discriminated union only to unwrap it again back to the known type.

Perhaps `discard` could have an internal complimentary function specifically for discarding objects to save on the effort of wrapping a known type in a discriminated union only to unwrap it again back to the known type.
}
}
@ -189,28 +189,7 @@ pub fn deinit(self: *Self) void {
pub fn discard(self: *Self, val: types.Val) void {
switch (val) {
.object => |object| {
var data = self.heap.fetch(object);
coral.debug.assert(data.ref_count != 0);
data.ref_count -= 1;
if (data.ref_count == 0) {
data.state.info.deinitializer(.{
.env = self,
.obj = val.as_ref(),
});
// TODO: Free individual key-value pairs of fields
data.state.fields.deinit(self.allocator);
coral.io.deallocate(self.allocator, data.state.userdata);
self.heap.remove(object);
} else {
self.heap.assign(object, data);
}
},
.object => |object| self.object_release(object),
else => {},
}
}
@ -417,6 +396,28 @@ pub fn new_string(self: *Self, data: []const u8) coral.io.AllocationError!types.
});
}
pub fn object_release(self: *Self, object: types.Object) void {
var data = self.heap.fetch(object);
coral.debug.assert(data.ref_count != 0);
data.ref_count -= 1;
if (data.ref_count == 0) {
data.state.info.deinitializer(.{
.env = self,
.obj = .{.object = object},
});
// TODO: Free individual key-value pairs of fields
data.state.fields.deinit(self.allocator);
coral.io.deallocate(self.allocator, data.state.userdata);
self.heap.remove(object);
} else {
self.heap.assign(object, data);
}
}
pub fn set_global(self: *Self, global_name: []const u8, value: types.Ref) coral.io.AllocationError!void {
try self.globals.assign(self.allocator, global_name, value);
}