Skip to content

Commit 34d607f

Browse files
committed
Use the slice repr for ~[T]
1 parent 5fb2dfa commit 34d607f

File tree

16 files changed

+247
-264
lines changed

16 files changed

+247
-264
lines changed

src/libcollections/slice.rs

+60
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ use core::iter::{range_step, MultiplicativeIterator};
9292

9393
use MutableSeq;
9494
use vec::Vec;
95+
#[cfg(not(stage0))]
96+
use raw::Slice;
9597

9698
pub use core::slice::{Chunks, Slice, ImmutableSlice, ImmutablePartialEqSlice};
9799
pub use core::slice::{ImmutableOrdSlice, MutableSlice, Items, MutItems};
@@ -282,6 +284,64 @@ pub trait CloneableVector<T> {
282284

283285
impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
284286
/// Returns a copy of `v`.
287+
#[cfg(not(stage0))]
288+
fn to_owned(&self) -> ~[T] {
289+
use num::CheckedMul;
290+
use option::Expect;
291+
292+
let len = self.len();
293+
294+
if len == 0 {
295+
unsafe {
296+
let slice: Slice<T> = Slice{data: 0 as *T, len: 0};
297+
mem::transmute(slice)
298+
}
299+
} else {
300+
let unit_size = mem::size_of::<T>();
301+
let data_size = if unit_size == 0 {
302+
len
303+
} else {
304+
let data_size = len.checked_mul(&unit_size);
305+
data_size.expect("overflow in from_iter()")
306+
};
307+
308+
unsafe {
309+
// this should pass the real required alignment
310+
let ret = allocate(data_size, 8) as *mut T;
311+
312+
if unit_size > 0 {
313+
// Be careful with the following loop. We want it to be optimized
314+
// to a memcpy (or something similarly fast) when T is Copy. LLVM
315+
// is easily confused, so any extra operations during the loop can
316+
// prevent this optimization.
317+
let mut i = 0;
318+
let p = &mut (*ret) as *mut _ as *mut T;
319+
try_finally(
320+
&mut i, (),
321+
|i, ()| while *i < len {
322+
mem::move_val_init(
323+
&mut(*p.offset(*i as int)),
324+
self.unsafe_ref(*i).clone());
325+
*i += 1;
326+
},
327+
|i| if *i < len {
328+
// we must be failing, clean up after ourselves
329+
for j in range(0, *i as int) {
330+
ptr::read(&*p.offset(j));
331+
}
332+
// FIXME: #13994 (should pass align and size here)
333+
deallocate(ret as *mut u8, 0, 8);
334+
});
335+
}
336+
let slice: Slice<T> = Slice{data: ret as *T, len: len};
337+
mem::transmute(slice)
338+
}
339+
}
340+
}
341+
342+
/// Returns a copy of `v`.
343+
// NOTE: remove after snapshot
344+
#[cfg(stage0)]
285345
#[inline]
286346
fn to_vec(&self) -> Vec<T> { Vec::from_slice(*self) }
287347

src/libcore/mem.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
174174

175175
/// Deprecated, use `overwrite` instead
176176
#[inline]
177-
#[deprecated = "use ptr::write"]
177+
#[deprecated = "this function has been renamed to overwrite()"]
178178
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
179179
ptr::write(dst, src)
180180
}

src/librustc/middle/trans/adt.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,7 @@ impl Case {
305305

306306
// Box<T> could either be a thin or fat pointer depending on T
307307
ty::ty_uniq(t) => match ty::get(t).sty {
308-
// Box<[T]>/Box<str> might be FatPointer in a post DST world
309-
ty::ty_vec(_, None) | ty::ty_str => continue,
308+
ty::ty_vec(_, None) | return Some(FatPointer(i, slice_elt_base)),
310309

311310
// Box<Trait> is a pair of pointers: the actual object and a vtable
312311
ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
@@ -326,7 +325,6 @@ impl Case {
326325

327326
// Anything else is not a pointer
328327
_ => continue
329-
330328
}
331329
}
332330

src/librustc/middle/trans/base.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,16 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
195195
llvm::NoReturnAttribute as uint64_t)
196196
}
197197
}
198+
// `~` pointer return values never alias because ownership is transferred
199+
ty::ty_uniq(t)
200+
=> match ty::get(t).sty {
201+
ty::ty_vec(_, None) | ty::ty_str | ty::ty_trait(..) => {}
202+
_ => unsafe {
203+
llvm::LLVMAddReturnAttribute(llfn,
204+
lib::llvm::NoAliasAttribute as c_uint,
205+
lib::llvm::NoReturnAttribute as uint64_t);
206+
}
207+
},
198208
_ => {}
199209
}
200210

