Skip to content

Commit

Permalink
auto merge of #13344 : eddyb/rust/kill-unboxed-vec, r=cmr
Browse files Browse the repository at this point in the history
Removes the special `ty_unboxed_vec` type from the type system.
It was previously used only during translating `~[T]`/`~str` allocation and drop glue.
  • Loading branch information
bors committed Apr 6, 2014
2 parents f1f5056 + 2d22243 commit 4af69f2
Show file tree
Hide file tree
Showing 24 changed files with 208 additions and 375 deletions.
1 change: 0 additions & 1 deletion src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
let mt = parse_mt(st, |x,y| conv(x,y));
return ty::mk_rptr(st.tcx, r, mt);
}
'U' => return ty::mk_unboxed_vec(st.tcx, parse_mt(st, |x,y| conv(x,y))),
'V' => {
let mt = parse_mt(st, |x,y| conv(x,y));
let v = parse_vstore(st, |x,y| conv(x,y));
Expand Down
1 change: 0 additions & 1 deletion src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
mywrite!(w, "v");
enc_vstore(w, cx, v);
}
ty::ty_unboxed_vec(mt) => { mywrite!(w, "U"); enc_mt(w, cx, mt); }
ty::ty_closure(ref f) => {
mywrite!(w, "f");
enc_closure_ty(w, cx, *f);
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, pats: Vec<@Pat> ) {
}
}
}
ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
ty::ty_vec(..) => {
match *ctor {
vec(n) => Some(format!("vectors of length {}", n)),
_ => None
Expand Down Expand Up @@ -282,7 +282,7 @@ fn is_useful(cx: &MatchCheckCtxt, m: &matrix, v: &[@Pat]) -> useful {
ty::ty_vec(_, ty::vstore_fixed(n)) => {
is_useful_specialized(cx, m, v, vec(n), n, left_ty)
}
ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
ty::ty_vec(..) => {
let max_len = m.iter().rev().fold(0, |max_len, r| {
match r.get(0).node {
PatVec(ref before, _, ref after) => {
Expand Down Expand Up @@ -464,7 +464,7 @@ fn missing_ctor(cx: &MatchCheckCtxt,
_ => None
}
}
ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
ty::ty_vec(..) => {

// Find the lengths and slices of all vector patterns.
let mut vec_pat_lens = m.iter().filter_map(|r| {
Expand Down Expand Up @@ -529,7 +529,7 @@ fn ctor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
}
}
ty::ty_struct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
ty::ty_unboxed_vec(..) | ty::ty_vec(..) => {
ty::ty_vec(..) => {
match *ctor {
vec(n) => n,
_ => 0u
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,8 @@ fn extract_vec_elems<'a>(
let _icx = push_ctxt("match::extract_vec_elems");
let vec_datum = match_datum(bcx, val, pat_id);
let (base, len) = vec_datum.get_vec_base_and_len(bcx);
let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
let vec_ty = node_id_type(bcx, pat_id);
let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty));

let mut elems = Vec::from_fn(elem_count, |i| {
match slice {
Expand Down Expand Up @@ -1681,8 +1682,8 @@ fn compile_submatch_continue<'r,
kind = compare;
},
vec_len(..) => {
let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id));
let (_, len) = tvec::get_base_and_len(bcx, val, vt.vec_ty);
let vec_ty = node_id_type(bcx, pat_id);
let (_, len) = tvec::get_base_and_len(bcx, val, vec_ty);
test_val = len;
kind = compare_vec_len;
}
Expand Down
151 changes: 52 additions & 99 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ use lib;
use metadata::{csearch, encoder};
use middle::astencode;
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
use middle::lang_items::{MallocFnLangItem, ClosureExchangeMallocFnLangItem};
use middle::trans::_match;
use middle::trans::adt;
use middle::trans::build::*;
Expand Down Expand Up @@ -336,111 +335,64 @@ pub fn at_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef) -> ValueRef {
GEPi(bcx, boxptr, [0u, abi::box_field_body])
}

// malloc_raw_dyn: allocates a box to contain a given type, but with a
// potentially dynamic size.
pub fn malloc_raw_dyn<'a>(
bcx: &'a Block<'a>,
t: ty::t,
heap: heap,
size: ValueRef)
-> Result<'a> {
let _icx = push_ctxt("malloc_raw");
let ccx = bcx.ccx();

fn require_alloc_fn(bcx: &Block, t: ty::t, it: LangItem) -> ast::DefId {
let li = &bcx.tcx().lang_items;
match li.require(it) {
Ok(id) => id,
Err(s) => {
bcx.sess().fatal(format!("allocation of `{}` {}",
bcx.ty_to_str(t), s));
}
fn require_alloc_fn(bcx: &Block, info_ty: ty::t, it: LangItem) -> ast::DefId {
match bcx.tcx().lang_items.require(it) {
Ok(id) => id,
Err(s) => {
bcx.sess().fatal(format!("allocation of `{}` {}",
bcx.ty_to_str(info_ty), s));
}
}
}

if heap == heap_exchange {
let llty_value = type_of::type_of(ccx, t);

// Allocate space:
let r = callee::trans_lang_call(
bcx,
require_alloc_fn(bcx, t, ExchangeMallocFnLangItem),
[size],
None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to()))
} else {
// we treat ~fn as @ here, which isn't ideal
let langcall = match heap {
heap_managed => {
require_alloc_fn(bcx, t, MallocFnLangItem)
}
heap_exchange_closure => {
require_alloc_fn(bcx, t, ClosureExchangeMallocFnLangItem)
}
_ => fail!("heap_exchange already handled")
};
// The following malloc_raw_dyn* functions allocate a box to contain
// a given type, but with a potentially dynamic size.

// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);
let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);

// Allocate space:
let drop_glue = glue::get_drop_glue(ccx, t);
let r = callee::trans_lang_call(
bcx,
langcall,
[
PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
size,
llalign
],
None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
}
}

// malloc_raw: expects an unboxed type and returns a pointer to
// enough space for a box of that type. This includes a rust_opaque_box
// header.
pub fn malloc_raw<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap)
-> Result<'a> {
let ty = type_of(bcx.ccx(), t);
let size = llsize_of(bcx.ccx(), ty);
malloc_raw_dyn(bcx, t, heap, size)
}

pub struct MallocResult<'a> {
pub bcx: &'a Block<'a>,
pub smart_ptr: ValueRef,
pub body: ValueRef
}

// malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a smart
// pointer, and pulls out the body
pub fn malloc_general_dyn<'a>(
bcx: &'a Block<'a>,
t: ty::t,
heap: heap,
pub fn malloc_raw_dyn<'a>(bcx: &'a Block<'a>,
ptr_ty: ty::t,
size: ValueRef)
-> MallocResult<'a> {
assert!(heap != heap_exchange);
let _icx = push_ctxt("malloc_general");
let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size);
let body = GEPi(bcx, llbox, [0u, abi::box_field_body]);
-> Result<'a> {
let _icx = push_ctxt("malloc_raw_exchange");
let ccx = bcx.ccx();

MallocResult {
bcx: bcx,
smart_ptr: llbox,
body: body,
}
// Allocate space:
let r = callee::trans_lang_call(bcx,
require_alloc_fn(bcx, ptr_ty, ExchangeMallocFnLangItem),
[size],
None);

let llty_ptr = type_of::type_of(ccx, ptr_ty);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
}

pub fn malloc_general<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap)
-> MallocResult<'a> {
let ty = type_of(bcx.ccx(), t);
assert!(heap != heap_exchange);
malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty))
pub fn malloc_raw_dyn_managed<'a>(
bcx: &'a Block<'a>,
t: ty::t,
alloc_fn: LangItem,
size: ValueRef)
-> Result<'a> {
let _icx = push_ctxt("malloc_raw_managed");
let ccx = bcx.ccx();

let langcall = require_alloc_fn(bcx, t, alloc_fn);

// Grab the TypeRef type of box_ptr_ty.
let box_ptr_ty = ty::mk_box(bcx.tcx(), t);
let llty = type_of(ccx, box_ptr_ty);
let llalign = C_uint(ccx, llalign_of_min(ccx, llty) as uint);

// Allocate space:
let drop_glue = glue::get_drop_glue(ccx, t);
let r = callee::trans_lang_call(
bcx,
langcall,
[
PointerCast(bcx, drop_glue, Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to()),
size,
llalign
],
None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty))
}

// Type descriptor and type glue stuff
Expand Down Expand Up @@ -708,7 +660,8 @@ pub fn iter_structural_ty<'r,
ty::ty_str(ty::vstore_fixed(_)) |
ty::ty_vec(_, ty::vstore_fixed(_)) => {
let (base, len) = tvec::get_base_and_byte_len(cx, av, t);
cx = tvec::iter_vec_raw(cx, base, t, len, f);
let unit_ty = ty::sequence_element_type(cx.tcx(), t);
cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
}
ty::ty_tup(ref args) => {
let repr = adt::represent_type(cx.ccx(), t);
Expand Down
15 changes: 10 additions & 5 deletions src/librustc/middle/trans/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl<'a> CleanupMethods<'a> for FunctionContext<'a> {
fn schedule_free_value(&self,
cleanup_scope: ScopeId,
val: ValueRef,
heap: common::heap) {
heap: Heap) {
/*!
* Schedules a call to `free(val)`. Note that this is a shallow
* operation.
Expand Down Expand Up @@ -814,9 +814,14 @@ impl Cleanup for DropValue {
}
}

pub enum Heap {
HeapManaged,
HeapExchange
}

pub struct FreeValue {
ptr: ValueRef,
heap: common::heap,
heap: Heap,
}

impl Cleanup for FreeValue {
Expand All @@ -826,10 +831,10 @@ impl Cleanup for FreeValue {

fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
match self.heap {
common::heap_managed => {
HeapManaged => {
glue::trans_free(bcx, self.ptr)
}
common::heap_exchange | common::heap_exchange_closure => {
HeapExchange => {
glue::trans_exchange_free(bcx, self.ptr)
}
}
Expand Down Expand Up @@ -901,7 +906,7 @@ pub trait CleanupMethods<'a> {
fn schedule_free_value(&self,
cleanup_scope: ScopeId,
val: ValueRef,
heap: common::heap);
heap: Heap);
fn schedule_clean(&self,
cleanup_scope: ScopeId,
cleanup: ~Cleanup);
Expand Down
7 changes: 6 additions & 1 deletion src/librustc/middle/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ use back::abi;
use back::link::mangle_internal_name_by_path_and_seq;
use driver::session::FullDebugInfo;
use lib::llvm::ValueRef;
use middle::lang_items::ClosureExchangeMallocFnLangItem;
use middle::moves;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::common::*;
use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
use middle::trans::debuginfo;
use middle::trans::expr;
use middle::trans::machine::llsize_of;
use middle::trans::type_of::*;
use middle::trans::type_::Type;
use middle::ty;
Expand Down Expand Up @@ -168,7 +170,10 @@ fn allocate_cbox<'a>(bcx: &'a Block<'a>,
tcx.sess.bug("trying to trans allocation of @fn")
}
ast::OwnedSigil => {
malloc_raw(bcx, cdata_ty, heap_exchange_closure)
let ty = type_of(bcx.ccx(), cdata_ty);
let size = llsize_of(bcx.ccx(), ty);
// we treat proc as @ here, which isn't ideal
malloc_raw_dyn_managed(bcx, cdata_ty, ClosureExchangeMallocFnLangItem, size)
}
ast::BorrowedSigil => {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
Expand Down
8 changes: 0 additions & 8 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,14 +386,6 @@ impl<'a> FunctionContext<'a> {
}
}

// Heap selectors. Indicate which heap something should go on.
#[deriving(Eq)]
pub enum heap {
heap_managed,
heap_exchange,
heap_exchange_closure
}

// Basic block context. We create a block context for each basic block
// (single-entry, single-exit sequence of instructions) we generate from Rust
// code. Each basic block we generate is attached to a function, typically
Expand Down
Loading

0 comments on commit 4af69f2

Please sign in to comment.