mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Merge pull request #5622 from roc-lang/reset-reuse-free
free or reuse unconditionally when value is unique
This commit is contained in:
commit
0ade2a85d2
37 changed files with 583 additions and 295 deletions
|
@ -195,8 +195,10 @@ comptime {
|
|||
exportUtilsFn(utils.test_panic, "test_panic");
|
||||
exportUtilsFn(utils.increfRcPtrC, "incref_rc_ptr");
|
||||
exportUtilsFn(utils.decrefRcPtrC, "decref_rc_ptr");
|
||||
exportUtilsFn(utils.freeRcPtrC, "free_rc_ptr");
|
||||
exportUtilsFn(utils.increfDataPtrC, "incref_data_ptr");
|
||||
exportUtilsFn(utils.decrefDataPtrC, "decref_data_ptr");
|
||||
exportUtilsFn(utils.freeDataPtrC, "free_data_ptr");
|
||||
exportUtilsFn(utils.isUnique, "is_unique");
|
||||
exportUtilsFn(utils.decrefCheckNullC, "decref_check_null");
|
||||
exportUtilsFn(utils.allocateWithRefcountC, "allocate_with_refcount");
|
||||
|
|
|
@ -220,6 +220,29 @@ pub fn increfDataPtrC(
|
|||
return increfRcPtrC(isizes, inc_amount);
|
||||
}
|
||||
|
||||
pub fn freeDataPtrC(
|
||||
bytes_or_null: ?[*]isize,
|
||||
alignment: u32,
|
||||
) callconv(.C) void {
|
||||
var bytes = bytes_or_null orelse return;
|
||||
|
||||
const ptr = @ptrToInt(bytes);
|
||||
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||
const masked_ptr = ptr & ~tag_mask;
|
||||
|
||||
const isizes: [*]isize = @intToPtr([*]isize, masked_ptr);
|
||||
|
||||
return freeRcPtrC(isizes - 1, alignment);
|
||||
}
|
||||
|
||||
pub fn freeRcPtrC(
|
||||
bytes_or_null: ?[*]isize,
|
||||
alignment: u32,
|
||||
) callconv(.C) void {
|
||||
var bytes = bytes_or_null orelse return;
|
||||
return free_ptr_to_refcount(bytes, alignment);
|
||||
}
|
||||
|
||||
pub fn decref(
|
||||
bytes_or_null: ?[*]u8,
|
||||
data_bytes: usize,
|
||||
|
@ -236,13 +259,23 @@ pub fn decref(
|
|||
decref_ptr_to_refcount(isizes - 1, alignment);
|
||||
}
|
||||
|
||||
inline fn decref_ptr_to_refcount(
|
||||
inline fn free_ptr_to_refcount(
|
||||
refcount_ptr: [*]isize,
|
||||
alignment: u32,
|
||||
) void {
|
||||
if (RC_TYPE == Refcount.none) return;
|
||||
const extra_bytes = std.math.max(alignment, @sizeOf(usize));
|
||||
|
||||
// NOTE: we don't even check whether the refcount is "infinity" here!
|
||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||
}
|
||||
|
||||
inline fn decref_ptr_to_refcount(
|
||||
refcount_ptr: [*]isize,
|
||||
alignment: u32,
|
||||
) void {
|
||||
if (RC_TYPE == Refcount.none) return;
|
||||
|
||||
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
||||
std.debug.print("| decrement {*}: ", .{refcount_ptr});
|
||||
}
|
||||
|
@ -264,13 +297,13 @@ inline fn decref_ptr_to_refcount(
|
|||
}
|
||||
|
||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||
free_ptr_to_refcount(refcount_ptr, alignment);
|
||||
}
|
||||
},
|
||||
Refcount.atomic => {
|
||||
var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, 1, Monotonic);
|
||||
if (last == REFCOUNT_ONE_ISIZE) {
|
||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||
free_ptr_to_refcount(refcount_ptr, alignment);
|
||||
}
|
||||
},
|
||||
Refcount.none => unreachable,
|
||||
|
|
|
@ -393,8 +393,10 @@ pub const UTILS_TEST_PANIC: &str = "roc_builtins.utils.test_panic";
|
|||
pub const UTILS_ALLOCATE_WITH_REFCOUNT: &str = "roc_builtins.utils.allocate_with_refcount";
|
||||
pub const UTILS_INCREF_RC_PTR: &str = "roc_builtins.utils.incref_rc_ptr";
|
||||
pub const UTILS_DECREF_RC_PTR: &str = "roc_builtins.utils.decref_rc_ptr";
|
||||
pub const UTILS_FREE_RC_PTR: &str = "roc_builtins.utils.free_rc_ptr";
|
||||
pub const UTILS_INCREF_DATA_PTR: &str = "roc_builtins.utils.incref_data_ptr";
|
||||
pub const UTILS_DECREF_DATA_PTR: &str = "roc_builtins.utils.decref_data_ptr";
|
||||
pub const UTILS_FREE_DATA_PTR: &str = "roc_builtins.utils.free_data_ptr";
|
||||
pub const UTILS_IS_UNIQUE: &str = "roc_builtins.utils.is_unique";
|
||||
pub const UTILS_DECREF_CHECK_NULL: &str = "roc_builtins.utils.decref_check_null";
|
||||
pub const UTILS_DICT_PSEUDO_SEED: &str = "roc_builtins.utils.dict_pseudo_seed";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue