Switch builtins to use roc_alloc and friends

This commit is contained in:
Richard Feldman 2021-05-22 22:05:19 -04:00
parent 8cafabc0c9
commit ab51582541
4 changed files with 299 additions and 297 deletions

View file

@ -1,5 +1,37 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
// If allocation fails, this must cxa_throw - it must not return a null pointer!
extern fn roc_alloc(alignment: usize, size: usize) callconv(.C) *c_void;
// This should never be passed a null pointer.
// If allocation fails, this must cxa_throw - it must not return a null pointer!
extern fn roc_realloc(alignment: usize, c_ptr: *c_void, new_size: usize) callconv(.C) *c_void;
// This should never be passed a null pointer.
extern fn roc_dealloc(alignment: usize, c_ptr: *c_void) callconv(.C) void;
pub fn alloc(alignment: usize, size: usize) [*]u8 {
return @ptrCast(
[*]u8,
@call(.{ .modifier = always_inline }, roc_alloc, .{ alignment, size })
);
}
pub fn realloc(alignment: usize, c_ptr: [*]u8, new_size: usize) [*]u8 {
return @ptrCast(
[*]u8,
@call(.{ .modifier = always_inline }, roc_realloc, .{ alignment, c_ptr, new_size })
);
}
pub fn dealloc(alignment: usize, c_ptr: [*]u8) void {
return @call(
.{ .modifier = always_inline },
roc_dealloc,
.{ alignment, c_ptr }
);
}
pub const Inc = fn (?[*]u8) callconv(.C) void;
pub const IncN = fn (?[*]u8, u64) callconv(.C) void;
@ -62,7 +94,6 @@ pub fn intWidth(width: IntWidth) anytype {
}
pub fn decref(
allocator: *Allocator,
alignment: usize,
bytes_or_null: ?[*]u8,
data_bytes: usize,
@ -81,7 +112,7 @@ pub fn decref(
switch (alignment) {
16 => {
if (refcount == REFCOUNT_ONE_ISIZE) {
allocator.free((bytes - 16)[0 .. 16 + data_bytes]);
dealloc(alignment, bytes - 16);
} else if (refcount_isize < 0) {
(isizes - 1)[0] = refcount - 1;
}
@ -89,7 +120,7 @@ pub fn decref(
else => {
// NOTE enums can currently have an alignment of < 8
if (refcount == REFCOUNT_ONE_ISIZE) {
allocator.free((bytes - 8)[0 .. 8 + data_bytes]);
dealloc(alignment, bytes - 8);
} else if (refcount_isize < 0) {
(isizes - 1)[0] = refcount - 1;
}
@ -98,7 +129,6 @@ pub fn decref(
}
pub fn allocateWithRefcount(
allocator: *Allocator,
alignment: usize,
data_bytes: usize,
) [*]u8 {
@ -108,7 +138,7 @@ pub fn allocateWithRefcount(
16 => {
const length = 2 * @sizeOf(usize) + data_bytes;
var new_bytes: []align(16) u8 = allocator.alignedAlloc(u8, 16, length) catch unreachable;
var new_bytes: [*]align(16) u8 = @alignCast(16, alloc(alignment, length));
var as_usize_array = @ptrCast([*]usize, new_bytes);
if (result_in_place) {
@ -127,13 +157,13 @@ pub fn allocateWithRefcount(
else => {
const length = @sizeOf(usize) + data_bytes;
var new_bytes: []align(8) u8 = allocator.alignedAlloc(u8, 8, length) catch unreachable;
var new_bytes: [*]align(8) u8 = @alignCast(8, alloc(alignment, length));
var as_usize_array = @ptrCast([*]isize, new_bytes);
var as_isize_array = @ptrCast([*]isize, new_bytes);
if (result_in_place) {
as_usize_array[0] = @intCast(isize, number_of_slots);
as_isize_array[0] = @intCast(isize, number_of_slots);
} else {
as_usize_array[0] = REFCOUNT_ONE_ISIZE;
as_isize_array[0] = REFCOUNT_ONE_ISIZE;
}
var as_u8_array = @ptrCast([*]u8, new_bytes);
@ -146,7 +176,6 @@ pub fn allocateWithRefcount(
pub fn unsafeReallocate(
source_ptr: [*]u8,
allocator: *Allocator,
alignment: usize,
old_length: usize,
new_length: usize,
@ -165,8 +194,8 @@ pub fn unsafeReallocate(
// TODO handle out of memory
// NOTE realloc will dealloc the original allocation
const old_allocation = (source_ptr - align_width)[0..old_width];
const new_allocation = allocator.realloc(old_allocation, new_width) catch unreachable;
const old_allocation = source_ptr - align_width;
const new_allocation = realloc(alignment, old_allocation, new_width);
const new_source = @ptrCast([*]u8, new_allocation) + align_width;
return new_source;