fix sized deallocation for Box<[T]>
This commit is contained in:
parent
5aa2da0133
commit
d1bd139251
@ -340,6 +340,27 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
|
||||
self.schedule_clean(cleanup_scope, drop as CleanupObj);
|
||||
}
|
||||
|
||||
fn schedule_free_slice(&self,
|
||||
cleanup_scope: ScopeId,
|
||||
val: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
heap: Heap) {
|
||||
/*!
|
||||
* Schedules a call to `free(val)`. Note that this is a shallow
|
||||
* operation.
|
||||
*/
|
||||
|
||||
let drop = box FreeSlice { ptr: val, size: size, align: align, heap: heap };
|
||||
|
||||
debug!("schedule_free_slice({:?}, val={}, heap={:?})",
|
||||
cleanup_scope,
|
||||
self.ccx.tn().val_to_string(val),
|
||||
heap);
|
||||
|
||||
self.schedule_clean(cleanup_scope, drop as CleanupObj);
|
||||
}
|
||||
|
||||
fn schedule_clean(&self,
|
||||
cleanup_scope: ScopeId,
|
||||
cleanup: CleanupObj) {
|
||||
@ -926,6 +947,34 @@ impl Cleanup for FreeValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FreeSlice {
|
||||
ptr: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
heap: Heap,
|
||||
}
|
||||
|
||||
impl Cleanup for FreeSlice {
|
||||
fn must_unwind(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn clean_on_unwind(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
|
||||
match self.heap {
|
||||
HeapManaged => {
|
||||
glue::trans_free(bcx, self.ptr)
|
||||
}
|
||||
HeapExchange => {
|
||||
glue::trans_exchange_free_dyn(bcx, self.ptr, self.size, self.align)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LifetimeEnd {
|
||||
ptr: ValueRef,
|
||||
}
|
||||
@ -1020,6 +1069,12 @@ pub trait CleanupMethods<'a> {
|
||||
val: ValueRef,
|
||||
heap: Heap,
|
||||
content_ty: ty::t);
|
||||
fn schedule_free_slice(&self,
|
||||
cleanup_scope: ScopeId,
|
||||
val: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
heap: Heap);
|
||||
fn schedule_clean(&self,
|
||||
cleanup_scope: ScopeId,
|
||||
cleanup: CleanupObj);
|
||||
|
@ -53,7 +53,7 @@ pub fn trans_free<'a>(cx: &'a Block<'a>, v: ValueRef) -> &'a Block<'a> {
|
||||
Some(expr::Ignore)).bcx
|
||||
}
|
||||
|
||||
fn trans_exchange_free_internal<'a>(cx: &'a Block<'a>, v: ValueRef, size: ValueRef,
|
||||
pub fn trans_exchange_free_dyn<'a>(cx: &'a Block<'a>, v: ValueRef, size: ValueRef,
|
||||
align: ValueRef) -> &'a Block<'a> {
|
||||
let _icx = push_ctxt("trans_exchange_free");
|
||||
let ccx = cx.ccx();
|
||||
@ -65,10 +65,8 @@ fn trans_exchange_free_internal<'a>(cx: &'a Block<'a>, v: ValueRef, size: ValueR
|
||||
|
||||
pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef, size: u64,
|
||||
align: u64) -> &'a Block<'a> {
|
||||
trans_exchange_free_internal(cx,
|
||||
v,
|
||||
C_uint(cx.ccx(), size as uint),
|
||||
C_uint(cx.ccx(), align as uint))
|
||||
trans_exchange_free_dyn(cx, v, C_uint(cx.ccx(), size as uint),
|
||||
C_uint(cx.ccx(), align as uint))
|
||||
}
|
||||
|
||||
pub fn trans_exchange_free_ty<'a>(bcx: &'a Block<'a>, ptr: ValueRef,
|
||||
@ -467,7 +465,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
let info = GEPi(bcx, v0, [0, abi::slice_elt_len]);
|
||||
let info = Load(bcx, info);
|
||||
let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
|
||||
trans_exchange_free_internal(bcx, llbox, llsize, llalign)
|
||||
trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
|
@ -25,6 +25,7 @@ use middle::trans::datum::*;
|
||||
use middle::trans::expr::{Dest, Ignore, SaveIn};
|
||||
use middle::trans::expr;
|
||||
use middle::trans::glue;
|
||||
use middle::trans::machine;
|
||||
use middle::trans::machine::{nonzero_llsize_of, llsize_of_alloc};
|
||||
use middle::trans::type_::Type;
|
||||
use middle::trans::type_of;
|
||||
@ -59,6 +60,7 @@ pub fn make_drop_glue_unboxed<'a>(
|
||||
-> &'a Block<'a> {
|
||||
let not_null = IsNotNull(bcx, vptr);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
let ccx = bcx.ccx();
|
||||
let tcx = bcx.tcx();
|
||||
let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
|
||||
|
||||
@ -73,8 +75,11 @@ pub fn make_drop_glue_unboxed<'a>(
|
||||
if should_deallocate {
|
||||
let not_null = IsNotNull(bcx, dataptr);
|
||||
with_cond(bcx, not_null, |bcx| {
|
||||
// FIXME: #13994: the old `Box<[T]>` will not support sized deallocation
|
||||
glue::trans_exchange_free(bcx, dataptr, 0, 8)
|
||||
let llty = type_of::type_of(ccx, unit_ty);
|
||||
let llsize = machine::llsize_of(ccx, llty);
|
||||
let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
|
||||
let size = Mul(bcx, llsize, get_len(bcx, vptr));
|
||||
glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
|
||||
})
|
||||
} else {
|
||||
bcx
|
||||
@ -281,15 +286,16 @@ pub fn trans_uniq_vec<'a>(bcx: &'a Block<'a>,
|
||||
debug!(" vt={}, count={:?}", vt.to_string(ccx), count);
|
||||
let vec_ty = node_id_type(bcx, uniq_expr.id);
|
||||
|
||||
let unit_sz = nonzero_llsize_of(ccx, type_of::type_of(ccx, vt.unit_ty));
|
||||
let llty = type_of::type_of(ccx, vt.unit_ty);
|
||||
let unit_sz = nonzero_llsize_of(ccx, llty);
|
||||
let llcount = if count < 4u {
|
||||
C_int(ccx, 4)
|
||||
} else {
|
||||
C_uint(ccx, count)
|
||||
};
|
||||
let alloc = Mul(bcx, llcount, unit_sz);
|
||||
let llty_ptr = type_of::type_of(ccx, vt.unit_ty).ptr_to();
|
||||
let align = C_uint(ccx, 8);
|
||||
let llty_ptr = llty.ptr_to();
|
||||
let align = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
|
||||
let Result { bcx: bcx, val: dataptr } = malloc_raw_dyn(bcx,
|
||||
llty_ptr,
|
||||
vec_ty,
|
||||
@ -299,16 +305,15 @@ pub fn trans_uniq_vec<'a>(bcx: &'a Block<'a>,
|
||||
// Create a temporary scope lest execution should fail while
|
||||
// constructing the vector.
|
||||
let temp_scope = fcx.push_custom_cleanup_scope();
|
||||
// FIXME: #13994: the old `Box<[T]> will not support sized deallocation,
|
||||
// this is a placeholder
|
||||
fcx.schedule_free_value(cleanup::CustomScope(temp_scope),
|
||||
dataptr, cleanup::HeapExchange, vt.unit_ty);
|
||||
|
||||
debug!(" alloc_uniq_vec() returned dataptr={}, len={}",
|
||||
bcx.val_to_string(dataptr), count);
|
||||
fcx.schedule_free_slice(cleanup::CustomScope(temp_scope),
|
||||
dataptr, alloc, align, cleanup::HeapExchange);
|
||||
|
||||
let bcx = write_content(bcx, &vt, uniq_expr,
|
||||
content_expr, SaveIn(dataptr));
|
||||
debug!(" alloc_uniq_vec() returned dataptr={}, len={}",
|
||||
bcx.val_to_string(dataptr), count);
|
||||
|
||||
let bcx = write_content(bcx, &vt, uniq_expr,
|
||||
content_expr, SaveIn(dataptr));
|
||||
|
||||
fcx.pop_custom_cleanup_scope(temp_scope);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user