Skip to content

Commit 79a5448

Browse files
committed
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.
2 parents 7277fe9 + 0fc06b1 commit 79a5448

File tree

2 files changed

+1
-109
lines changed

2 files changed

+1
-109
lines changed

src/librustc/middle/trans/expr.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -587,25 +587,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
587587
let contents_ty = expr_ty(bcx, &**contents);
588588
match ty::get(box_ty).sty {
589589
ty::ty_uniq(..) => {
590-
let is_vec = match contents.node {
591-
ast::ExprRepeat(..) | ast::ExprVec(..) => true,
592-
ast::ExprLit(lit) => match lit.node {
593-
ast::LitStr(..) => true,
594-
_ => false
595-
},
596-
_ => false
597-
};
598-
599-
if is_vec {
600-
// Special case for owned vectors.
601-
fcx.push_ast_cleanup_scope(contents.id);
602-
let datum = unpack_datum!(
603-
bcx, tvec::trans_uniq_vec(bcx, expr, &**contents));
604-
bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
605-
DatumBlock::new(bcx, datum)
606-
} else {
607-
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
608-
}
590+
trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
609591
}
610592
ty::ty_box(..) => {
611593
trans_managed_expr(bcx, box_ty, &**contents, contents_ty)

src/librustc/middle/trans/tvec.rs

-90
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
use back::abi;
1414
use llvm;
1515
use llvm::{ValueRef};
16-
use middle::lang_items::StrDupUniqFnLangItem;
1716
use middle::trans::base::*;
1817
use middle::trans::base;
1918
use middle::trans::build::*;
20-
use middle::trans::callee;
2119
use middle::trans::cleanup;
2220
use middle::trans::cleanup::CleanupMethods;
2321
use middle::trans::common::*;
@@ -241,94 +239,6 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
241239
}
242240
}
243241

244-
pub fn trans_uniq_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
245-
uniq_expr: &ast::Expr,
246-
content_expr: &ast::Expr)
247-
-> DatumBlock<'blk, 'tcx, Expr> {
248-
/*!
249-
* Box<[...]> and "...".to_string() allocate boxes in the exchange heap and write
250-
* the array elements into them.
251-
*/
252-
253-
debug!("trans_uniq_vec(uniq_expr={})", bcx.expr_to_string(uniq_expr));
254-
let fcx = bcx.fcx;
255-
let ccx = fcx.ccx;
256-
257-
// Handle "".to_string().
258-
match content_expr.node {
259-
ast::ExprLit(lit) => {
260-
match lit.node {
261-
ast::LitStr(ref s, _) => {
262-
let llptrval = C_cstr(ccx, (*s).clone(), false);
263-
let llptrval = PointerCast(bcx, llptrval, Type::i8p(ccx));
264-
let llsizeval = C_uint(ccx, s.get().len());
265-
let typ = ty::mk_uniq(bcx.tcx(), ty::mk_str(bcx.tcx()));
266-
let lldestval = rvalue_scratch_datum(bcx,
267-
typ,
268-
"");
269-
let alloc_fn = langcall(bcx,
270-
Some(lit.span),
271-
"",
272-
StrDupUniqFnLangItem);
273-
let bcx = callee::trans_lang_call(
274-
bcx,
275-
alloc_fn,
276-
[ llptrval, llsizeval ],
277-
Some(expr::SaveIn(lldestval.val))).bcx;
278-
return DatumBlock::new(bcx, lldestval).to_expr_datumblock();
279-
}
280-
_ => {}
281-
}
282-
}
283-
_ => {}
284-
}
285-
286-
let vt = vec_types_from_expr(bcx, content_expr);
287-
let count = elements_required(bcx, content_expr);
288-
debug!(" vt={}, count={:?}", vt.to_string(ccx), count);
289-
let vec_ty = node_id_type(bcx, uniq_expr.id);
290-
291-
let llty = type_of::type_of(ccx, vt.unit_ty);
292-
let unit_sz = nonzero_llsize_of(ccx, llty);
293-
let llcount = if count < 4u {
294-
C_int(ccx, 4)
295-
} else {
296-
C_uint(ccx, count)
297-
};
298-
let alloc = Mul(bcx, llcount, unit_sz);
299-
let llty_ptr = llty.ptr_to();
300-
let align = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
301-
let Result { bcx: bcx, val: dataptr } = malloc_raw_dyn(bcx,
302-
llty_ptr,
303-
vec_ty,
304-
alloc,
305-
align);
306-
307-
// Create a temporary scope lest execution should fail while
308-
// constructing the vector.
309-
let temp_scope = fcx.push_custom_cleanup_scope();
310-
311-
fcx.schedule_free_slice(cleanup::CustomScope(temp_scope),
312-
dataptr, alloc, align, cleanup::HeapExchange);
313-
314-
debug!(" alloc_uniq_vec() returned dataptr={}, len={}",
315-
bcx.val_to_string(dataptr), count);
316-
317-
let bcx = write_content(bcx, &vt, uniq_expr,
318-
content_expr, SaveIn(dataptr));
319-
320-
fcx.pop_custom_cleanup_scope(temp_scope);
321-
322-
if ty::type_is_sized(bcx.tcx(), vec_ty) {
323-
immediate_rvalue_bcx(bcx, dataptr, vec_ty).to_expr_datumblock()
324-
} else {
325-
let scratch = rvalue_scratch_datum(bcx, vec_ty, "");
326-
Store(bcx, dataptr, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
327-
Store(bcx, llcount, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
328-
DatumBlock::new(bcx, scratch.to_expr_datum())
329-
}
330-
}
331-
332242
pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
333243
vt: &VecTypes,
334244
vstore_expr: &ast::Expr,

0 commit comments

Comments
 (0)