summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorEric Holk <eholk@mozilla.com>2011-07-18 12:02:26 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-21 11:51:22 -0700
commit3ae4dcd41e72d197e3882835253745f79588b04a (patch)
tree38b0fa41afe156057c8913f779fda2e4ca0b08ac /src/comp
parenta44fb04d57400f70ad58c1e35fc9dd9a7c43de07 (diff)
downloadrust-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.rs4
-rw-r--r--src/comp/middle/trans_comm.rs110
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));
+    }
+}
+