diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-06-14 14:37:47 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-06-14 16:00:30 -0700 |
| commit | 14258b87a72003428006122a7c2ed7914a95bfb2 (patch) | |
| tree | dbf2c4d22b7c2ab21b41f435c8ee6d143f8e5319 /src/comp | |
| parent | bd18860be713acf95933dc11aa8a5b18c0f1e1d4 (diff) | |
| download | rust-14258b87a72003428006122a7c2ed7914a95bfb2.tar.gz rust-14258b87a72003428006122a7c2ed7914a95bfb2.zip | |
rustc: Free heapified interior vectors
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/trans.rs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index fa54a1d37c2..cba884c04b3 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2274,6 +2274,31 @@ fn make_free_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) { rslt.bcx.build.RetVoid(); } +fn maybe_free_ivec_heap_part(&@block_ctxt cx, ValueRef v0, ty::t unit_ty) + -> result { + auto llunitty = type_of_or_i8(cx, unit_ty); + + auto stack_len = cx.build.Load(cx.build.InBoundsGEP(v0, [C_int(0), + C_uint(abi::ivec_elt_len)])); + auto maybe_on_heap_cx = new_sub_block_ctxt(cx, "maybe_on_heap"); + auto next_cx = new_sub_block_ctxt(cx, "next"); + auto maybe_on_heap = cx.build.ICmp(lib::llvm::LLVMIntEQ, stack_len, + C_int(0)); + cx.build.CondBr(maybe_on_heap, maybe_on_heap_cx.llbb, next_cx.llbb); + + // Might be on the heap. Load the heap pointer and free it. (It's ok to + // free a null pointer.) + auto stub_ptr = maybe_on_heap_cx.build.PointerCast(v0, + T_ptr(T_ivec_heap(llunitty))); + auto heap_ptr = maybe_on_heap_cx.build.Load( + maybe_on_heap_cx.build.InBoundsGEP(stub_ptr, + [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)])); + auto after_free_cx = trans_non_gc_free(maybe_on_heap_cx, heap_ptr).bcx; + after_free_cx.build.Br(next_cx.llbb); + + ret res(next_cx, C_nil()); +} + fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) { // NB: v0 is an *alias* of type t here, not a direct value. auto rslt; @@ -2286,6 +2311,11 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) { rslt = decr_refcnt_maybe_free(cx, v0, v0, t); } + case (ty::ty_ivec(?tm)) { + rslt = iter_structural_ty(cx, v0, t, drop_ty); + rslt = maybe_free_ivec_heap_part(rslt.bcx, v0, tm.ty); + } + case (ty::ty_box(_)) { rslt = decr_refcnt_maybe_free(cx, v0, v0, t); } |
