Currently, the signature of roc_alloc is (size: usize, alignment: u32) [*]u8
(zig syntax).
The argument alignment
is currently not used by most platforms, since most platforms just use malloc
. And malloc
does not have an alignment argument, but always uses the "fundamental alignment". I am not absolutely sure, what the fundamental alignment is, I think, it is 16 bytes?
In Zig, there is the function allocation.alignedAlloc()
that takes an alignment value. But this value has to be comptime. So it can not use a variable alignment from roc. So a zig-platform has to use an alignment of 16 to support all types (for example List U128
.
My question is, is it useful for roc_alloc
to have the argument alignment
if neither malloc
nor zig can use it?
My argument is fault. It is possible to use the argument in zig:
export fn roc_alloc(size: usize, alignment: u32) [*]u8 {
var mem: []u8 = undefined;
if (alignment <= 8) {
mem = allocator.alignedAlloc(u8, 8, size) catch std.debug.panic("roc_alloc: OOM", .{});
} else {
mem = allocator.alignedAlloc(u8, 16, size) catch std.debug.panic("roc_alloc: OOM", .{});
}
return mem.ptr;
}
Interesting that it is comptime zig. I guess that is the normal case
Also, yeah, for simplicity, one can always fall back on 16 bytes. That said, denser allocations can be done. Saves a lot of space in arenas for example if everything is packed as tight as alignment allows
At the moment, the value of alignment is at least 8 (maybe usize, I am on a 64 system). Even for a type like List U8
. Could/Should this be changed?
Oh yeah, I always forget that all of our allocations are refcounted so they contain a usize....
So savings of at most 8 bytes per allocations in roc if you don't align to 16 all the time
Was there a discussion to put the ref counts to a different place? This would be an argument to do this.
It's like the idea to put attributes in different arrays to get a better memory layout. It seems wrong that every roc object on the heap needs 8 bytes to save a very small number.
refcounts need to be on the heap. That said, we could:
Also, to be fair, most objects on the heap in roc are dynamically sized and can get quite large (list and str). Everything else tends to be on the stack.
boxing is pretty dang rare (and recursive tags are uncommon but definitely used)
Last updated: Jul 05 2025 at 12:14 UTC