fix that inc on list was no longer recursive

This commit is contained in:
Folkert 2023-05-03 01:03:09 +02:00
parent dc77c702c5
commit 05a9b4d601
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
3 changed files with 47 additions and 18 deletions

View file

@ -1,7 +1,10 @@
const std = @import("std");
const builtin = @import("builtin");
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
const Monotonic = std.builtin.AtomicOrder.Monotonic;
const DEBUG_INCDEC = false;
pub fn WithOverflow(comptime T: type) type {
return extern struct { value: T, has_overflowed: bool };
}
@ -40,7 +43,6 @@ fn testing_roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int
}
comptime {
const builtin = @import("builtin");
// During tests, use the testing allocators to satisfy these functions.
if (builtin.is_test) {
@export(testing_roc_alloc, .{ .name = "roc_alloc", .linkage = .Strong });
@ -156,7 +158,18 @@ pub fn increfRcPtrC(ptr_to_refcount: *isize, amount: isize) callconv(.C) void {
// As such, we do not need to cap incrementing.
switch (RC_TYPE) {
Refcount.normal => {
const old = @intCast(usize, ptr_to_refcount.*);
ptr_to_refcount.* += amount;
const new = @intCast(usize, ptr_to_refcount.*);
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
const stdout = std.io.getStdOut().writer();
const oldH = old - REFCOUNT_ONE + 1;
const newH = new - REFCOUNT_ONE + 1;
stdout.print("| increment {*}: {} + {} = {}!\n", .{ ptr_to_refcount, oldH, amount, newH }) catch unreachable;
}
},
Refcount.atomic => {
_ = @atomicRmw(isize, ptr_to_refcount, std.builtin.AtomicRmwOp.Add, amount, Monotonic);
@ -246,7 +259,19 @@ inline fn decref_ptr_to_refcount(
if (refcount != REFCOUNT_MAX_ISIZE) {
switch (RC_TYPE) {
Refcount.normal => {
const old = @intCast(usize, refcount);
refcount_ptr[0] = refcount -% 1;
const new = @intCast(usize, refcount -% 1);
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
const stdout = std.io.getStdOut().writer();
const oldH = old - REFCOUNT_ONE + 1;
const newH = new - REFCOUNT_ONE + 1;
stdout.print("| decrement {*}: {} - 1 = {}!\n", .{ refcount_ptr, oldH, newH }) catch unreachable;
}
if (refcount == REFCOUNT_ONE_ISIZE) {
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
}

View file

@ -45,6 +45,10 @@ impl HelperOp {
fn is_dec(&self) -> bool {
matches!(self, Self::Dec)
}
fn is_inc(&self) -> bool {
matches!(self, Self::Inc)
}
}
#[derive(Debug)]

View file

@ -860,23 +860,23 @@ fn refcount_list<'a>(
arena.alloc(ret_stmt),
);
let modify_elems_and_list =
if layout_interner.get(elem_layout).is_refcounted() && ctx.op.is_dec() {
refcount_list_elems(
root,
ident_ids,
ctx,
layout_interner,
elem_layout,
LAYOUT_UNIT,
box_layout,
len,
elements,
modify_list,
)
} else {
modify_list
};
let relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
let modify_elems_and_list = if relevant_op && layout_interner.get(elem_layout).is_refcounted() {
refcount_list_elems(
root,
ident_ids,
ctx,
layout_interner,
elem_layout,
LAYOUT_UNIT,
box_layout,
len,
elements,
modify_list,
)
} else {
modify_list
};
//
// Do nothing if the list is empty