Skip to content

Removed take_glue from tydesc. #11723

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 27, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/librustc/back/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ pub static general_code_alignment: uint = 16u;

pub static tydesc_field_size: uint = 0u;
pub static tydesc_field_align: uint = 1u;
pub static tydesc_field_take_glue: uint = 2u;
pub static tydesc_field_drop_glue: uint = 3u;
pub static tydesc_field_visit_glue: uint = 4u;
pub static tydesc_field_name_offset: uint = 5u;
pub static n_tydesc_fields: uint = 6u;
pub static tydesc_field_drop_glue: uint = 2u;
pub static tydesc_field_visit_glue: uint = 3u;
pub static tydesc_field_name_offset: uint = 4u;
pub static n_tydesc_fields: uint = 5u;

// The two halves of a closure: code and environment.
pub static fn_field_code: uint = 0u;
Expand Down
40 changes: 16 additions & 24 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -777,16 +777,16 @@ pub fn iter_structural_ty<'r,
let variant_cx =
fcx.new_temp_block(~"enum-iter-variant-" +
variant.disr_val.to_str());
let variant_cx =
iter_variant(variant_cx, repr, av, *variant,
substs.tps, |x,y,z| f(x,y,z));
match adt::trans_case(cx, repr, variant.disr_val) {
_match::single_result(r) => {
AddCase(llswitch, r.val, variant_cx.llbb)
}
_ => ccx.sess.unimpl("value from adt::trans_case \
in iter_structural_ty")
}
let variant_cx =
iter_variant(variant_cx, repr, av, *variant,
substs.tps, |x,y,z| f(x,y,z));
Br(variant_cx, next_cx.llbb);
}
cx = next_cx;
Expand Down Expand Up @@ -1458,16 +1458,16 @@ pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
// trans_closure: Builds an LLVM function out of a source function.
// If the function closes over its environment a closure will be
// returned.
pub fn trans_closure(ccx: @CrateContext,
path: ast_map::Path,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: |&FunctionContext|) {
pub fn trans_closure<'a>(ccx: @CrateContext,
path: ast_map::Path,
decl: &ast::FnDecl,
body: &ast::Block,
llfndecl: ValueRef,
param_substs: Option<@param_substs>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
output_type: ty::t,
maybe_load_env: |&'a Block<'a>| -> &'a Block<'a>) {
ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1);

let _icx = push_ctxt("trans_closure");
Expand Down Expand Up @@ -1500,7 +1500,7 @@ pub fn trans_closure(ccx: @CrateContext,

bcx = copy_args_to_allocas(&fcx, arg_scope, bcx, decl.inputs, arg_datums);

maybe_load_env(&fcx);
bcx = maybe_load_env(bcx);

// Up until here, IR instructions for this function have explicitly not been annotated with
// source code location, so we don't step into call setup code. From here on, source location
Expand Down Expand Up @@ -1558,16 +1558,8 @@ pub fn trans_fn(ccx: @CrateContext,
debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx));
let _icx = push_ctxt("trans_fn");
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
trans_closure(ccx,
path.clone(),
decl,
body,
llfndecl,
param_substs,
id,
attrs,
output_type,
|_fcx| { });
trans_closure(ccx, path.clone(), decl, body, llfndecl,
param_substs, id, attrs, output_type, |bcx| bcx);
}

pub fn trans_enum_variant(ccx: @CrateContext,
Expand Down
19 changes: 10 additions & 9 deletions src/librustc/middle/trans/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,23 +282,22 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
// Given an enclosing block context, a new function context, a closure type,
// and a list of upvars, generate code to load and populate the environment
// with the upvars and type descriptors.
fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar], sigil: ast::Sigil) {
fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
cap_vars: &[moves::CaptureVar],
sigil: ast::Sigil) -> &'a Block<'a> {
let _icx = push_ctxt("closure::load_environment");

// Don't bother to create the block if there's nothing to load
if cap_vars.len() == 0 {
return;
return bcx;
}

let bcx = fcx.entry_bcx.get().unwrap();

// Load a pointer to the closure data, skipping over the box header:
let llcdata = at_box_body(bcx, cdata_ty, fcx.llenv.unwrap());
let llcdata = at_box_body(bcx, cdata_ty, bcx.fcx.llenv.unwrap());

// Store the pointer to closure data in an alloca for debug info because that's what the
// llvm.dbg.declare intrinsic expects
let env_pointer_alloca = if fcx.ccx.sess.opts.extra_debuginfo {
let env_pointer_alloca = if bcx.ccx().sess.opts.extra_debuginfo {
let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), cdata_ty), "__debuginfo_env_ptr");
Store(bcx, llcdata, alloc);
Some(alloc)
Expand All @@ -317,7 +316,7 @@ fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,
let def_id = ast_util::def_id_of_def(cap_var.def);

{
let mut llupvars = fcx.llupvars.borrow_mut();
let mut llupvars = bcx.fcx.llupvars.borrow_mut();
llupvars.get().insert(def_id.node, upvarptr);
}

Expand All @@ -334,6 +333,8 @@ fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,

i += 1u;
}

bcx
}

fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) {
Expand Down Expand Up @@ -405,7 +406,7 @@ pub fn trans_expr_fn<'a>(
trans_closure(ccx, sub_path, decl, body, llfn,
bcx.fcx.param_substs, user_id,
[], ty::ty_fn_ret(fty),
|fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
|bcx| load_environment(bcx, cdata_ty, cap_vars, sigil));
fill_fn_pair(bcx, dest_addr, llfn, llbox);

bcx
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ pub struct tydesc_info {
size: ValueRef,
align: ValueRef,
name: ValueRef,
take_glue: Cell<Option<ValueRef>>,
drop_glue: Cell<Option<ValueRef>>,
visit_glue: Cell<Option<ValueRef>>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ impl Datum<Expr> {
}
ByValue => {
let v = load(bcx, l.val, l.ty);
l.kind.post_store(bcx, l.val, l.ty);
bcx = l.kind.post_store(bcx, l.val, l.ty);
DatumBlock(bcx, Datum(v, l.ty, Rvalue(ByValue)))
}
}
Expand Down
134 changes: 29 additions & 105 deletions src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,24 @@ pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef)
Some(expr::Ignore)).bcx
}

pub fn take_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
pub fn take_ty<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
-> &'a Block<'a> {
// NB: v is an *alias* of type t here, not a direct value.
let _icx = push_ctxt("take_ty");
if ty::type_needs_drop(cx.tcx(), t) {
return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
match ty::get(t).sty {
ty::ty_box(_) |
ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
incr_refcnt_of_boxed(bcx, v)
}
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
incr_refcnt_of_boxed(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]))
}
_ if ty::type_is_structural(t)
&& ty::type_needs_drop(bcx.tcx(), t) => {
iter_structural_ty(bcx, v, t, take_ty)
}
_ => bcx
}
return cx;
}

pub fn drop_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t)
Expand All @@ -88,30 +98,15 @@ pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)

pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext,
static_ti: @tydesc_info) {
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
}

fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
if (field == abi::tydesc_field_take_glue || field == abi::tydesc_field_drop_glue)
&& !ty::type_needs_drop(tcx, t) {
return ty::mk_nil();
}

if field == abi::tydesc_field_take_glue {
match ty::get(t).sty {
ty::ty_str(ty::vstore_uniq) | ty::ty_vec(_, ty::vstore_uniq) |
ty::ty_unboxed_vec(..) | ty::ty_uniq(..) => return ty::mk_nil(),
_ => {}
}
}

if field == abi::tydesc_field_take_glue && ty::type_is_boxed(t) {
return ty::mk_box(tcx, ty::mk_nil());
}

if field == abi::tydesc_field_drop_glue {
if !ty::type_needs_drop(tcx, t) {
return ty::mk_nil();
}
match ty::get(t).sty {
ty::ty_box(typ)
if !ty::type_needs_drop(tcx, typ) =>
Expand Down Expand Up @@ -145,9 +140,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
let simpl_ti = get_tydesc(ccx, simpl);
lazily_emit_tydesc_glue(ccx, field, simpl_ti);

if field == abi::tydesc_field_take_glue {
ti.take_glue.set(simpl_ti.take_glue.get());
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
ti.drop_glue.set(simpl_ti.drop_glue.get());
} else if field == abi::tydesc_field_visit_glue {
ti.visit_glue.set(simpl_ti.visit_glue.get());
Expand All @@ -158,20 +151,7 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {

let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to());

if field == abi::tydesc_field_take_glue {
match ti.take_glue.get() {
Some(_) => (),
None => {
debug!("+++ lazily_emit_tydesc_glue TAKE {}",
ppaux::ty_to_str(ccx.tcx, ti.ty));
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "take");
ti.take_glue.set(Some(glue_fn));
make_generic_glue(ccx, ti.ty, glue_fn, make_take_glue, "take");
debug!("--- lazily_emit_tydesc_glue TAKE {}",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
match ti.drop_glue.get() {
Some(_) => (),
None => {
Expand Down Expand Up @@ -213,9 +193,7 @@ pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef,
None => None,
Some(sti) => {
lazily_emit_tydesc_glue(ccx, field, sti);
if field == abi::tydesc_field_take_glue {
sti.take_glue.get()
} else if field == abi::tydesc_field_drop_glue {
if field == abi::tydesc_field_drop_glue {
sti.drop_glue.get()
} else if field == abi::tydesc_field_visit_glue {
sti.visit_glue.get()
Expand Down Expand Up @@ -472,53 +450,16 @@ fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef,
next_bcx
}

fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) -> &'a Block<'a> {
let _icx = push_ctxt("make_take_glue");
// NB: v is a *pointer* to type t here, not a direct value.
match ty::get(t).sty {
ty::ty_box(_) |
ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
}
ty::ty_vec(_, ty::vstore_slice(_))
| ty::ty_str(ty::vstore_slice(_)) => {
bcx
}
ty::ty_closure(_) => bcx,
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
incr_refcnt_of_boxed(bcx, llbox);
bcx
}
ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]);
let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable]));

// Cast the vtable to a pointer to a pointer to a tydesc.
let llvtable = PointerCast(bcx, llvtable,
bcx.ccx().tydesc_type.ptr_to().ptr_to());
let lltydesc = Load(bcx, llvtable);
call_tydesc_glue_full(bcx,
lluniquevalue,
lltydesc,
abi::tydesc_field_take_glue,
None);
bcx
}
_ if ty::type_is_structural(t) => {
iter_structural_ty(bcx, v, t, take_ty)
}
_ => bcx
}
}

fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) {
fn incr_refcnt_of_boxed<'a>(bcx: &'a Block<'a>,
box_ptr_ptr: ValueRef) -> &'a Block<'a> {
let _icx = push_ctxt("incr_refcnt_of_boxed");
let ccx = cx.ccx();
let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]);
let rc = Load(cx, rc_ptr);
let rc = Add(cx, rc, C_int(ccx, 1));
Store(cx, rc, rc_ptr);
let ccx = bcx.ccx();
let box_ptr = Load(bcx, box_ptr_ptr);
let rc_ptr = GEPi(bcx, box_ptr, [0u, abi::box_field_refcnt]);
let rc = Load(bcx, rc_ptr);
let rc = Add(bcx, rc, C_int(ccx, 1));
Store(bcx, rc, rc_ptr);
bcx
}


Expand Down Expand Up @@ -554,7 +495,6 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info {
size: llsize,
align: llalign,
name: ty_name,
take_glue: Cell::new(None),
drop_glue: Cell::new(None),
visit_glue: Cell::new(None),
};
Expand Down Expand Up @@ -616,21 +556,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
// before being put into the tydesc because we only have a singleton
// tydesc type. Then we'll recast each function to its real type when
// calling it.
let take_glue =
match ti.take_glue.get() {
None => {
ccx.stats.n_null_glues.set(ccx.stats.n_null_glues.get() +
1);
C_null(glue_fn_ty)
}
Some(v) => {
unsafe {
ccx.stats.n_real_glues.set(ccx.stats.n_real_glues.get() +
1);
llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref())
}
}
};
let drop_glue =
match ti.drop_glue.get() {
None => {
Expand Down Expand Up @@ -665,7 +590,6 @@ pub fn emit_tydescs(ccx: &CrateContext) {
let tydesc = C_named_struct(ccx.tydesc_type,
[ti.size, // size
ti.align, // align
take_glue, // take_glue
drop_glue, // drop_glue
visit_glue, // visit_glue
ti.name]); // name
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/trans/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ impl Type {

let elems = [int_ty, // size
int_ty, // align
glue_fn_ty, // take
glue_fn_ty, // drop
glue_fn_ty, // visit
Type::struct_([Type::i8p(), Type::int(arch)], false)]; // name
Expand Down
2 changes: 2 additions & 0 deletions src/libstd/unstable/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub struct TyDesc {
align: uint,

// Called on a copy of a value of type `T` *after* memcpy
// NOTE remove after next snapshot
#[cfg(stage0)]
take_glue: GlueFn,

// Called when a value of type `T` is no longer needed
Expand Down