make List.map borrow based on passed function

This commit is contained in:
Folkert 2021-05-16 14:09:39 +02:00
parent 3a4a78fdbb
commit 3ca6ffade9
8 changed files with 106 additions and 35 deletions

View File

@ -185,7 +185,7 @@ pub fn listMap(list: RocList, transform: Opaque, caller: Caller1, alignment: usi
caller(transform, source_ptr + (i * old_element_width), target_ptr + (i * new_element_width));
}
utils.decref(std.heap.c_allocator, alignment, list.bytes, size * old_element_width);
// utils.decref(std.heap.c_allocator, alignment, list.bytes, size * old_element_width);
return output;
} else {

View File

@ -145,7 +145,6 @@ fn build_transform_caller_help_new<'a, 'ctx, 'env>(
arguments_cast.push(argument);
}
dbg!(closure_data_layout);
match closure_data_layout {
Layout::FunctionPointer(_, _) => {
// do nothing

View File

@ -2287,14 +2287,30 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
DecRef(symbol) => {
let (value, layout) = load_symbol_and_layout(scope, symbol);
if layout.is_refcounted() {
if value.is_pointer_value() {
// BasicValueEnum::PointerValue(value_ptr) => {
let value_ptr = value.into_pointer_value();
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, value_ptr);
match layout {
Layout::Builtin(Builtin::List(_, _)) => {
debug_assert!(value.is_struct_value());
let refcount_ptr = PointerToRefcount::from_list_wrapper(
env,
value.into_struct_value(),
);
refcount_ptr.decrement(env, layout);
} else {
eprint!("we're likely leaking memory; see issue #985 for details");
}
_ if layout.is_refcounted() => {
if value.is_pointer_value() {
// BasicValueEnum::PointerValue(value_ptr) => {
let value_ptr = value.into_pointer_value();
let refcount_ptr =
PointerToRefcount::from_ptr_to_data(env, value_ptr);
refcount_ptr.decrement(env, layout);
} else {
eprint!("we're likely leaking memory; see issue #985 for details");
}
}
_ => {
// nothing to do
}
}

View File

@ -2048,6 +2048,13 @@ fn update<'a>(
&& state.dependencies.solved_all()
&& state.goal_phase == Phase::MakeSpecializations
{
Proc::insert_refcount_operations(arena, &mut state.procedures);
Proc::optimize_refcount_operations(
arena,
module_id,
&mut ident_ids,
&mut state.procedures,
);
// display the mono IR of the module, for debug purposes
if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS {
let procs_string = state
@ -2060,14 +2067,6 @@ fn update<'a>(
println!("{}", result);
}
Proc::insert_refcount_operations(arena, &mut state.procedures);
Proc::optimize_refcount_operations(
arena,
module_id,
&mut ident_ids,
&mut state.procedures,
);
state.constrained_ident_ids.insert(module_id, ident_ids);

View File

@ -409,14 +409,36 @@ impl<'a> BorrowInfState<'a> {
LowLevel {
op,
opt_closure_layout: _,
opt_closure_layout,
} => {
// very unsure what demand RunLowLevel should place upon its arguments
self.own_var(z);
use roc_module::low_level::LowLevel::*;
match op {
ListMap => {
match self
.param_map
.get_symbol(arguments[1], opt_closure_layout.unwrap())
{
Some(ps) => {
if !ps[0].borrow {
self.own_var(arguments[0]);
}
let ps = lowlevel_borrow_signature(self.arena, *op);
if ps.len() > 1 && !ps[1].borrow {
self.own_var(arguments[2]);
}
}
None => unreachable!(),
}
}
_ => {
// very unsure what demand RunLowLevel should place upon its arguments
self.own_var(z);
self.own_args_using_bools(arguments, ps);
let ps = lowlevel_borrow_signature(self.arena, *op);
self.own_args_using_bools(arguments, ps);
}
}
}
Foreign { .. } => {

View File

@ -538,7 +538,12 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
&*env.arena.alloc(stmt)
}
Refcounting(ModifyRc::DecRef(_symbol), _cont) => unreachable!("not introduced yet"),
Refcounting(ModifyRc::DecRef(symbol), cont) => {
// decref the current cell
env.deferred.decrefs.push(*symbol);
expand_and_cancel(env, cont)
}
Refcounting(ModifyRc::Dec(symbol), cont) => {
use ConstructorLayout::*;

View File

@ -1,4 +1,4 @@
use crate::borrow::ParamMap;
use crate::borrow::{ParamMap, BORROWED, OWNED};
use crate::ir::{Expr, JoinPointId, ModifyRc, Param, Proc, Stmt};
use crate::layout::Layout;
use bumpalo::collections::Vec;
@ -443,18 +443,48 @@ impl<'a> Context<'a> {
match &call_type {
LowLevel {
op,
opt_closure_layout: _,
} => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
opt_closure_layout,
} => match op {
roc_module::low_level::LowLevel::ListMap => {
match self
.param_map
.get_symbol(arguments[1], opt_closure_layout.unwrap())
{
Some(ps) => {
let b = if ps[0].borrow {
let ps = [BORROWED, BORROWED, BORROWED];
self.add_dec_after_lowlevel(arguments, &ps, b, b_live_vars)
} else {
// let ps = [OWNED, BORROWED, BORROWED];
// self.add_dec_after_lowlevel(arguments, &ps, b, b_live_vars)
self.arena.alloc(Stmt::Refcounting(
ModifyRc::DecRef(arguments[0]),
self.arena.alloc(b),
))
};
let v = Expr::Call(crate::ir::Call {
call_type,
arguments,
});
let v = Expr::Call(crate::ir::Call {
call_type,
arguments,
});
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
_ => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
let v = Expr::Call(crate::ir::Call {
call_type,
arguments,
});
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
},
Foreign { .. } => {
let ps = crate::borrow::foreign_borrow_signature(self.arena, arguments.len());

View File

@ -19,7 +19,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable};
use std::collections::HashMap;
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
pub const PRETTY_PRINT_IR_SYMBOLS: bool = false;
pub const PRETTY_PRINT_IR_SYMBOLS: bool = true;
macro_rules! return_on_layout_error {
($env:expr, $layout_result:expr) => {