From 6b99bb6f7f63e8417042220a6c02eb43d48803d5 Mon Sep 17 00:00:00 2001 From: Talha Qamar <qamartalha@proton.me> Date: Fri, 31 Jan 2025 21:17:28 +0500 Subject: [PATCH] Added Arena Allocator (crime against humanity) --- src/lily/alloc/arena.hb | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/lily/alloc/arena.hb diff --git a/src/lily/alloc/arena.hb b/src/lily/alloc/arena.hb new file mode 100644 index 0000000..908a059 --- /dev/null +++ b/src/lily/alloc/arena.hb @@ -0,0 +1,62 @@ +.{Config, Target, Type, log, collections: .{Vec}} := @use("../lib.hb"); + +Allocation := struct { + ptr: ^u8, + len: uint, +} + +ArenaAllocator := struct { + ptr: ^u8, + size: uint, + allocated: uint, + + $new := fn(size: uint): Self { + allocated := idk + if size == 0 { + allocated = Target.page_size() + } else { + allocated = size + } + ptr := Target.alloc_zeroed(size) + return .(ptr, size, 0) + } + deinit := fn(self: ^Self): void { + match Target.current() { + .LibC => Target.dealloc(self.ptr), + .AbleOS => Target.dealloc(self.ptr, self.size), + } + log.debug("deinit: allocator") + } + alloc := fn(self: ^Self, $T: type, count: uint): ?^T { + if count * @sizeof(T) + self.allocated > self.size { + log.error("You allocated more memory on the arena than the arena had."); + die + } + allocation := self.ptr + self.allocated + self.allocated = self.allocated + count * @sizeof(T) + log.debug("allocated") + return @bitcast(allocation) + } + alloc_zeroed := fn(self: ^Self, $T: type, count: uint): ?^T { + return self.alloc(T, count) + } + realloc := fn(self: ^Self, $T: type, ptr: ^T, count: uint): ?^T { + log.error("Don't call realloc on the arena allocator"); + die + } + dealloc := fn(self: ^Self, $T: type, ptr: ^T): void { + log.debug("freed") + } + _find_and_remove := fn(self: ^Self, ptr: ^u8): ?Allocation { + i := 0 + loop if i == self.allocations.len() break else { + defer i += 1 + alloced := self.allocations.get_unchecked(i) + if alloced.ptr == ptr { + _ = self.allocations.swap_remove(i) + return alloced + } + } + return null + } +}