remove headers from unique vectors

This commit is contained in:
Daniel Micay 2013-07-15 14:23:42 -04:00
parent 04f9ce0ae3
commit e118555ce6
18 changed files with 230 additions and 136 deletions

View file

@ -63,34 +63,33 @@ pub enum LangItem {
FailFnLangItem, // 24 FailFnLangItem, // 24
FailBoundsCheckFnLangItem, // 25 FailBoundsCheckFnLangItem, // 25
ExchangeMallocFnLangItem, // 26 ExchangeMallocFnLangItem, // 26
VectorExchangeMallocFnLangItem, // 27 ClosureExchangeMallocFnLangItem, // 27
ClosureExchangeMallocFnLangItem, // 28 ExchangeFreeFnLangItem, // 28
ExchangeFreeFnLangItem, // 29 MallocFnLangItem, // 29
MallocFnLangItem, // 30 FreeFnLangItem, // 30
FreeFnLangItem, // 31 BorrowAsImmFnLangItem, // 31
BorrowAsImmFnLangItem, // 32 BorrowAsMutFnLangItem, // 32
BorrowAsMutFnLangItem, // 33 ReturnToMutFnLangItem, // 33
ReturnToMutFnLangItem, // 34 CheckNotBorrowedFnLangItem, // 34
CheckNotBorrowedFnLangItem, // 35 StrDupUniqFnLangItem, // 35
StrDupUniqFnLangItem, // 36 RecordBorrowFnLangItem, // 36
RecordBorrowFnLangItem, // 37 UnrecordBorrowFnLangItem, // 37
UnrecordBorrowFnLangItem, // 38
StartFnLangItem, // 39 StartFnLangItem, // 38
TyDescStructLangItem, // 40 TyDescStructLangItem, // 39
TyVisitorTraitLangItem, // 41 TyVisitorTraitLangItem, // 40
OpaqueStructLangItem, // 42 OpaqueStructLangItem, // 41
} }
pub struct LanguageItems { pub struct LanguageItems {
items: [Option<def_id>, ..43] items: [Option<def_id>, ..42]
} }
impl LanguageItems { impl LanguageItems {
pub fn new() -> LanguageItems { pub fn new() -> LanguageItems {
LanguageItems { LanguageItems {
items: [ None, ..43 ] items: [ None, ..42 ]
} }
} }
@ -130,24 +129,23 @@ impl LanguageItems {
24 => "fail_", 24 => "fail_",
25 => "fail_bounds_check", 25 => "fail_bounds_check",
26 => "exchange_malloc", 26 => "exchange_malloc",
27 => "vector_exchange_malloc", 27 => "closure_exchange_malloc",
28 => "closure_exchange_malloc", 28 => "exchange_free",
29 => "exchange_free", 29 => "malloc",
30 => "malloc", 30 => "free",
31 => "free", 31 => "borrow_as_imm",
32 => "borrow_as_imm", 32 => "borrow_as_mut",
33 => "borrow_as_mut", 33 => "return_to_mut",
34 => "return_to_mut", 34 => "check_not_borrowed",
35 => "check_not_borrowed", 35 => "strdup_uniq",
36 => "strdup_uniq", 36 => "record_borrow",
37 => "record_borrow", 37 => "unrecord_borrow",
38 => "unrecord_borrow",
39 => "start", 38 => "start",
40 => "ty_desc", 39 => "ty_desc",
41 => "ty_visitor", 40 => "ty_visitor",
42 => "opaque", 41 => "opaque",
_ => "???" _ => "???"
} }
@ -240,9 +238,6 @@ impl LanguageItems {
pub fn exchange_malloc_fn(&self) -> def_id { pub fn exchange_malloc_fn(&self) -> def_id {
self.items[ExchangeMallocFnLangItem as uint].get() self.items[ExchangeMallocFnLangItem as uint].get()
} }
pub fn vector_exchange_malloc_fn(&self) -> def_id {
self.items[VectorExchangeMallocFnLangItem as uint].get()
}
pub fn closure_exchange_malloc_fn(&self) -> def_id { pub fn closure_exchange_malloc_fn(&self) -> def_id {
self.items[ClosureExchangeMallocFnLangItem as uint].get() self.items[ClosureExchangeMallocFnLangItem as uint].get()
} }
@ -336,7 +331,6 @@ impl<'self> LanguageItemCollector<'self> {
item_refs.insert(@"fail_bounds_check", item_refs.insert(@"fail_bounds_check",
FailBoundsCheckFnLangItem as uint); FailBoundsCheckFnLangItem as uint);
item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint); item_refs.insert(@"exchange_malloc", ExchangeMallocFnLangItem as uint);
item_refs.insert(@"vector_exchange_malloc", VectorExchangeMallocFnLangItem as uint);
item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint); item_refs.insert(@"closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint);
item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint); item_refs.insert(@"exchange_free", ExchangeFreeFnLangItem as uint);
item_refs.insert(@"malloc", MallocFnLangItem as uint); item_refs.insert(@"malloc", MallocFnLangItem as uint);

View file

@ -294,25 +294,6 @@ pub fn malloc_raw_dyn(bcx: block,
[size], [size],
None); None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to())) rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to()))
} else if heap == heap_exchange_vector {
// Grab the TypeRef type of box_ptr_ty.
let element_type = match ty::get(t).sty {
ty::ty_unboxed_vec(e) => e,
_ => fail!("not a vector body")
};
let box_ptr_ty = ty::mk_evec(bcx.tcx(), element_type, ty::vstore_uniq);
let llty = type_of(ccx, box_ptr_ty);
let llty_value = type_of::type_of(ccx, t);
let llalign = llalign_of_min(ccx, llty_value);
// Allocate space:
let r = callee::trans_lang_call(
bcx,
bcx.tcx().lang_items.vector_exchange_malloc_fn(),
[C_i32(llalign as i32), size],
None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
} else { } else {
// we treat ~fn, @fn and @[] as @ here, which isn't ideal // we treat ~fn, @fn and @[] as @ here, which isn't ideal
let (mk_fn, langcall) = match heap { let (mk_fn, langcall) = match heap {
@ -322,7 +303,7 @@ pub fn malloc_raw_dyn(bcx: block,
heap_exchange_closure => { heap_exchange_closure => {
(ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn()) (ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn())
} }
_ => fail!("heap_exchange/heap_exchange_vector already handled") _ => fail!("heap_exchange already handled")
}; };
// Grab the TypeRef type of box_ptr_ty. // Grab the TypeRef type of box_ptr_ty.

View file

@ -283,7 +283,6 @@ pub enum heap {
heap_managed, heap_managed,
heap_managed_unique, heap_managed_unique,
heap_exchange, heap_exchange,
heap_exchange_vector,
heap_exchange_closure heap_exchange_closure
} }
@ -405,7 +404,7 @@ pub fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) {
let f: @fn(block) -> block = |a| glue::trans_free(a, ptr); let f: @fn(block) -> block = |a| glue::trans_free(a, ptr);
f f
} }
heap_exchange | heap_exchange_vector | heap_exchange_closure => { heap_exchange | heap_exchange_closure => {
let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr); let f: @fn(block) -> block = |a| glue::trans_exchange_free(a, ptr);
f f
} }

View file

@ -460,7 +460,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
expr, contents); expr, contents);
} }
ast::expr_vstore(contents, ast::expr_vstore_uniq) => { ast::expr_vstore(contents, ast::expr_vstore_uniq) => {
let heap = tvec::heap_for_unique_vector(bcx, expr_ty(bcx, contents)); let heap = heap_for_unique(bcx, expr_ty(bcx, contents));
return tvec::trans_uniq_or_managed_vstore(bcx, heap, return tvec::trans_uniq_or_managed_vstore(bcx, heap,
expr, contents); expr, contents);
} }

View file

@ -397,9 +397,7 @@ pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) -> block {
ty::ty_uniq(*) => { ty::ty_uniq(*) => {
uniq::make_free_glue(bcx, v, t) uniq::make_free_glue(bcx, v, t)
} }
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => { ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
tvec::make_uniq_free_glue(bcx, v, t)
}
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => { ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => {
make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t)) make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
} }

View file

@ -122,9 +122,9 @@ impl Reflector {
bracket_name: &str, bracket_name: &str,
extra: &[ValueRef], extra: &[ValueRef],
inner: &fn(&mut Reflector)) { inner: &fn(&mut Reflector)) {
self.visit(~"enter_" + bracket_name, extra); self.visit("enter_" + bracket_name, extra);
inner(self); inner(self);
self.visit(~"leave_" + bracket_name, extra); self.visit("leave_" + bracket_name, extra);
} }
pub fn vstore_name_and_extra(&mut self, pub fn vstore_name_and_extra(&mut self,
@ -183,7 +183,11 @@ impl Reflector {
ty::ty_evec(ref mt, vst) => { ty::ty_evec(ref mt, vst) => {
let (name, extra) = self.vstore_name_and_extra(t, vst); let (name, extra) = self.vstore_name_and_extra(t, vst);
let extra = extra + self.c_mt(mt); let extra = extra + self.c_mt(mt);
self.visit(~"evec_" + name, extra) if "uniq" == name && ty::type_contents(bcx.tcx(), t).contains_managed() {
self.visit("evec_uniq_managed", extra)
} else {
self.visit(~"evec_" + name, extra)
}
} }
ty::ty_box(ref mt) => { ty::ty_box(ref mt) => {
let extra = self.c_mt(mt); let extra = self.c_mt(mt);

View file

@ -33,23 +33,6 @@ use std::option::None;
use syntax::ast; use syntax::ast;
use syntax::codemap; use syntax::codemap;
pub fn make_uniq_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
-> block {
let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty);
let not_null = IsNotNull(bcx, box_datum.val);
do with_cond(bcx, not_null) |bcx| {
let body_datum = box_datum.box_body(bcx);
let bcx = glue::drop_ty(bcx, body_datum.to_ref_llval(bcx),
body_datum.ty);
if ty::type_contents(bcx.tcx(), box_ty).contains_managed() {
glue::trans_free(bcx, box_datum.val)
} else {
glue::trans_exchange_free(bcx, box_datum.val)
}
}
}
// Boxed vector types are in some sense currently a "shorthand" for a box // Boxed vector types are in some sense currently a "shorthand" for a box
// containing an unboxed vector. This expands a boxed vector type into such an // containing an unboxed vector. This expands a boxed vector type into such an
// expanded type. It doesn't respect mutability, but that doesn't matter at // expanded type. It doesn't respect mutability, but that doesn't matter at
@ -59,7 +42,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty); let unboxed_vec_ty = ty::mk_mut_unboxed_vec(tcx, unit_ty);
match ty::get(t).sty { match ty::get(t).sty {
ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => { ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) => {
fail!("cannot treat vectors/strings as exchange allocations yet"); ty::mk_imm_uniq(tcx, unboxed_vec_ty)
} }
ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => { ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) => {
ty::mk_imm_box(tcx, unboxed_vec_ty) ty::mk_imm_box(tcx, unboxed_vec_ty)
@ -80,8 +63,12 @@ pub fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef {
Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc])) Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc]))
} }
pub fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef { pub fn get_bodyptr(bcx: block, vptr: ValueRef, t: ty::t) -> ValueRef {
GEPi(bcx, vptr, [0u, abi::box_field_body]) if ty::type_contents(bcx.tcx(), t).contains_managed() {
GEPi(bcx, vptr, [0u, abi::box_field_body])
} else {
vptr
}
} }
pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef { pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef {
@ -104,25 +91,24 @@ pub fn alloc_raw(bcx: block, unit_ty: ty::t,
let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type)); let vecsize = Add(bcx, alloc, llsize_of(ccx, ccx.opaque_vec_type));
let base::MallocResult {bcx, box: bx, body} = if heap == heap_exchange {
base::malloc_general_dyn(bcx, vecbodyty, heap, vecsize); let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, vecbodyty, heap_exchange, vecsize);
Store(bcx, fill, GEPi(bcx, body, [0u, abi::vec_elt_fill])); Store(bcx, fill, GEPi(bcx, val, [0u, abi::vec_elt_fill]));
Store(bcx, alloc, GEPi(bcx, body, [0u, abi::vec_elt_alloc])); Store(bcx, alloc, GEPi(bcx, val, [0u, abi::vec_elt_alloc]));
base::maybe_set_managed_unique_rc(bcx, bx, heap); return rslt(bcx, val);
return rslt(bcx, bx);
}
pub fn heap_for_unique_vector(bcx: block, t: ty::t) -> heap {
if ty::type_contents(bcx.tcx(), t).contains_managed() {
heap_managed_unique
} else { } else {
heap_exchange_vector let base::MallocResult {bcx, box: bx, body} =
base::malloc_general_dyn(bcx, vecbodyty, heap, vecsize);
Store(bcx, fill, GEPi(bcx, body, [0u, abi::vec_elt_fill]));
Store(bcx, alloc, GEPi(bcx, body, [0u, abi::vec_elt_alloc]));
base::maybe_set_managed_unique_rc(bcx, bx, heap);
return rslt(bcx, bx);
} }
} }
pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t, pub fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
fill: ValueRef, alloc: ValueRef) -> Result { fill: ValueRef, alloc: ValueRef) -> Result {
alloc_raw(bcx, unit_ty, fill, alloc, heap_for_unique_vector(bcx, unit_ty)) alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty))
} }
pub fn alloc_vec(bcx: block, pub fn alloc_vec(bcx: block,
@ -146,12 +132,12 @@ pub fn alloc_vec(bcx: block,
pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result {
let _icx = push_ctxt("tvec::duplicate_uniq"); let _icx = push_ctxt("tvec::duplicate_uniq");
let fill = get_fill(bcx, get_bodyptr(bcx, vptr)); let fill = get_fill(bcx, get_bodyptr(bcx, vptr, vec_ty));
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
let Result {bcx, val: newptr} = alloc_uniq_raw(bcx, unit_ty, fill, fill); let Result {bcx, val: newptr} = alloc_uniq_raw(bcx, unit_ty, fill, fill);
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr)); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty));
let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr)); let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr, vec_ty));
base::call_memcpy(bcx, new_data_ptr, data_ptr, fill, 1); base::call_memcpy(bcx, new_data_ptr, data_ptr, fill, 1);
let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) { let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) {
@ -323,7 +309,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
// Handle ~"". // Handle ~"".
match heap { match heap {
heap_exchange_vector => { heap_exchange => {
match content_expr.node { match content_expr.node {
ast::expr_lit(@codemap::spanned { ast::expr_lit(@codemap::spanned {
node: ast::lit_str(s), _ node: ast::lit_str(s), _
@ -346,7 +332,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
_ => {} _ => {}
} }
} }
heap_exchange | heap_exchange_closure => fail!("vectors use vector_exchange_alloc"), heap_exchange_closure => fail!("vectors use exchange_alloc"),
heap_managed | heap_managed_unique => {} heap_managed | heap_managed_unique => {}
} }
@ -356,7 +342,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
let Result {bcx, val} = alloc_vec(bcx, vt.unit_ty, count, heap); let Result {bcx, val} = alloc_vec(bcx, vt.unit_ty, count, heap);
add_clean_free(bcx, val, heap); add_clean_free(bcx, val, heap);
let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val)); let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val, vt.vec_ty));
debug!("alloc_vec() returned val=%s, dataptr=%s", debug!("alloc_vec() returned val=%s, dataptr=%s",
bcx.val_to_str(val), bcx.val_to_str(dataptr)); bcx.val_to_str(val), bcx.val_to_str(dataptr));
@ -562,7 +548,7 @@ pub fn get_base_and_len(bcx: block,
(base, len) (base, len)
} }
ty::vstore_uniq | ty::vstore_box => { ty::vstore_uniq | ty::vstore_box => {
let body = get_bodyptr(bcx, llval); let body = get_bodyptr(bcx, llval, vec_ty);
(get_dataptr(bcx, body), get_fill(bcx, body)) (get_dataptr(bcx, body), get_fill(bcx, body))
} }
} }
@ -604,7 +590,7 @@ pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
fill: ValueRef, f: iter_vec_block) -> block { fill: ValueRef, f: iter_vec_block) -> block {
let _icx = push_ctxt("tvec::iter_vec_uniq"); let _icx = push_ctxt("tvec::iter_vec_uniq");
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr)); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty));
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f) iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
} }

