mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge remote-tracking branch 'origin/trunk' into linux-32-bit
This commit is contained in:
commit
2931427870
3 changed files with 30 additions and 70 deletions
|
@ -125,6 +125,7 @@ pub fn gen_from_mono_module(
|
||||||
|| name.starts_with("roc_builtins.dec")
|
|| name.starts_with("roc_builtins.dec")
|
||||||
|| name.starts_with("list.RocList")
|
|| name.starts_with("list.RocList")
|
||||||
|| name.starts_with("dict.RocDict")
|
|| name.starts_with("dict.RocDict")
|
||||||
|
|| name.contains("decref")
|
||||||
{
|
{
|
||||||
function.add_attribute(AttributeLoc::Function, enum_attr);
|
function.add_attribute(AttributeLoc::Function, enum_attr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,15 +105,16 @@ pub const IntWidth = enum(u8) {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn decrefC(
|
pub fn decrefC(
|
||||||
bytes_or_null: ?[*]u8,
|
bytes_or_null: ?[*]isize,
|
||||||
data_bytes: usize,
|
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
) callconv(.C) void {
|
) callconv(.C) void {
|
||||||
// IMPORTANT: bytes_or_null is this case is expected to be a pointer to the refcount
|
// IMPORTANT: bytes_or_null is this case is expected to be a pointer to the refcount
|
||||||
// (NOT the start of the data, or the start of the allocation)
|
// (NOT the start of the data, or the start of the allocation)
|
||||||
if (bytes_or_null) |bytes| {
|
|
||||||
return @call(.{ .modifier = always_inline }, decref, .{ bytes + @sizeOf(usize), data_bytes, alignment });
|
// this is of course unsafe, but we trust what we get from the llvm side
|
||||||
}
|
var bytes = @ptrCast([*]isize, bytes_or_null);
|
||||||
|
|
||||||
|
return @call(.{ .modifier = always_inline }, decref_ptr_to_refcount, .{ bytes, alignment });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decref(
|
pub fn decref(
|
||||||
|
@ -129,39 +130,20 @@ pub fn decref(
|
||||||
|
|
||||||
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@sizeOf(isize), bytes));
|
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@sizeOf(isize), bytes));
|
||||||
|
|
||||||
const refcount = (isizes - 1)[0];
|
decref_ptr_to_refcount(isizes - 1, alignment);
|
||||||
const refcount_isize = @bitCast(isize, refcount);
|
}
|
||||||
|
|
||||||
|
inline fn decref_ptr_to_refcount(
|
||||||
|
refcount_ptr: [*]isize,
|
||||||
|
alignment: u32,
|
||||||
|
) void {
|
||||||
|
const refcount: isize = refcount_ptr[0];
|
||||||
|
const extra_bytes = std.math.max(alignment, @sizeOf(usize));
|
||||||
|
|
||||||
switch (alignment) {
|
|
||||||
16 => {
|
|
||||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
if (refcount == REFCOUNT_ONE_ISIZE) {
|
||||||
dealloc(bytes - 16, alignment);
|
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||||
} else if (refcount_isize < 0) {
|
} else if (refcount < 0) {
|
||||||
(isizes - 1)[0] = refcount - 1;
|
refcount_ptr[0] = refcount - 1;
|
||||||
}
|
|
||||||
},
|
|
||||||
8 => {
|
|
||||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
|
||||||
dealloc(bytes - 8, alignment);
|
|
||||||
} else if (refcount_isize < 0) {
|
|
||||||
(isizes - 1)[0] = refcount - 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
4 => {
|
|
||||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
|
||||||
dealloc(bytes - 4, alignment);
|
|
||||||
} else if (refcount_isize < 0) {
|
|
||||||
(isizes - 1)[0] = refcount - 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
else => {
|
|
||||||
// NOTE enums can currently have an alignment of < 8
|
|
||||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
|
||||||
dealloc(bytes - 8, alignment);
|
|
||||||
} else if (refcount_isize < 0) {
|
|
||||||
(isizes - 1)[0] = refcount - 1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,25 +151,17 @@ pub fn allocateWithRefcount(
|
||||||
data_bytes: usize,
|
data_bytes: usize,
|
||||||
element_alignment: u32,
|
element_alignment: u32,
|
||||||
) [*]u8 {
|
) [*]u8 {
|
||||||
const result_in_place = false;
|
|
||||||
|
|
||||||
const alignment = std.math.max(@sizeOf(usize), element_alignment);
|
const alignment = std.math.max(@sizeOf(usize), element_alignment);
|
||||||
const first_slot_offset = std.math.max(@sizeOf(usize), element_alignment);
|
const first_slot_offset = std.math.max(@sizeOf(usize), element_alignment);
|
||||||
|
const length = alignment + data_bytes;
|
||||||
|
|
||||||
switch (alignment) {
|
switch (alignment) {
|
||||||
16 => {
|
16 => {
|
||||||
const length = 16 + data_bytes;
|
|
||||||
|
|
||||||
var new_bytes: [*]align(16) u8 = @alignCast(16, alloc(length, alignment));
|
var new_bytes: [*]align(16) u8 = @alignCast(16, alloc(length, alignment));
|
||||||
|
|
||||||
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
var as_usize_array = @ptrCast([*]usize, new_bytes);
|
||||||
if (result_in_place) {
|
|
||||||
as_usize_array[0] = 0;
|
|
||||||
as_usize_array[1] = @intCast(usize, number_of_slots);
|
|
||||||
} else {
|
|
||||||
as_usize_array[0] = 0;
|
as_usize_array[0] = 0;
|
||||||
as_usize_array[1] = REFCOUNT_ONE;
|
as_usize_array[1] = REFCOUNT_ONE;
|
||||||
}
|
|
||||||
|
|
||||||
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
||||||
const first_slot = as_u8_array + first_slot_offset;
|
const first_slot = as_u8_array + first_slot_offset;
|
||||||
|
@ -195,17 +169,11 @@ pub fn allocateWithRefcount(
|
||||||
return first_slot;
|
return first_slot;
|
||||||
},
|
},
|
||||||
8 => {
|
8 => {
|
||||||
const length = 8 + data_bytes;
|
|
||||||
|
|
||||||
var raw = alloc(length, alignment);
|
var raw = alloc(length, alignment);
|
||||||
var new_bytes: [*]align(8) u8 = @alignCast(8, raw);
|
var new_bytes: [*]align(8) u8 = @alignCast(8, raw);
|
||||||
|
|
||||||
var as_isize_array = @ptrCast([*]isize, new_bytes);
|
var as_isize_array = @ptrCast([*]isize, new_bytes);
|
||||||
if (result_in_place) {
|
|
||||||
as_isize_array[0] = @intCast(isize, number_of_slots);
|
|
||||||
} else {
|
|
||||||
as_isize_array[0] = REFCOUNT_ONE_ISIZE;
|
as_isize_array[0] = REFCOUNT_ONE_ISIZE;
|
||||||
}
|
|
||||||
|
|
||||||
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
||||||
const first_slot = as_u8_array + first_slot_offset;
|
const first_slot = as_u8_array + first_slot_offset;
|
||||||
|
@ -213,17 +181,11 @@ pub fn allocateWithRefcount(
|
||||||
return first_slot;
|
return first_slot;
|
||||||
},
|
},
|
||||||
4 => {
|
4 => {
|
||||||
const length = 4 + data_bytes;
|
|
||||||
|
|
||||||
var raw = alloc(length, alignment);
|
var raw = alloc(length, alignment);
|
||||||
var new_bytes: [*]align(@alignOf(isize)) u8 = @alignCast(@alignOf(isize), raw);
|
var new_bytes: [*]align(@alignOf(isize)) u8 = @alignCast(@alignOf(isize), raw);
|
||||||
|
|
||||||
var as_isize_array = @ptrCast([*]isize, new_bytes);
|
var as_isize_array = @ptrCast([*]isize, new_bytes);
|
||||||
if (result_in_place) {
|
|
||||||
as_isize_array[0] = @intCast(isize, number_of_slots);
|
|
||||||
} else {
|
|
||||||
as_isize_array[0] = REFCOUNT_ONE_ISIZE;
|
as_isize_array[0] = REFCOUNT_ONE_ISIZE;
|
||||||
}
|
|
||||||
|
|
||||||
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
var as_u8_array = @ptrCast([*]u8, new_bytes);
|
||||||
const first_slot = as_u8_array + first_slot_offset;
|
const first_slot = as_u8_array + first_slot_offset;
|
||||||
|
@ -231,9 +193,10 @@ pub fn allocateWithRefcount(
|
||||||
return first_slot;
|
return first_slot;
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
const stdout = std.io.getStdOut().writer();
|
// const stdout = std.io.getStdOut().writer();
|
||||||
stdout.print("alignment: {d}", .{alignment}) catch unreachable;
|
// stdout.print("alignment: {d}", .{alignment}) catch unreachable;
|
||||||
@panic("allocateWithRefcount with invalid alignment");
|
// @panic("allocateWithRefcount with invalid alignment");
|
||||||
|
unreachable;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,18 +220,14 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
||||||
|
|
||||||
let alignment = env.context.i32_type().const_int(alignment as _, false);
|
let alignment = env.context.i32_type().const_int(alignment as _, false);
|
||||||
|
|
||||||
// has to be non-zero, or the deallocation is skipped
|
|
||||||
let data_bytes = env.ptr_int().const_int(1, false);
|
|
||||||
|
|
||||||
call_void_bitcode_fn(
|
call_void_bitcode_fn(
|
||||||
env,
|
env,
|
||||||
&[
|
&[
|
||||||
env.builder.build_bitcast(
|
env.builder.build_bitcast(
|
||||||
parent.get_nth_param(0).unwrap(),
|
parent.get_nth_param(0).unwrap(),
|
||||||
env.context.i8_type().ptr_type(AddressSpace::Generic),
|
env.ptr_int().ptr_type(AddressSpace::Generic),
|
||||||
"foo",
|
"foo",
|
||||||
),
|
),
|
||||||
data_bytes.into(),
|
|
||||||
alignment.into(),
|
alignment.into(),
|
||||||
],
|
],
|
||||||
roc_builtins::bitcode::UTILS_DECREF,
|
roc_builtins::bitcode::UTILS_DECREF,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue