auto merge of #17188 : thestinger/rust/tvec, r=pcwalton

`Box<[T]>` is created by allocating `Box<[T, ..n]>` and coercing it so
this code path is never used. It's also broken because it clamps the
capacity of the memory allocations to 4 elements and that's incompatible
with sized deallocation. This dates back to when `~[T]` was a growable
vector type implemented as:

*{ { tydesc, ref_count, prev, next }, { length, capacity, data[] } }

Since even empty vectors had to allocate, it started off the capacity of
all vectors at 4 as a heuristic. It's not possible to grow `Box<[T]>`
and there is no need for a memory allocation when it's empty, so it
would be a terrible heuristic today even if it worked.
This commit is contained in:
bors 2014-09-13 20:36:02 +00:00
commit 79a5448f41
2 changed files with 1 additions and 109 deletions

View File

@ -587,25 +587,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let contents_ty = expr_ty(bcx, &**contents);
match ty::get(box_ty).sty {
ty::ty_uniq(..) => {
let is_vec = match contents.node {
ast::ExprRepeat(..) | ast::ExprVec(..) => true,
ast::ExprLit(lit) => match lit.node {
ast::LitStr(..) => true,
_ => false
},
_ => false
};
if is_vec {
// Special case for owned vectors.
fcx.push_ast_cleanup_scope(contents.id);
let datum = unpack_datum!(
bcx, tvec::trans_uniq_vec(bcx, expr, &**contents));
bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
DatumBlock::new(bcx, datum)
} else {
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
}
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
}
ty::ty_box(..) => {
trans_managed_expr(bcx, box_ty, &**contents, contents_ty)

View File

@ -13,11 +13,9 @@
use back::abi;
use llvm;
use llvm::{ValueRef};
use middle::lang_items::StrDupUniqFnLangItem;
use middle::trans::base::*;
use middle::trans::base;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::cleanup;
use middle::trans::cleanup::CleanupMethods;
use middle::trans::common::*;
@ -241,94 +239,6 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
pub fn trans_uniq_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
uniq_expr: &ast::Expr,
content_expr: &ast::Expr)
-> DatumBlock<'blk, 'tcx, Expr> {
/*!
* Box<[...]> and "...".to_string() allocate boxes in the exchange heap and write
* the array elements into them.
*/
debug!("trans_uniq_vec(uniq_expr={})", bcx.expr_to_string(uniq_expr));
let fcx = bcx.fcx;
let ccx = fcx.ccx;
// Handle "".to_string().
match content_expr.node {
ast::ExprLit(lit) => {
match lit.node {
ast::LitStr(ref s, _) => {
let llptrval = C_cstr(ccx, (*s).clone(), false);
let llptrval = PointerCast(bcx, llptrval, Type::i8p(ccx));
let llsizeval = C_uint(ccx, s.get().len());
let typ = ty::mk_uniq(bcx.tcx(), ty::mk_str(bcx.tcx()));
let lldestval = rvalue_scratch_datum(bcx,
typ,
"");
let alloc_fn = langcall(bcx,
Some(lit.span),
"",
StrDupUniqFnLangItem);
let bcx = callee::trans_lang_call(
bcx,
alloc_fn,
[ llptrval, llsizeval ],
Some(expr::SaveIn(lldestval.val))).bcx;
return DatumBlock::new(bcx, lldestval).to_expr_datumblock();
}
_ => {}
}
}
_ => {}
}
let vt = vec_types_from_expr(bcx, content_expr);
let count = elements_required(bcx, content_expr);
debug!(" vt={}, count={:?}", vt.to_string(ccx), count);
let vec_ty = node_id_type(bcx, uniq_expr.id);
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 = 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,
alloc,
align);
// Create a temporary scope lest execution should fail while
// constructing the vector.
let temp_scope = fcx.push_custom_cleanup_scope();
fcx.schedule_free_slice(cleanup::CustomScope(temp_scope),
dataptr, alloc, align, cleanup::HeapExchange);
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);
if ty::type_is_sized(bcx.tcx(), vec_ty) {
immediate_rvalue_bcx(bcx, dataptr, vec_ty).to_expr_datumblock()
} else {
let scratch = rvalue_scratch_datum(bcx, vec_ty, "");
Store(bcx, dataptr, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
Store(bcx, llcount, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
DatumBlock::new(bcx, scratch.to_expr_datum())
}
}
pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
vt: &VecTypes,
vstore_expr: &ast::Expr,