mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +00:00
Updated refcount logic
This commit is contained in:
parent
0fe94cbd90
commit
74f2b0afda
4 changed files with 29 additions and 71 deletions
|
@ -231,9 +231,9 @@ inline fn decref_ptr_to_refcount(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub export fn isUnique(
|
pub fn isUnique(
|
||||||
bytes_or_null: ?[*]u8,
|
bytes_or_null: ?[*]u8,
|
||||||
) bool {
|
) callconv(.C) bool {
|
||||||
var bytes = bytes_or_null orelse return true;
|
var bytes = bytes_or_null orelse return true;
|
||||||
|
|
||||||
const ptr = @ptrToInt(bytes);
|
const ptr = @ptrToInt(bytes);
|
||||||
|
|
|
@ -1252,8 +1252,15 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
RefCountIsUnique => {
|
RefCountIsUnique => {
|
||||||
arguments!(input);
|
arguments!(data_ptr);
|
||||||
call_bitcode_fn(env, &[input], &bitcode::UTILS_IS_UNIQUE)
|
|
||||||
|
let ptr = env.builder.build_pointer_cast(
|
||||||
|
data_ptr.into_pointer_value(),
|
||||||
|
env.context.i8_type().ptr_type(AddressSpace::default()),
|
||||||
|
"cast_to_i8_ptr",
|
||||||
|
);
|
||||||
|
|
||||||
|
call_bitcode_fn(env, &[ptr.into()], &bitcode::UTILS_IS_UNIQUE)
|
||||||
}
|
}
|
||||||
|
|
||||||
Unreachable => match RocReturn::from_layout(env, layout_interner, layout) {
|
Unreachable => match RocReturn::from_layout(env, layout_interner, layout) {
|
||||||
|
|
|
@ -194,11 +194,8 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
layout: InLayout<'a>,
|
layout: InLayout<'a>,
|
||||||
structure: Symbol,
|
structure: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
let rc_ptr = root.create_symbol(ident_ids, "rc_ptr");
|
|
||||||
let rc = root.create_symbol(ident_ids, "rc");
|
|
||||||
let refcount_1 = root.create_symbol(ident_ids, "refcount_1");
|
|
||||||
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
|
||||||
let addr = root.create_symbol(ident_ids, "addr");
|
let addr = root.create_symbol(ident_ids, "addr");
|
||||||
|
let is_unique = root.create_symbol(ident_ids, "is_unique");
|
||||||
|
|
||||||
let union_layout = match layout_interner.get(layout) {
|
let union_layout = match layout_interner.get(layout) {
|
||||||
Layout::Union(u) => u,
|
Layout::Union(u) => u,
|
||||||
|
@ -208,7 +205,6 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
// Whenever we recurse into a child layout we will want to Decrement
|
// Whenever we recurse into a child layout we will want to Decrement
|
||||||
ctx.op = HelperOp::Dec;
|
ctx.op = HelperOp::Dec;
|
||||||
ctx.recursive_union = Some(union_layout);
|
ctx.recursive_union = Some(union_layout);
|
||||||
let recursion_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
|
|
||||||
|
|
||||||
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
||||||
let then_stmt = {
|
let then_stmt = {
|
||||||
|
@ -313,69 +309,26 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let if_stmt = Stmt::Switch {
|
let if_stmt = root.arena.alloc(Stmt::Switch {
|
||||||
cond_symbol: is_unique,
|
cond_symbol: is_unique,
|
||||||
cond_layout: LAYOUT_BOOL,
|
cond_layout: LAYOUT_BOOL,
|
||||||
branches: root.arena.alloc([(1, BranchInfo::None, then_stmt)]),
|
branches: root.arena.alloc([(1, BranchInfo::None, then_stmt)]),
|
||||||
default_branch: (BranchInfo::None, root.arena.alloc(else_stmt)),
|
default_branch: (BranchInfo::None, root.arena.alloc(else_stmt)),
|
||||||
ret_layout: layout,
|
ret_layout: layout,
|
||||||
};
|
});
|
||||||
|
|
||||||
// Uniqueness test
|
Stmt::Let(
|
||||||
let is_unique_stmt = {
|
is_unique,
|
||||||
let_lowlevel(
|
Expr::Call(Call {
|
||||||
root.arena,
|
call_type: CallType::LowLevel {
|
||||||
LAYOUT_BOOL,
|
op: LowLevel::RefCountIsUnique,
|
||||||
is_unique,
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
Eq,
|
},
|
||||||
&[rc, refcount_1],
|
arguments: root.arena.alloc([structure]),
|
||||||
root.arena.alloc(if_stmt),
|
}),
|
||||||
)
|
Layout::BOOL,
|
||||||
};
|
if_stmt,
|
||||||
|
)
|
||||||
// Constant for unique refcount
|
|
||||||
let refcount_1_encoded = match root.target_info.ptr_width() {
|
|
||||||
PtrWidth::Bytes4 => i32::MIN as i128,
|
|
||||||
PtrWidth::Bytes8 => i64::MIN as i128,
|
|
||||||
}
|
|
||||||
.to_ne_bytes();
|
|
||||||
let refcount_1_expr = Expr::Literal(Literal::Int(refcount_1_encoded));
|
|
||||||
let refcount_1_stmt = Stmt::Let(
|
|
||||||
refcount_1,
|
|
||||||
refcount_1_expr,
|
|
||||||
root.layout_isize,
|
|
||||||
root.arena.alloc(is_unique_stmt),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Refcount value
|
|
||||||
let rc_expr = Expr::UnionAtIndex {
|
|
||||||
structure: rc_ptr,
|
|
||||||
tag_id: 0,
|
|
||||||
union_layout: root.union_refcount,
|
|
||||||
index: 0,
|
|
||||||
};
|
|
||||||
let rc_stmt = Stmt::Let(
|
|
||||||
rc,
|
|
||||||
rc_expr,
|
|
||||||
root.layout_isize,
|
|
||||||
root.arena.alloc(refcount_1_stmt),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Refcount pointer
|
|
||||||
let rc_ptr_stmt = {
|
|
||||||
rc_ptr_from_data_ptr_help(
|
|
||||||
root,
|
|
||||||
ident_ids,
|
|
||||||
structure,
|
|
||||||
rc_ptr,
|
|
||||||
union_layout.stores_tag_id_in_pointer(root.target_info),
|
|
||||||
root.arena.alloc(rc_stmt),
|
|
||||||
addr,
|
|
||||||
recursion_ptr,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
rc_ptr_stmt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refcount_resetref_proc_body<'a>(
|
pub fn refcount_resetref_proc_body<'a>(
|
||||||
|
|
|
@ -326,9 +326,7 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
symbol,
|
symbol,
|
||||||
continuation,
|
continuation,
|
||||||
),
|
),
|
||||||
Layout::LambdaSet(_) => {
|
// TODO: lambda sets should not be reachable, yet they are.
|
||||||
unreachable!("lambda sets should not be a runtime layout")
|
|
||||||
}
|
|
||||||
// TODO: Implement this with uniqueness checks.
|
// TODO: Implement this with uniqueness checks.
|
||||||
_ => {
|
_ => {
|
||||||
let new_continuation = specialize_drops_stmt(
|
let new_continuation = specialize_drops_stmt(
|
||||||
|
@ -905,8 +903,8 @@ where
|
||||||
let join = arena.alloc(Stmt::Join {
|
let join = arena.alloc(Stmt::Join {
|
||||||
id: join_id,
|
id: join_id,
|
||||||
parameters: arena.alloc([]),
|
parameters: arena.alloc([]),
|
||||||
body: switch,
|
body: continutation,
|
||||||
remainder: continutation,
|
remainder: switch,
|
||||||
});
|
});
|
||||||
|
|
||||||
join
|
join
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue