Lots of work on memory tracking and channels.
We're trying to get closer to doing correct move semantics for channel operations. This involves a lot of cleanup (such as removing the unused sched parameter from rust_vec constructor) and making circular_buffer kernel_owned. Added tagging for memory allocations. This means we give a string tag to everything we allocate. If we leak something and TRACK_ALLOCATIONS is enabled, then it's much easier now to tell exactly what is leaking.
This commit is contained in:
parent
a44fb04d57
commit
3ae4dcd41e
24 changed files with 313 additions and 240 deletions
|
|
@ -38,6 +38,7 @@ type upcalls =
|
|||
ValueRef flush_chan,
|
||||
ValueRef del_chan,
|
||||
ValueRef clone_chan,
|
||||
ValueRef chan_target_task,
|
||||
ValueRef _yield,
|
||||
ValueRef sleep,
|
||||
ValueRef send,
|
||||
|
|
@ -95,6 +96,9 @@ fn declare_upcalls(type_names tn, TypeRef tydesc_type, TypeRef taskptr_type,
|
|||
del_chan=dv("del_chan", ~[T_opaque_chan_ptr()]),
|
||||
clone_chan=d("clone_chan", ~[taskptr_type, T_opaque_chan_ptr()],
|
||||
T_opaque_chan_ptr()),
|
||||
chan_target_task=d("chan_target_task",
|
||||
~[T_opaque_chan_ptr()],
|
||||
taskptr_type),
|
||||
_yield=dv("yield", empty_vec),
|
||||
sleep=dv("sleep", ~[T_size_t()]),
|
||||
send=dv("send", ~[T_opaque_chan_ptr(), T_ptr(T_i8())]),
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ import back::link::mangle_internal_name_by_path_and_seq;
|
|||
import trans_common::*;
|
||||
import trans::*;
|
||||
|
||||
export trans_port;
|
||||
export trans_chan;
|
||||
export trans_spawn;
|
||||
export trans_send;
|
||||
export trans_recv;
|
||||
|
||||
fn trans_port(&@block_ctxt cx, ast::node_id id) -> result {
|
||||
auto t = node_id_type(cx.fcx.lcx.ccx, id);
|
||||
auto unit_ty;
|
||||
|
|
@ -123,13 +129,7 @@ fn trans_spawn(&@block_ctxt cx, &ast::spawn_dom dom, &option::t[str] name,
|
|||
auto llargs = alloc_ty(bcx, args_ty);
|
||||
auto i = 0u;
|
||||
for (ValueRef v in arg_vals) {
|
||||
// log_err #fmt("ty(llargs) = %s",
|
||||
// val_str(bcx.fcx.lcx.ccx.tn, llargs.val));
|
||||
|
||||
auto target = bcx.build.GEP(llargs.val, ~[C_int(0), C_int(i as int)]);
|
||||
// log_err #fmt("ty(v) = %s", val_str(bcx.fcx.lcx.ccx.tn, v));
|
||||
// log_err #fmt("ty(target) = %s",
|
||||
// val_str(bcx.fcx.lcx.ccx.tn, target));
|
||||
|
||||
bcx.build.Store(v, target);
|
||||
i += 1u;
|
||||
|
|
@ -199,55 +199,6 @@ fn mk_spawn_wrapper(&@block_ctxt cx, &@ast::expr func, &ty::t args_ty) ->
|
|||
ret rslt(cx, llfndecl);
|
||||
}
|
||||
|
||||
// Does a deep copy of a value. This is needed for passing arguments to child
|
||||
// tasks, and for sending things through channels. There are probably some
|
||||
// uniqueness optimizations and things we can do here for tasks in the same
|
||||
// domain.
|
||||
fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
|
||||
-> result
|
||||
{
|
||||
// TODO: make sure all paths add any reference counting that they need to.
|
||||
|
||||
// TODO: Teach deep copy to understand everything else it needs to.
|
||||
|
||||
auto tcx = bcx.fcx.lcx.ccx.tcx;
|
||||
if(ty::type_is_scalar(tcx, t)) {
|
||||
ret rslt(bcx, v);
|
||||
}
|
||||
else if(ty::type_is_str(tcx, t)) {
|
||||
ret rslt(bcx,
|
||||
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str,
|
||||
~[bcx.fcx.lltaskptr, target_task, v]));
|
||||
}
|
||||
else if(ty::type_is_chan(tcx, t)) {
|
||||
// If this is a channel, we need to clone it.
|
||||
auto chan_ptr = bcx.build.PointerCast(v, T_opaque_chan_ptr());
|
||||
|
||||
auto chan_raw_val =
|
||||
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.clone_chan,
|
||||
~[bcx.fcx.lltaskptr, target_task, chan_ptr]);
|
||||
|
||||
// Cast back to the type the context was expecting.
|
||||
auto chan_val = bcx.build.PointerCast(chan_raw_val,
|
||||
val_ty(v));
|
||||
|
||||
ret rslt(bcx, chan_val);
|
||||
}
|
||||
else if(ty::type_is_structural(tcx, t)) {
|
||||
fn inner_deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t) -> result {
|
||||
log_err "Unimplemented type for deep_copy.";
|
||||
fail;
|
||||
}
|
||||
|
||||
ret iter_structural_ty(bcx, v, t, inner_deep_copy);
|
||||
}
|
||||
else {
|
||||
bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
|
||||
"trans::deep_copy: " +
|
||||
ty_to_str(tcx, t));
|
||||
}
|
||||
}
|
||||
|
||||
fn trans_send(&@block_ctxt cx, &@ast::expr lhs, &@ast::expr rhs,
|
||||
ast::node_id id) -> result {
|
||||
auto bcx = cx;
|
||||
|
|
@ -302,3 +253,52 @@ fn recv_val(&@block_ctxt cx, ValueRef to, &@ast::expr from, &ty::t unit_ty,
|
|||
ret rslt(bcx, to);
|
||||
}
|
||||
|
||||
// Does a deep copy of a value. This is needed for passing arguments to child
|
||||
// tasks, and for sending things through channels. There are probably some
|
||||
// uniqueness optimizations and things we can do here for tasks in the same
|
||||
// domain.
|
||||
fn deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t, ValueRef target_task)
|
||||
-> result
|
||||
{
|
||||
// TODO: make sure all paths add any reference counting that they need to.
|
||||
|
||||
// TODO: Teach deep copy to understand everything else it needs to.
|
||||
|
||||
auto tcx = bcx.fcx.lcx.ccx.tcx;
|
||||
if(ty::type_is_scalar(tcx, t)) {
|
||||
ret rslt(bcx, v);
|
||||
}
|
||||
else if(ty::type_is_str(tcx, t)) {
|
||||
ret rslt(bcx,
|
||||
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.dup_str,
|
||||
~[bcx.fcx.lltaskptr, target_task, v]));
|
||||
}
|
||||
else if(ty::type_is_chan(tcx, t)) {
|
||||
// If this is a channel, we need to clone it.
|
||||
auto chan_ptr = bcx.build.PointerCast(v, T_opaque_chan_ptr());
|
||||
|
||||
auto chan_raw_val =
|
||||
bcx.build.Call(bcx.fcx.lcx.ccx.upcalls.clone_chan,
|
||||
~[bcx.fcx.lltaskptr, target_task, chan_ptr]);
|
||||
|
||||
// Cast back to the type the context was expecting.
|
||||
auto chan_val = bcx.build.PointerCast(chan_raw_val,
|
||||
val_ty(v));
|
||||
|
||||
ret rslt(bcx, chan_val);
|
||||
}
|
||||
else if(ty::type_is_structural(tcx, t)) {
|
||||
fn inner_deep_copy(&@block_ctxt bcx, ValueRef v, ty::t t) -> result {
|
||||
log_err "Unimplemented type for deep_copy.";
|
||||
fail;
|
||||
}
|
||||
|
||||
ret iter_structural_ty(bcx, v, t, inner_deep_copy);
|
||||
}
|
||||
else {
|
||||
bcx.fcx.lcx.ccx.sess.bug("unexpected type in " +
|
||||
"trans::deep_copy: " +
|
||||
ty_to_str(tcx, t));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue