Skip to content

Commit e1a26ad

Browse files
committed
use element count in slices, not size in bytes
This allows the indexing bounds check or other comparisons against an element length to avoid a multiplication by the size.
1 parent aa93381 commit e1a26ad

File tree

10 files changed

+154
-76
lines changed

10 files changed

+154
-76
lines changed

src/librustc/middle/trans/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ fn extract_vec_elems(bcx: @mut Block,
10591059
Store(bcx, slice_begin,
10601060
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
10611061
);
1062-
Store(bcx, slice_len,
1062+
Store(bcx, UDiv(bcx, slice_len, vt.llunit_size),
10631063
GEPi(bcx, scratch.val, [0u, abi::slice_elt_len])
10641064
);
10651065
elems[n] = scratch.val;

src/librustc/middle/trans/base.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use middle::trans::glue;
5454
use middle::trans::inline;
5555
use middle::trans::llrepr::LlvmRepr;
5656
use middle::trans::machine;
57-
use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_alloc};
57+
use middle::trans::machine::{llalign_of_min, llsize_of};
5858
use middle::trans::meth;
5959
use middle::trans::monomorphize;
6060
use middle::trans::tvec;
@@ -2910,7 +2910,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
29102910
}
29112911
}
29122912

2913-
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
2913+
pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint) {
29142914
let str_slice_type = Type::struct_([Type::i8p(), ccx.int_type], false);
29152915
let elttype = Type::struct_([str_slice_type, ccx.int_type], false);
29162916
let maptype = Type::array(&elttype, ccx.module_data.len() as u64);
@@ -2942,7 +2942,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
29422942
unsafe {
29432943
llvm::LLVMSetInitializer(map, C_array(elttype, elts));
29442944
}
2945-
return (map, keys.len(), llsize_of_alloc(ccx, elttype));
2945+
return (map, keys.len())
29462946
}
29472947

29482948

@@ -3004,19 +3004,17 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
30043004
lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
30053005

30063006
llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
3007-
let (mod_map, mod_count, mod_struct_size) = create_module_map(ccx);
3007+
let (mod_map, mod_count) = create_module_map(ccx);
30083008

30093009
llvm::LLVMSetInitializer(map, C_struct(
30103010
[C_i32(2),
30113011
C_struct([
30123012
p2i(ccx, mod_map),
3013-
// byte size of the module map array, an entry consists of two integers
3014-
C_int(ccx, ((mod_count * mod_struct_size) as int))
3013+
C_uint(ccx, mod_count)
30153014
], false),
30163015
C_struct([
30173016
p2i(ccx, vec_elements),
3018-
// byte size of the subcrates array, an entry consists of an integer
3019-
C_int(ccx, (subcrates.len() * llsize_of_alloc(ccx, ccx.int_type)) as int)
3017+
C_uint(ccx, subcrates.len())
30203018
], false)
30213019
], false));
30223020
}

src/librustc/middle/trans/consts.rs

+18-30
Original file line numberDiff line numberDiff line change
@@ -83,23 +83,18 @@ pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef {
8383
}
8484
}
8585

86-
pub fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr])
87-
-> (ValueRef, ValueRef, Type, bool) {
88-
unsafe {
89-
let vec_ty = ty::expr_ty(cx.tcx, e);
90-
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
91-
let llunitty = type_of::type_of(cx, unit_ty);
92-
let unit_sz = machine::llsize_of(cx, llunitty);
93-
let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
94-
let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
95-
// If the vector contains enums, an LLVM array won't work.
96-
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
97-
C_struct(vs, false)
98-
} else {
99-
C_array(llunitty, vs)
100-
};
101-
return (v, sz, llunitty, inlineable.iter().fold(true, |a, &b| a && b));
102-
}
86+
fn const_vec(cx: @mut CrateContext, e: &ast::Expr, es: &[@ast::Expr]) -> (ValueRef, Type, bool) {
87+
let vec_ty = ty::expr_ty(cx.tcx, e);
88+
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
89+
let llunitty = type_of::type_of(cx, unit_ty);
90+
let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
91+
// If the vector contains enums, an LLVM array won't work.
92+
let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
93+
C_struct(vs, false)
94+
} else {
95+
C_array(llunitty, vs)
96+
};
97+
(v, llunitty, inlineable.iter().fold(true, |a, &b| a && b))
10398
}
10499

105100
fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
@@ -225,9 +220,8 @@ pub fn const_expr(cx: @mut CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
225220
assert_eq!(abi::slice_elt_len, 1);
226221

227222
match ty::get(ty).sty {
228-
ty::ty_evec(_, ty::vstore_fixed(*)) => {
229-
let size = machine::llsize_of(cx, val_ty(llconst));
230-
llconst = C_struct([llptr, size], false);
223+
ty::ty_evec(_, ty::vstore_fixed(len)) => {
224+
llconst = C_struct([llptr, C_uint(cx, len)], false);
231225
}
232226
_ => {}
233227
}
@@ -412,14 +406,8 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
412406
(bv, C_uint(cx, u)),
413407

414408
ty::vstore_slice(_) => {
415-
let unit_ty = ty::sequence_element_type(cx.tcx, bt);
416-
let llunitty = type_of::type_of(cx, unit_ty);
417-
let unit_sz = machine::llsize_of(cx, llunitty);
418-
419409
let e1 = const_get_elt(cx, bv, [0]);
420-
(const_deref_ptr(cx, e1),
421-
llvm::LLVMConstUDiv(const_get_elt(cx, bv, [1]),
422-
unit_sz))
410+
(const_deref_ptr(cx, e1), const_get_elt(cx, bv, [1]))
423411
},
424412
_ => cx.sess.span_bug(base.span,
425413
"index-expr base must be fixed-size or slice")
@@ -538,7 +526,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
538526
}
539527
}
540528
ast::ExprVec(ref es, ast::MutImmutable) => {
541-
let (v, _, _, inlineable) = const_vec(cx, e, *es);
529+
let (v, _, inlineable) = const_vec(cx, e, *es);
542530
(v, inlineable)
543531
}
544532
ast::ExprVstore(sub, ast::ExprVstoreSlice) => {
@@ -550,7 +538,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
550538
}
551539
}
552540
ast::ExprVec(ref es, ast::MutImmutable) => {
553-
let (cv, sz, llunitty, _) = const_vec(cx, e, *es);
541+
let (cv, llunitty, _) = const_vec(cx, e, *es);
554542
let llty = val_ty(cv);
555543
let gv = do "const".with_c_str |name| {
556544
llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
@@ -559,7 +547,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
559547
llvm::LLVMSetGlobalConstant(gv, True);
560548
SetLinkage(gv, PrivateLinkage);
561549
let p = const_ptrcast(cx, gv, llunitty);
562-
(C_struct([p, sz], false), false)
550+
(C_struct([p, C_uint(cx, es.len())], false), false)
563551
}
564552
_ => cx.sess.span_bug(e.span, "bad const-slice expr")
565553
}

src/librustc/middle/trans/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ fn vec_slice_metadata(cx: &mut CrateContext,
18651865
offset: ComputedMemberOffset,
18661866
},
18671867
MemberDescription {
1868-
name: @"size_in_bytes",
1868+
name: @"length",
18691869
llvm_type: member_llvm_types[1],
18701870
type_metadata: type_metadata(cx, ty::mk_uint(), span),
18711871
offset: ComputedMemberOffset,

src/librustc/middle/trans/expr.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,12 @@ pub fn trans_to_datum(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
274274
ty::vstore_slice(ty::re_static));
275275

276276
let scratch = scratch_datum(bcx, slice_ty, "__adjust", false);
277+
278+
let vt = tvec::vec_types(bcx, datum.ty);
279+
let unscaled_len = UDiv(bcx, len, vt.llunit_size);
280+
277281
Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
278-
Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
282+
Store(bcx, unscaled_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
279283
DatumBlock {bcx: bcx, datum: scratch}
280284
}
281285

src/librustc/middle/trans/tvec.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ pub fn trans_slice_vstore(bcx: @mut Block,
237237
Ignore => {}
238238
SaveIn(lldest) => {
239239
Store(bcx, llfixed, GEPi(bcx, lldest, [0u, abi::slice_elt_base]));
240-
let lllen = Mul(bcx, llcount, vt.llunit_size);
241-
Store(bcx, lllen, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
240+
Store(bcx, llcount, GEPi(bcx, lldest, [0u, abi::slice_elt_len]));
242241
}
243242
}
244243

@@ -529,7 +528,8 @@ pub fn get_base_and_len(bcx: @mut Block,
529528
}
530529
ty::vstore_slice(_) => {
531530
let base = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_base]));
532-
let len = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
531+
let count = Load(bcx, GEPi(bcx, llval, [0u, abi::slice_elt_len]));
532+
let len = Mul(bcx, count, vt.llunit_size);
533533
(base, len)
534534
}
535535
ty::vstore_uniq | ty::vstore_box => {

src/libstd/rand/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ fn main () {
5252
```
5353
*/
5454

55+
use sys::size_of;
56+
use unstable::raw::Slice;
5557
use cast;
5658
use container::Container;
5759
use iter::{Iterator, range};
@@ -133,10 +135,10 @@ pub trait Rng {
133135
/// println!("{:?}", v);
134136
/// }
135137
/// ```
136-
fn fill_bytes(&mut self, mut dest: &mut [u8]) {
137-
// this relies on the lengths being transferred correctly when
138-
// transmuting between vectors like this.
139-
let as_u64: &mut &mut [u64] = unsafe { cast::transmute(&mut dest) };
138+
fn fill_bytes(&mut self, dest: &mut [u8]) {
139+
let mut slice: Slice<u64> = unsafe { cast::transmute_copy(&dest) };
140+
slice.len /= size_of::<u64>();
141+
let as_u64: &mut [u64] = unsafe { cast::transmute(slice) };
140142
for dest in as_u64.mut_iter() {
141143
*dest = self.next_u64();
142144
}
@@ -147,7 +149,9 @@ pub trait Rng {
147149

148150
// space for a u32
149151
if remaining >= 4 {
150-
let as_u32: &mut &mut [u32] = unsafe { cast::transmute(&mut dest) };
152+
let mut slice: Slice<u32> = unsafe { cast::transmute_copy(&dest) };
153+
slice.len /= size_of::<u32>();
154+
let as_u32: &mut [u32] = unsafe { cast::transmute(slice) };
151155
as_u32[as_u32.len() - 1] = self.next_u32();
152156
remaining -= 4;
153157
}

src/libstd/repr.rs

+19-16
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,7 @@ impl<'self> ReprVisitor<'self> {
186186
}
187187
}
188188

189-
pub fn write_vec_range(&mut self,
190-
_mtbl: uint,
191-
ptr: *(),
192-
len: uint,
193-
inner: *TyDesc)
194-
-> bool {
189+
pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
195190
let mut p = ptr as *u8;
196191
let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
197192
self.writer.write(['[' as u8]);
@@ -213,13 +208,8 @@ impl<'self> ReprVisitor<'self> {
213208
true
214209
}
215210

216-
pub fn write_unboxed_vec_repr(&mut self,
217-
mtbl: uint,
218-
v: &raw::Vec<()>,
219-
inner: *TyDesc)
220-
-> bool {
221-
self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data),
222-
v.fill, inner)
211+
pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool {
212+
self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
223213
}
224214

225215
fn write_escaped_char(&mut self, ch: char, is_str: bool) {
@@ -377,19 +367,32 @@ impl<'self> TyVisitor for ReprVisitor<'self> {
377367
}
378368
}
379369

370+
#[cfg(stage0)]
380371
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
381372
do self.get::<raw::Slice<()>> |this, s| {
382373
this.writer.write(['&' as u8]);
383374
this.write_mut_qualifier(mtbl);
384-
this.write_vec_range(mtbl, s.data, s.len, inner);
375+
this.write_vec_range(s.data, s.len, inner);
376+
}
377+
}
378+
379+
#[cfg(not(stage0))]
380+
fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
381+
do self.get::<raw::Slice<()>> |this, s| {
382+
this.writer.write(['&' as u8]);
383+
this.write_mut_qualifier(mtbl);
384+
let size = unsafe {
385+
if (*inner).size == 0 { 1 } else { (*inner).size }
386+
};
387+
this.write_vec_range(s.data, s.len * size, inner);
385388
}
386389
}
387390

388391
fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint,
389-
mtbl: uint, inner: *TyDesc) -> bool {
392+
_: uint, inner: *TyDesc) -> bool {
390393
let assumed_size = if sz == 0 { n } else { sz };
391394
do self.get::<()> |this, b| {
392-
this.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), assumed_size, inner);
395+
this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
393396
}
394397
}
395398

0 commit comments

Comments
 (0)