View file

@ -183,7 +183,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
ty::ty_uint(t) => Type::uint_from_ty(cx, t), ty::ty_uint(t) => Type::uint_from_ty(cx, t),
ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_float(t) => Type::float_from_ty(cx, t),
ty::ty_estr(ty::vstore_uniq) => { ty::ty_estr(ty::vstore_uniq) => {
Type::unique(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() Type::vec(cx.sess.targ_cfg.arch, &Type::i8()).ptr_to()
} }
ty::ty_enum(did, ref substs) => { ty::ty_enum(did, ref substs) => {
// Only create the named struct, but don't fill it in. We // Only create the named struct, but don't fill it in. We
@ -217,7 +217,11 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type {
ty::ty_evec(ref mt, ty::vstore_uniq) => { ty::ty_evec(ref mt, ty::vstore_uniq) => {
let ty = type_of(cx, mt.ty); let ty = type_of(cx, mt.ty);
let ty = Type::vec(cx.sess.targ_cfg.arch, &ty); let ty = Type::vec(cx.sess.targ_cfg.arch, &ty);
Type::unique(cx, &ty).ptr_to() if ty::type_contents(cx.tcx, mt.ty).contains_managed() {
Type::unique(cx, &ty).ptr_to()
} else {
ty.ptr_to()
}
} }
ty::ty_unboxed_vec(ref mt) => { ty::ty_unboxed_vec(ref mt) => {
let ty = type_of(cx, mt.ty); let ty = type_of(cx, mt.ty);

View file

@ -297,6 +297,14 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
true true
} }
#[cfg(not(stage0))]
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<~[@u8]>();
if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
self.bump_past::<~[@u8]>();
true
}
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool { fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<&'static [u8]>(); self.align_to::<&'static [u8]>();
if ! self.inner.visit_evec_slice(mtbl, inner) { return false; } if ! self.inner.visit_evec_slice(mtbl, inner) { return false; }

View file

@ -353,6 +353,14 @@ impl TyVisitor for ReprVisitor {
} }
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool { fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&UnboxedVecRepr> |b| {
self.writer.write_char('~');
self.write_unboxed_vec_repr(mtbl, *b, inner);
}
}
#[cfg(not(stage0))]
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
do self.get::<&VecRepr> |b| { do self.get::<&VecRepr> |b| {
self.writer.write_char('~'); self.writer.write_char('~');
self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner); self.write_unboxed_vec_repr(mtbl, &b.unboxed, inner);

View file

@ -84,14 +84,6 @@ pub unsafe fn exchange_malloc(size: uintptr_t) -> *c_char {
malloc_raw(size as uint) as *c_char malloc_raw(size as uint) as *c_char
} }
#[cfg(not(test))]
#[lang="vector_exchange_malloc"]
#[inline]
pub unsafe fn vector_exchange_malloc(align: u32, size: uintptr_t) -> *c_char {
let total_size = get_box_size(size as uint, align as uint);
malloc_raw(total_size as uint) as *c_char
}
// FIXME: #7496 // FIXME: #7496
#[cfg(not(test))] #[cfg(not(test))]
#[lang="closure_exchange_malloc"] #[lang="closure_exchange_malloc"]

View file

@ -1003,6 +1003,7 @@ pub mod raw {
/// Sets the length of the string and adds the null terminator /// Sets the length of the string and adds the null terminator
#[inline] #[inline]
#[cfg(stage0)]
pub unsafe fn set_len(v: &mut ~str, new_len: uint) { pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
let v: **mut vec::raw::VecRepr = cast::transmute(v); let v: **mut vec::raw::VecRepr = cast::transmute(v);
let repr: *mut vec::raw::VecRepr = *v; let repr: *mut vec::raw::VecRepr = *v;
@ -1012,6 +1013,18 @@ pub mod raw {
*null = 0u8; *null = 0u8;
} }
/// Sets the length of the string and adds the null terminator
#[inline]
#[cfg(not(stage0))]
pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
let v: **mut vec::UnboxedVecRepr = cast::transmute(v);
let repr: *mut vec::UnboxedVecRepr = *v;
(*repr).fill = new_len + 1u;
let null = ptr::mut_offset(cast::transmute(&((*repr).data)),
new_len);
*null = 0u8;
}
#[test] #[test]
fn test_from_buf_len() { fn test_from_buf_len() {
unsafe { unsafe {
@ -2027,7 +2040,7 @@ impl NullTerminatedStr for @str {
*/ */
#[inline] #[inline]
fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] { fn as_bytes_with_null<'a>(&'a self) -> &'a [u8] {
let ptr: &'a ~[u8] = unsafe { ::cast::transmute(self) }; let ptr: &'a @[u8] = unsafe { ::cast::transmute(self) };
let slice: &'a [u8] = *ptr; let slice: &'a [u8] = *ptr;
slice slice
} }

View file

@ -99,6 +99,7 @@ pub trait TyVisitor {
fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool; fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool;
fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint, fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint,
mtbl: uint, inner: *TyDesc) -> bool; mtbl: uint, inner: *TyDesc) -> bool;

View file

@ -30,6 +30,7 @@ use ptr::RawPtr;
use rt::global_heap::malloc_raw; use rt::global_heap::malloc_raw;
use rt::global_heap::realloc_raw; use rt::global_heap::realloc_raw;
use sys; use sys;
use sys::size_of;
use uint; use uint;
use unstable::intrinsics; use unstable::intrinsics;
#[cfg(stage0)] #[cfg(stage0)]
@ -108,9 +109,9 @@ pub fn with_capacity<T>(capacity: uint) -> ~[T] {
vec vec
} else { } else {
let alloc = capacity * sys::nonzero_size_of::<T>(); let alloc = capacity * sys::nonzero_size_of::<T>();
let ptr = malloc_raw(alloc + sys::size_of::<raw::VecRepr>()) as *mut raw::VecRepr; let ptr = malloc_raw(alloc + sys::size_of::<UnboxedVecRepr>()) as *mut UnboxedVecRepr;
(*ptr).unboxed.alloc = alloc; (*ptr).alloc = alloc;
(*ptr).unboxed.fill = 0; (*ptr).fill = 0;
cast::transmute(ptr) cast::transmute(ptr)
} }
} }
@ -1150,7 +1151,7 @@ impl<T> OwnedVector<T> for ~[T] {
::at_vec::raw::reserve_raw(td, ptr, n); ::at_vec::raw::reserve_raw(td, ptr, n);
} else { } else {
let alloc = n * sys::nonzero_size_of::<T>(); let alloc = n * sys::nonzero_size_of::<T>();
*ptr = realloc_raw(*ptr as *mut c_void, alloc + sys::size_of::<raw::VecRepr>()) *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>())
as *mut raw::VecRepr; as *mut raw::VecRepr;
(**ptr).unboxed.alloc = alloc; (**ptr).unboxed.alloc = alloc;
} }
@ -1173,19 +1174,20 @@ impl<T> OwnedVector<T> for ~[T] {
// Only make the (slow) call into the runtime if we have to // Only make the (slow) call into the runtime if we have to
if self.capacity() < n { if self.capacity() < n {
unsafe { unsafe {
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
let td = get_tydesc::<T>(); let td = get_tydesc::<T>();
if contains_managed::<T>() { if contains_managed::<T>() {
let ptr: *mut *mut raw::VecRepr = cast::transmute(self);
::at_vec::raw::reserve_raw(td, ptr, n); ::at_vec::raw::reserve_raw(td, ptr, n);
} else { } else {
let ptr: *mut *mut UnboxedVecRepr = cast::transmute(self);
let alloc = n * sys::nonzero_size_of::<T>(); let alloc = n * sys::nonzero_size_of::<T>();
let size = alloc + sys::size_of::<raw::VecRepr>(); let size = alloc + sys::size_of::<UnboxedVecRepr>();
if alloc / sys::nonzero_size_of::<T>() != n || size < alloc { if alloc / sys::nonzero_size_of::<T>() != n || size < alloc {
fail!("vector size is too large: %u", n); fail!("vector size is too large: %u", n);
} }
*ptr = realloc_raw(*ptr as *mut c_void, size) *ptr = realloc_raw(*ptr as *mut c_void, size)
as *mut raw::VecRepr; as *mut UnboxedVecRepr;
(**ptr).unboxed.alloc = alloc; (**ptr).alloc = alloc;
} }
} }
} }
@ -1211,6 +1213,7 @@ impl<T> OwnedVector<T> for ~[T] {
/// Returns the number of elements the vector can hold without reallocating. /// Returns the number of elements the vector can hold without reallocating.
#[inline] #[inline]
#[cfg(stage0)]
fn capacity(&self) -> uint { fn capacity(&self) -> uint {
unsafe { unsafe {
let repr: **raw::VecRepr = transmute(self); let repr: **raw::VecRepr = transmute(self);
@ -1218,8 +1221,24 @@ impl<T> OwnedVector<T> for ~[T] {
} }
} }
/// Returns the number of elements the vector can hold without reallocating.
#[inline]
#[cfg(not(stage0))]
fn capacity(&self) -> uint {
unsafe {
if contains_managed::<T>() {
let repr: **raw::VecRepr = transmute(self);
(**repr).unboxed.alloc / sys::nonzero_size_of::<T>()
} else {
let repr: **UnboxedVecRepr = transmute(self);
(**repr).alloc / sys::nonzero_size_of::<T>()
}
}
}
/// Append an element to a vector /// Append an element to a vector
#[inline] #[inline]
#[cfg(stage0)]
fn push(&mut self, t: T) { fn push(&mut self, t: T) {
unsafe { unsafe {
let repr: **raw::VecRepr = transmute(&mut *self); let repr: **raw::VecRepr = transmute(&mut *self);
@ -1233,8 +1252,36 @@ impl<T> OwnedVector<T> for ~[T] {
} }
} }
/// Append an element to a vector
#[inline]
#[cfg(not(stage0))]
fn push(&mut self, t: T) {
unsafe {
if contains_managed::<T>() {
let repr: **raw::VecRepr = transmute(&mut *self);
let fill = (**repr).unboxed.fill;
if (**repr).unboxed.alloc <= fill {
let new_len = self.len() + 1;
self.reserve_at_least(new_len);
}
self.push_fast(t);
} else {
let repr: **UnboxedVecRepr = transmute(&mut *self);
let fill = (**repr).fill;
if (**repr).alloc <= fill {
let new_len = self.len() + 1;
self.reserve_at_least(new_len);
}
self.push_fast(t);
}
}
}
// This doesn't bother to make sure we have space. // This doesn't bother to make sure we have space.
#[inline] // really pretty please #[inline] // really pretty please
#[cfg(stage0)]
unsafe fn push_fast(&mut self, t: T) { unsafe fn push_fast(&mut self, t: T) {
let repr: **mut raw::VecRepr = transmute(self); let repr: **mut raw::VecRepr = transmute(self);
let fill = (**repr).unboxed.fill; let fill = (**repr).unboxed.fill;
@ -1244,6 +1291,27 @@ impl<T> OwnedVector<T> for ~[T] {
intrinsics::move_val_init(&mut(*p), t); intrinsics::move_val_init(&mut(*p), t);
} }
// This doesn't bother to make sure we have space.
#[inline] // really pretty please
#[cfg(not(stage0))]
unsafe fn push_fast(&mut self, t: T) {
if contains_managed::<T>() {
let repr: **mut raw::VecRepr = transmute(self);
let fill = (**repr).unboxed.fill;
(**repr).unboxed.fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).unboxed.data));
let p = ptr::offset(p, fill) as *mut T;
intrinsics::move_val_init(&mut(*p), t);
} else {
let repr: **mut UnboxedVecRepr = transmute(self);
let fill = (**repr).fill;
(**repr).fill += sys::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data));
let p = ptr::offset(p, fill) as *mut T;
intrinsics::move_val_init(&mut(*p), t);
}
}
/// Takes ownership of the vector `rhs`, moving all elements into /// Takes ownership of the vector `rhs`, moving all elements into
/// the current vector. This does not copy any elements, and it is /// the current vector. This does not copy any elements, and it is
/// illegal to use the `rhs` vector after calling this method /// illegal to use the `rhs` vector after calling this method
@ -1834,6 +1902,8 @@ pub mod raw {
use unstable::intrinsics; use unstable::intrinsics;
use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector}; use vec::{UnboxedVecRepr, with_capacity, ImmutableVector, MutableVector};
use util; use util;
#[cfg(not(stage0))]
use unstable::intrinsics::contains_managed;
/// The internal representation of a (boxed) vector /// The internal representation of a (boxed) vector
#[allow(missing_doc)] #[allow(missing_doc)]
@ -1858,11 +1928,31 @@ pub mod raw {
* the vector is actually the specified size. * the vector is actually the specified size.
*/ */
#[inline] #[inline]
#[cfg(stage0)]
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) { pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
let repr: **mut VecRepr = transmute(v); let repr: **mut VecRepr = transmute(v);
(**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>(); (**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
} }
/**
* Sets the length of a vector
*
* This will explicitly set the size of the vector, without actually
* modifing its buffers, so it is up to the caller to ensure that
* the vector is actually the specified size.
*/
#[inline]
#[cfg(not(stage0))]
pub unsafe fn set_len<T>(v: &mut ~[T], new_len: uint) {
if contains_managed::<T>() {
let repr: **mut VecRepr = transmute(v);
(**repr).unboxed.fill = new_len * sys::nonzero_size_of::<T>();
} else {
let repr: **mut UnboxedVecRepr = transmute(v);
(**repr).fill = new_len * sys::nonzero_size_of::<T>();
}
}
/** /**
* Returns an unsafe pointer to the vector's buffer * Returns an unsafe pointer to the vector's buffer
* *

View file

@ -390,9 +390,9 @@ void tm_to_rust_tm(tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
if (zone != NULL) { if (zone != NULL) {
size_t size = strlen(zone); size_t size = strlen(zone);
reserve_vec_exact(&out_tm->tm_zone, size + 1); reserve_vec_exact(&out_tm->tm_zone, size + 1);
memcpy(out_tm->tm_zone->body.data, zone, size); memcpy(out_tm->tm_zone->data, zone, size);
out_tm->tm_zone->body.fill = size + 1; out_tm->tm_zone->fill = size + 1;
out_tm->tm_zone->body.data[size] = '\0'; out_tm->tm_zone->data[size] = '\0';
} }
} }

View file

@ -57,17 +57,17 @@ vec_data(rust_vec *v) {
return reinterpret_cast<T*>(v->data); return reinterpret_cast<T*>(v->data);
} }
inline void reserve_vec_exact(rust_vec_box** vpp, inline void reserve_vec_exact(rust_vec** vpp,
size_t size) { size_t size) {
if (size > (*vpp)->body.alloc) { if (size > (*vpp)->alloc) {
rust_exchange_alloc exchange_alloc; rust_exchange_alloc exchange_alloc;
*vpp = (rust_vec_box*)exchange_alloc *vpp = (rust_vec*)exchange_alloc
.realloc(*vpp, size + sizeof(rust_vec_box)); .realloc(*vpp, size + sizeof(rust_vec));
(*vpp)->body.alloc = size; (*vpp)->alloc = size;
} }
} }
typedef rust_vec_box rust_str; typedef rust_vec rust_str;
inline size_t get_box_size(size_t body_size, size_t body_align) { inline size_t get_box_size(size_t body_size, size_t body_align) {
size_t header_size = sizeof(rust_opaque_box); size_t header_size = sizeof(rust_opaque_box);

View file

@ -284,6 +284,13 @@ impl<V:TyVisitor + movable_ptr> TyVisitor for ptr_visit_adaptor<V> {
true true
} }
fn visit_evec_uniq_managed(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<~[@u8]>();
if ! self.inner.visit_evec_uniq_managed(mtbl, inner) { return false; }
self.bump_past::<~[@u8]>();
true
}
fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool { fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool {
self.align_to::<&'static [u8]>(); self.align_to::<&'static [u8]>();
if ! self.inner.visit_evec_slice(mtbl, inner) { return false; } if ! self.inner.visit_evec_slice(mtbl, inner) { return false; }
@ -567,6 +574,7 @@ impl TyVisitor for my_visitor {
fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_unboxed_vec(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_evec_box(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_evec_uniq(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_uniq_managed(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint, fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint,
_mtbl: uint, _inner: *TyDesc) -> bool { true } _mtbl: uint, _inner: *TyDesc) -> bool { true }

View file

@ -85,6 +85,14 @@ impl TyVisitor for MyVisitor {
self.types.push(~"]"); self.types.push(~"]");
true true
} }
fn visit_evec_uniq_managed(&self, _mtbl: uint, inner: *TyDesc) -> bool {
self.types.push(~"[");
unsafe {
visit_tydesc(inner, (@*self) as @TyVisitor);
}
self.types.push(~"]");
true
}
fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true } fn visit_evec_slice(&self, _mtbl: uint, _inner: *TyDesc) -> bool { true }
fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint, fn visit_evec_fixed(&self, _n: uint, _sz: uint, _align: uint,
_mtbl: uint, _inner: *TyDesc) -> bool { true } _mtbl: uint, _inner: *TyDesc) -> bool { true }