diff --git a/compiler/builtins/bitcode/src/utils.zig b/compiler/builtins/bitcode/src/utils.zig index 810d75b27f..c9f03d897a 100644 --- a/compiler/builtins/bitcode/src/utils.zig +++ b/compiler/builtins/bitcode/src/utils.zig @@ -120,10 +120,16 @@ pub const IntWidth = enum(u8) { I128 = 9, }; +const USE_ATOMICS = false; + pub fn increfC(ptr_to_refcount: *isize, amount: isize) callconv(.C) void { var refcount = ptr_to_refcount.*; - var masked_amount = if (refcount == REFCOUNT_MAX_ISIZE) 0 else amount; - ptr_to_refcount.* = refcount + masked_amount; + var masked_amount = if (refcount < REFCOUNT_MAX_ISIZE) amount else 0; + if (USE_ATOMICS) { + var last = @atomicRmw(isize, ptr_to_refcount, std.builtin.AtomicRmwOp.Add, masked_amount, std.builtin.AtomicOrder.Monotonic); + } else { + ptr_to_refcount.* = refcount + masked_amount; + } } pub fn decrefC( @@ -169,13 +175,20 @@ 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; + if (USE_ATOMICS) { + var amount : isize = if (refcount_ptr[0] < REFCOUNT_MAX_ISIZE) 1 else 0; + var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, amount, std.builtin.AtomicOrder.Monotonic); + if (last == REFCOUNT_ONE_ISIZE) { + dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment); + } + } else { + const refcount: isize = refcount_ptr[0]; + if (refcount == REFCOUNT_ONE_ISIZE) { + dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment); + } else if (refcount < REFCOUNT_MAX_ISIZE) { + refcount_ptr[0] = refcount - 1; + } } }