@@ -364,20 +374,19 @@ fn require_alloc_fn(bcx: &Block, info_ty: ty::t, it: LangItem) -> ast::DefId {
364374
// a given type, but with a potentially dynamic size.
365375

366376
pub fn malloc_raw_dyn<'a>(bcx: &'a Block<'a>,
367-
ptr_ty: ty::t,
377+
llty_ptr: Type,
378+
info_ty: ty::t,
368379
size: ValueRef,
369380
align: ValueRef)
370381
-> Result<'a> {
371382
let _icx = push_ctxt("malloc_raw_exchange");
372-
let ccx = bcx.ccx();
373383

374384
// Allocate space:
375385
let r = callee::trans_lang_call(bcx,
376-
require_alloc_fn(bcx, ptr_ty, ExchangeMallocFnLangItem),
386+
require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem),
377387
[size, align],
378388
None);
379389

380-
let llty_ptr = type_of::type_of(ccx, ptr_ty);
381390
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
382391
}
383392

@@ -731,8 +740,8 @@ pub fn iter_structural_ty<'r,
731740
}
732741
}
733742
ty::ty_vec(_, Some(n)) => {
743+
let (base, len) = tvec::get_fixed_base_and_len(cx, av, n);
734744
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
735-
let (base, len) = tvec::get_fixed_base_and_byte_len(cx, av, unit_ty, n);
736745
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
737746
}
738747
ty::ty_tup(ref args) => {

src/librustc/middle/trans/debuginfo.rs

+4-77
Original file line numberDiff line numberDiff line change
@@ -2718,81 +2718,6 @@ fn fixed_vec_metadata(cx: &CrateContext,
27182718
return MetadataCreationResult::new(metadata, false);
27192719
}
27202720

2721-
fn heap_vec_metadata(cx: &CrateContext,
2722-
vec_pointer_type: ty::t,
2723-
element_type: ty::t,
2724-
unique_type_id: UniqueTypeId,
2725-
span: Span)
2726-
-> MetadataCreationResult {
2727-
let element_type_metadata = type_metadata(cx, element_type, span);
2728-
let element_llvm_type = type_of::type_of(cx, element_type);
2729-
let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
2730-
2731-
return_if_metadata_created_in_meantime!(cx, unique_type_id);
2732-
2733-
let vecbox_llvm_type = Type::vec(cx, &element_llvm_type);
2734-
let vec_pointer_type_name = compute_debuginfo_type_name(cx,
2735-
vec_pointer_type,
2736-
true);
2737-
let vec_pointer_type_name = vec_pointer_type_name.as_slice();
2738-
2739-
let member_llvm_types = vecbox_llvm_type.field_types();
2740-
2741-
let int_type_metadata = type_metadata(cx, ty::mk_int(), span);
2742-
let array_type_metadata = unsafe {
2743-
llvm::LLVMDIBuilderCreateArrayType(
2744-
DIB(cx),
2745-
bytes_to_bits(element_size),
2746-
bytes_to_bits(element_align),
2747-
element_type_metadata,
2748-
create_DIArray(DIB(cx), [llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, 0)]))
2749-
};
2750-
2751-
let member_descriptions = [
2752-
MemberDescription {
2753-
name: "fill".to_string(),
2754-
llvm_type: *member_llvm_types.get(0),
2755-
type_metadata: int_type_metadata,
2756-
offset: ComputedMemberOffset,
2757-
},
2758-
MemberDescription {
2759-
name: "alloc".to_string(),
2760-
llvm_type: *member_llvm_types.get(1),
2761-
type_metadata: int_type_metadata,
2762-
offset: ComputedMemberOffset,
2763-
},
2764-
MemberDescription {
2765-
name: "elements".to_string(),
2766-
llvm_type: *member_llvm_types.get(2),
2767-
type_metadata: array_type_metadata,
2768-
offset: ComputedMemberOffset,
2769-
}
2770-
];
2771-
2772-
assert!(member_descriptions.len() == member_llvm_types.len());
2773-
2774-
let loc = span_start(cx, span);
2775-
let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2776-
2777-
let vec_box_unique_id = debug_context(cx).type_map
2778-
.borrow_mut()
2779-
.get_unique_type_id_of_heap_vec_box(cx,
2780-
element_type);
2781-
2782-
let vecbox_metadata = composite_type_metadata(cx,
2783-
vecbox_llvm_type,
2784-
vec_pointer_type_name,
2785-
vec_box_unique_id,
2786-
member_descriptions,
2787-
UNKNOWN_SCOPE_METADATA,
2788-
file_metadata,
2789-
span);
2790-
2791-
MetadataCreationResult::new(pointer_type_metadata(cx,
2792-
vec_pointer_type,
2793-
vecbox_metadata), false)
2794-
}
2795-
27962721
fn vec_slice_metadata(cx: &CrateContext,
27972722
vec_type: ty::t,
27982723
element_type: ty::t,
@@ -2995,11 +2920,13 @@ fn type_metadata(cx: &CrateContext,
29952920
ty::ty_uniq(pointee_type) => {
29962921
match ty::get(pointee_type).sty {
29972922
ty::ty_vec(ref mt, None) => {
2998-
heap_vec_metadata(cx, pointee_type, mt.ty, unique_type_id, usage_site_span)
2923+
let vec_metadata = vec_slice_metadata(cx, t, mt.ty, usage_site_span);
2924+
pointer_type_metadata(cx, t, vec_metadata)
29992925
}
30002926
ty::ty_str => {
30012927
let i8_t = ty::mk_i8();
3002-
heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
2928+
let vec_metadata = vec_slice_metadata(cx, t, i8_t, usage_site_span);
2929+
pointer_type_metadata(cx, t, vec_metadata)
30032930
}
30042931
ty::ty_trait(..) => {
30052932
MetadataCreationResult::new(

src/librustc/middle/trans/expr.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
395395
ast::ExprField(ref base, ident, _) => {
396396
trans_rec_field(bcx, &**base, ident.node)
397397
}
398-
ast::ExprIndex(ref base, ref idx) => {
399-
trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
398+
ast::ExprIndex(base, idx) => {
399+
trans_index(bcx, expr.span, &**base, &**idx, MethodCall::expr(expr.id))
400400
}
401401
ast::ExprVstore(ref contents, ast::ExprVstoreUniq) => {
402402
fcx.push_ast_cleanup_scope(contents.id);
@@ -465,7 +465,7 @@ fn trans_rec_field<'a>(bcx: &'a Block<'a>,
465465
}
466466

467467
fn trans_index<'a>(bcx: &'a Block<'a>,
468-
index_expr: &ast::Expr,
468+
sp: codemap::Span,
469469
base: &ast::Expr,
470470
idx: &ast::Expr,
471471
method_call: MethodCall)
@@ -1256,10 +1256,8 @@ fn trans_uniq_expr<'a>(bcx: &'a Block<'a>,
12561256
let llty = type_of::type_of(bcx.ccx(), contents_ty);
12571257
let size = llsize_of(bcx.ccx(), llty);
12581258
let align = C_uint(bcx.ccx(), llalign_of_min(bcx.ccx(), llty) as uint);
1259-
// We need to a make a pointer type because box_ty is ty_bot
1260-
// if content_ty is, e.g. box fail!().
1261-
let real_box_ty = ty::mk_uniq(bcx.tcx(), contents_ty);
1262-
let Result { bcx, val } = malloc_raw_dyn(bcx, real_box_ty, size, align);
1259+
let llty_ptr = llty.ptr_to();
1260+
let Result { bcx, val } = malloc_raw_dyn(bcx, llty_ptr, box_ty, size, align);
12631261
// Unique boxes do not allocate for zero-size types. The standard library
12641262
// may assume that `free` is never called on the pointer returned for
12651263
// `Box<ZeroSizeType>`.

src/librustc/middle/trans/glue.rs

+5-17
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn trans_free<'a>(cx: &'a Block<'a>, v: ValueRef) -> &'a Block<'a> {
5151
Some(expr::Ignore)).bcx
5252
}
5353

54-
fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef, size: u64,
54+
pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef, size: u64,
5555
align: u64) -> &'a Block<'a> {
5656
let _icx = push_ctxt("trans_exchange_free");
5757
let ccx = cx.ccx();
@@ -120,8 +120,8 @@ pub fn drop_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
120120
-> &'a Block<'a> {
121121
// NB: v is an *alias* of type t here, not a direct value.
122122
let _icx = push_ctxt("drop_ty");
123-
let ccx = bcx.ccx();
124123
if ty::type_needs_drop(bcx.tcx(), t) {
124+
let ccx = bcx.ccx();
125125
let glue = get_drop_glue(ccx, t);
126126
let glue_type = get_drop_glue_type(ccx, t);
127127
let ptr = if glue_type != t {
@@ -277,23 +277,11 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
277277
ty::ty_uniq(content_ty) => {
278278
match ty::get(content_ty).sty {
279279
ty::ty_vec(mt, None) => {
280-
let llbox = Load(bcx, v0);
281-
let not_null = IsNotNull(bcx, llbox);
282-
with_cond(bcx, not_null, |bcx| {
283-
let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, mt.ty);
284-
// FIXME: #13994: the old `Box<[T]>` will not support sized deallocation
285-
trans_exchange_free(bcx, llbox, 0, 8)
286-
})
280+
tvec::make_drop_glue_unboxed(bcx, v0, mt.ty)
287281
}
288282
ty::ty_str => {
289-
let llbox = Load(bcx, v0);
290-
let not_null = IsNotNull(bcx, llbox);
291-
with_cond(bcx, not_null, |bcx| {
292-
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
293-
let bcx = tvec::make_drop_glue_unboxed(bcx, llbox, unit_ty);
294-
// FIXME: #13994: the old `Box<str>` will not support sized deallocation
295-
trans_exchange_free(bcx, llbox, 0, 8)
296-
})
283+
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
284+
tvec::make_drop_glue_unboxed(bcx, v0, unit_ty)
297285
}
298286
ty::ty_trait(..) => {
299287
let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);

src/librustc/middle/trans/reflect.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ impl<'a, 'b> Reflector<'a, 'b> {
164164
});
165165
self.visit("box", extra.as_slice())
166166
}
167+
ty::ty_ptr(ref mt) => {
168+
let extra = self.c_mt(mt);
169+
self.visit("ptr", extra.as_slice())
170+
}
167171
ty::ty_uniq(typ) => {
168172
match ty::get(typ).sty {
169173
ty::ty_vec(ref mt, None) => {
@@ -188,17 +192,12 @@ impl<'a, 'b> Reflector<'a, 'b> {
188192
}
189193
}
190194
}
191-
ty::ty_ptr(ref mt) => {
192-
let extra = self.c_mt(mt);
193-
self.visit("ptr", extra.as_slice())
194-
}
195195
ty::ty_rptr(_, ref mt) => {
196196
match ty::get(mt.ty).sty {
197197
ty::ty_vec(ref mt, None) => {
198-
let (name, extra) = ("slice".to_string(), Vec::new());
198+
let extra = Vec::new();
199199
let extra = extra.append(self.c_mt(mt).as_slice());
200-
self.visit(format!("evec_{}", name).as_slice(),
201-
extra.as_slice())
200+
self.visit("evec_slice", extra.as_slice())
202201
}
203202
ty::ty_str => self.visit("estr_slice", &[]),
204203
ty::ty_trait(..) => {

0 commit comments

Comments
 (0)