aboutsummaryrefslogtreecommitdiff
path: root/src/mimalloc_arena.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/mimalloc_arena.zig65
1 files changed, 64 insertions, 1 deletions
diff --git a/src/mimalloc_arena.zig b/src/mimalloc_arena.zig
index 2de5ce018..37ea2ecc3 100644
--- a/src/mimalloc_arena.zig
+++ b/src/mimalloc_arena.zig
@@ -73,6 +73,60 @@ pub const GlobalArena = struct {
}
};
+const ArenaRegistry = struct {
+ arenas: std.AutoArrayHashMap(?*mimalloc.Heap, std.Thread.Id) = std.AutoArrayHashMap(?*mimalloc.Heap, std.Thread.Id).init(bun.default_allocator),
+ mutex: std.Thread.Mutex = .{},
+
+ var registry = ArenaRegistry{};
+
+ pub fn register(arena: Arena) void {
+ if (comptime Environment.allow_assert) {
+ registry.mutex.lock();
+ defer registry.mutex.unlock();
+ var entry = registry.arenas.getOrPut(arena.heap.?) catch unreachable;
+ const received = std.Thread.getCurrentId();
+
+ if (entry.found_existing) {
+ const expected = entry.value_ptr.*;
+ if (expected != received) {
+ bun.unreachablePanic("Arena created on wrong thread! Expected: {d} received: {d}", .{
+ expected,
+ received,
+ });
+ }
+ }
+ entry.value_ptr.* = received;
+ }
+ }
+
+ pub fn assert(arena: Arena) void {
+ if (comptime Environment.allow_assert) {
+ registry.mutex.lock();
+ defer registry.mutex.unlock();
+ const expected = registry.arenas.get(arena.heap.?) orelse {
+ bun.unreachablePanic("Arena not registered!", .{});
+ };
+ const received = std.Thread.getCurrentId();
+ if (expected != received) {
+ bun.unreachablePanic("Arena accessed on wrong thread! Expected: {d} received: {d}", .{
+ expected,
+ received,
+ });
+ }
+ }
+ }
+
+ pub fn unregister(arena: Arena) void {
+ if (comptime Environment.allow_assert) {
+ registry.mutex.lock();
+ defer registry.mutex.unlock();
+ if (!registry.arenas.swapRemove(arena.heap.?)) {
+ bun.unreachablePanic("Arena not registered!", .{});
+ }
+ }
+ }
+};
+
pub const Arena = struct {
heap: ?*mimalloc.Heap = null,
@@ -95,6 +149,9 @@ pub const Arena = struct {
}
pub fn deinit(this: *Arena) void {
+ if (comptime Environment.allow_assert) {
+ ArenaRegistry.unregister(this.*);
+ }
mimalloc.mi_heap_destroy(this.heap.?);
this.heap = null;
@@ -128,7 +185,11 @@ pub const Arena = struct {
}
pub fn init() !Arena {
- return Arena{ .heap = mimalloc.mi_heap_new() orelse return error.OutOfMemory };
+ const arena = Arena{ .heap = mimalloc.mi_heap_new() orelse return error.OutOfMemory };
+ if (comptime Environment.allow_assert) {
+ ArenaRegistry.register(arena);
+ }
+ return arena;
}
pub fn gc(this: Arena, force: bool) void {
@@ -167,6 +228,8 @@ pub const Arena = struct {
fn alloc(arena: *anyopaque, len: usize, ptr_align: u8, _: usize) ?[*]u8 {
var this = bun.cast(*mimalloc.Heap, arena);
+ // if (comptime Environment.allow_assert)
+ // ArenaRegistry.assert(.{ .heap = this });
return alignedAlloc(this, len, ptr_align);
}