Skip to content

Commit eb4661f

Browse files
committed
Factor vector-allocation code, always allocate space for at least 4 elts
(This prevents the first few reallocs when growing a vector.)
1 parent 5483b91 commit eb4661f

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

src/comp/middle/trans_ivec.rs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,39 @@ fn pointer_add(bcx: &@block_ctxt, ptr: ValueRef, bytes: ValueRef)
3131
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
3232
}
3333

34-
// FIXME factor out a scaling version wrapping a non-scaling version
35-
fn alloc(bcx: &@block_ctxt, vec_ty: &ty::t, vecsz: ValueRef, is_scaled: bool)
36-
-> {bcx: @block_ctxt,
37-
val: ValueRef,
38-
unit_ty: ty::t,
39-
llunitsz: ValueRef,
40-
llunitty: TypeRef} {
34+
fn alloc_raw(bcx: &@block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
35+
let llvecty = T_opaque_ivec();
36+
let vecsize = Add(bcx, alloc, llsize_of(llvecty));
37+
let {bcx, val: vecptr} =
38+
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
39+
Store(bcx, fill, InBoundsGEP
40+
(bcx, vecptr, [C_int(0), C_uint(abi::ivec_elt_fill)]));
41+
Store(bcx, alloc, InBoundsGEP
42+
(bcx, vecptr, [C_int(0), C_uint(abi::ivec_elt_alloc)]));
43+
ret {bcx: bcx, val: vecptr};
44+
}
45+
46+
type alloc_result = {bcx: @block_ctxt,
47+
val: ValueRef,
48+
unit_ty: ty::t,
49+
llunitsz: ValueRef,
50+
llunitty: TypeRef};
4151

52+
fn alloc(bcx: &@block_ctxt, vec_ty: &ty::t, elts: uint) -> alloc_result {
4253
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
4354
let llunitty = type_of_or_i8(bcx, unit_ty);
4455
let llvecty = T_ivec(llunitty);
4556
let {bcx, val: unit_sz} = size_of(bcx, unit_ty);
4657

47-
let fill = if is_scaled { vecsz }
48-
else { Mul(bcx, vecsz, unit_sz) };
49-
let vecsize = Add(bcx, fill, llsize_of(llvecty));
50-
let {bcx, val: vecptr} =
51-
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
52-
add_clean_temp(bcx, vecptr, vec_ty);
53-
54-
Store(bcx, fill, InBoundsGEP
55-
(bcx, vecptr, [C_int(0), C_uint(abi::ivec_elt_fill)]));
56-
Store(bcx, fill, InBoundsGEP
57-
(bcx, vecptr, [C_int(0), C_uint(abi::ivec_elt_alloc)]));
58-
ret {bcx: bcx, val: vecptr,
59-
unit_ty: unit_ty, llunitsz: unit_sz, llunitty: llunitty};
58+
let fill = Mul(bcx, C_uint(elts), unit_sz);
59+
let alloc = if elts < 4u { Mul(bcx, C_int(4), unit_sz) } else { fill };
60+
let {bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
61+
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
62+
add_clean_temp(bcx, vptr, vec_ty);
63+
ret {bcx: bcx, val: vptr, unit_ty: unit_ty,
64+
llunitsz: unit_sz, llunitty: llunitty};
6065
}
66+
6167
fn duplicate(bcx: &@block_ctxt, vptrptr: ValueRef) -> @block_ctxt {
6268
let vptr = Load(bcx, vptrptr);
6369
let fill = get_fill(bcx, vptr);
@@ -89,7 +95,7 @@ fn trans_ivec(bcx: &@block_ctxt, args: &[@ast::expr],
8995
id: ast::node_id) -> result {
9096
let vec_ty = node_id_type(bcx_ccx(bcx), id);
9197
let {bcx, val: vptr, llunitsz, unit_ty, llunitty} =
92-
alloc(bcx, vec_ty, C_uint(vec::len(args)), false);
98+
alloc(bcx, vec_ty, vec::len(args));
9399

94100
// Store the individual elements.
95101
let dataptr = get_dataptr(bcx, vptr, llunitty);
@@ -110,7 +116,7 @@ fn trans_ivec(bcx: &@block_ctxt, args: &[@ast::expr],
110116
fn trans_istr(bcx: &@block_ctxt, s: istr) -> result {
111117
let veclen = std::istr::byte_len(s) + 1u; // +1 for \0
112118
let {bcx, val: sptr, _} =
113-
alloc(bcx, ty::mk_istr(bcx_tcx(bcx)), C_uint(veclen), false);
119+
alloc(bcx, ty::mk_istr(bcx_tcx(bcx)), veclen);
114120

115121
let llcstr = C_cstr(bcx_ccx(bcx), s);
116122
let bcx = call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()),
@@ -194,12 +200,17 @@ fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef,
194200
ty::ty_istr. { true }
195201
ty::ty_vec(_) { false }
196202
};
203+
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
204+
let llunitty = type_of_or_i8(bcx, unit_ty);
205+
let {bcx, val: llunitsz} = size_of(bcx, unit_ty);
206+
197207
let lhs_fill = get_fill(bcx, lhs);
198208
if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(1)); }
199209
let rhs_fill = get_fill(bcx, rhs);
200210
let new_fill = Add(bcx, lhs_fill, rhs_fill);
201-
let {bcx, val: new_vec, unit_ty, llunitsz, llunitty} =
202-
alloc(bcx, vec_ty, new_fill, true);
211+
let {bcx, val: new_vec} = alloc_raw(bcx, new_fill, new_fill);
212+
let new_vec = PointerCast(bcx, new_vec, T_ptr(T_ivec(llunitty)));
213+
add_clean_temp(bcx, new_vec, vec_ty);
203214

204215
let write_ptr_ptr = do_spill(bcx, get_dataptr(bcx, new_vec, llunitty));
205216
let copy_fn = bind fn(bcx: &@block_ctxt, addr: ValueRef, _ty: ty::t,

0 commit comments

Comments
 (0)