diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-07-18 12:02:26 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-07-21 11:51:22 -0700 |
| commit | 3ae4dcd41e72d197e3882835253745f79588b04a (patch) | |
| tree | 38b0fa41afe156057c8913f779fda2e4ca0b08ac /src/comp | |
| parent | a44fb04d57400f70ad58c1e35fc9dd9a7c43de07 (diff) | |
| download | rust-3ae4dcd41e72d197e3882835253745f79588b04a.tar.gz rust-3ae4dcd41e72d197e3882835253745f79588b04a.zip | |
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.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/back/upcall.rs | 4 | ||||
| -rw-r--r-- | src/comp/middle/trans_comm.rs | 110 |
2 files changed, 59 insertions, 55 deletions
diff --git a/src/comp/back/upcall.rs b/src/comp/back/upcall.rs index 4c6b051b9a8..0237037b55e 100644 --- a/src/comp/back/upcall.rs +++ b/src/comp/back/upcall.rs @@ -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())]), diff --git a/src/comp/middle/trans_comm.rs b/src/comp/middle/trans_comm.rs index daa5dc3ea78..3ea1f588c95 100644 --- a/src/comp/middle/trans_comm.rs +++ b/src/comp/middle/trans_comm.rs @@ -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)); + } +} + |
