mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
simplify/optimize decref logic
This commit is contained in:
parent
7aac6b6750
commit
4e39543054
@ -105,14 +105,13 @@ pub const IntWidth = enum(u8) {
|
||||
};
|
||||
|
||||
pub fn decrefC(
|
||||
bytes_or_null: ?[*]u8,
|
||||
data_bytes: usize,
|
||||
bytes_or_null: ?[*]isize,
|
||||
alignment: u32,
|
||||
) callconv(.C) void {
|
||||
// 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)
|
||||
if (bytes_or_null) |bytes| {
|
||||
return @call(.{ .modifier = always_inline }, decref, .{ bytes + @sizeOf(usize), data_bytes, alignment });
|
||||
return @call(.{ .modifier = always_inline }, decref_ptr_to_refcount, .{ bytes, alignment });
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,39 +128,20 @@ pub fn decref(
|
||||
|
||||
const isizes: [*]isize = @ptrCast([*]isize, @alignCast(@sizeOf(isize), bytes));
|
||||
|
||||
const refcount = (isizes - 1)[0];
|
||||
const refcount_isize = @bitCast(isize, refcount);
|
||||
decref_ptr_to_refcount(isizes - 1, alignment);
|
||||
}
|
||||
|
||||
switch (alignment) {
|
||||
16 => {
|
||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
||||
dealloc(bytes - 16, alignment);
|
||||
} else if (refcount_isize < 0) {
|
||||
(isizes - 1)[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;
|
||||
}
|
||||
},
|
||||
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));
|
||||
|
||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||
} else if (refcount < 0) {
|
||||
refcount_ptr[0] = refcount - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,18 +220,14 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
||||
|
||||
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(
|
||||
env,
|
||||
&[
|
||||
env.builder.build_bitcast(
|
||||
parent.get_nth_param(0).unwrap(),
|
||||
env.context.i8_type().ptr_type(AddressSpace::Generic),
|
||||
env.ptr_int().ptr_type(AddressSpace::Generic),
|
||||
"foo",
|
||||
),
|
||||
data_bytes.into(),
|
||||
alignment.into(),
|
||||
],
|
||||
roc_builtins::bitcode::UTILS_DECREF,
|
||||
|
Loading…
Reference in New Issue
Block a user