about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-12-31 13:01:45 -0800
committerGraydon Hoare <graydon@mozilla.com>2010-12-31 13:01:45 -0800
commitbd536ba85fb1daaa81f5467ef2a0413a77446f4b (patch)
tree4b75847cb5014a01513c5632c0391328928857e3 /src/comp
parentf072718cfe83f0b92fa445cfa5b4f973886ef918 (diff)
downloadrust-bd536ba85fb1daaa81f5467ef2a0413a77446f4b.tar.gz
rust-bd536ba85fb1daaa81f5467ef2a0413a77446f4b.zip
Free objects by indirectly dropping fields via enclosed tydesc first.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 18a3a950ff6..115ef1f24b9 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -399,9 +399,11 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
                 mtys += T_ptr(mty);
             }
             let TypeRef vtbl = T_struct(mtys);
+            let TypeRef body = T_struct(vec(T_ptr(T_tydesc()),
+                                            T_nil()));
             let TypeRef pair =
                 T_struct(vec(T_ptr(vtbl),
-                             T_ptr(T_box(T_nil()))));
+                             T_ptr(T_box(body))));
             auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
             llvm.LLVMRefineType(abs_pair, pair);
             abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
@@ -775,6 +777,50 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
                                         T_int(), C_int(0));
         }
 
+        case (ty.ty_obj(_)) {
+            fn hit_zero(@block_ctxt cx, ValueRef v) -> result {
+
+                // Call through the obj's own fields-drop glue first.
+                auto body =
+                    cx.build.GEP(v,
+                                 vec(C_int(0),
+                                     C_int(abi.box_rc_field_body)));
+
+                auto fields =
+                    cx.build.GEP(body,
+                                 vec(C_int(0),
+                                     C_int(abi.obj_body_elt_fields)));
+                auto llrawptr = cx.build.BitCast(fields, T_ptr(T_i8()));
+
+                auto tydescptr =
+                    cx.build.GEP(body,
+                                 vec(C_int(0),
+                                     C_int(abi.obj_body_elt_tydesc)));
+                auto tydesc = cx.build.Load(tydescptr);
+                auto llfnptr =
+                    cx.build.GEP(tydesc,
+                                 vec(C_int(0),
+                                     C_int(abi.tydesc_field_drop_glue_off)));
+                auto llfn = cx.build.Load(llfnptr);
+                cx.build.FastCall(llfn, vec(cx.fcx.lltaskptr, llrawptr));
+
+                // Then free the body.
+                // FIXME: switch gc/non-gc on layer of the type.
+                ret trans_non_gc_free(cx, v);
+            }
+            auto box_cell =
+                cx.build.GEP(v,
+                             vec(C_int(0),
+                                 C_int(abi.obj_field_box)));
+
+            auto boxptr = cx.build.Load(box_cell);
+
+            ret decr_refcnt_and_if_zero(cx, boxptr,
+                                        bind hit_zero(_, boxptr),
+                                        "free obj",
+                                        T_int(), C_int(0));
+        }
+
         case (_) {
             if (ty.type_is_structural(t)) {
                 ret iter_structural_ty(cx, v, t,
@@ -2651,7 +2697,8 @@ impure fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
                                       C_int(abi.obj_field_box)));
     bcx.build.Store(vtbl, pair_vtbl);
 
-    let TypeRef llbox_ty = T_ptr(T_box(T_nil()));
+    let TypeRef llbox_ty = T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc()),
+                                                    T_nil()))));
     if (_vec.len[ty.arg](arg_tys) == 0u) {
         // Store null into pair, if no args.
         bcx.build.Store(C_null(llbox_ty), pair_box);