From ca115dd083a1fe1d2b4892c5e50e49eb83ff1f3c Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Wed, 21 Dec 2016 14:29:34 -0700 Subject: [PATCH] Remove extra lang item, exchange_free; use box_free instead. Trans used to insert code equivalent to box_free in a wrapper around exchange_free, and that code is now removed from trans. --- src/liballoc/heap.rs | 1 + src/librustc/middle/lang_items.rs | 1 - src/librustc_trans/collector.rs | 28 ++++++------- src/librustc_trans/glue.rs | 66 +++++++++---------------------- 4 files changed, 32 insertions(+), 64 deletions(-) diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index a1e3263698081..81ed4be7763e9 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -144,6 +144,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { } #[cfg(not(test))] +#[cfg(stage0)] #[lang = "exchange_free"] #[inline] unsafe fn exchange_free(ptr: *mut u8, old_size: usize, align: usize) { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 1efc211b8c35b..029a1d66add0b 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -328,7 +328,6 @@ language_item_table! { PanicFmtLangItem, "panic_fmt", panic_fmt; ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn; - ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn; BoxFreeFnLangItem, "box_free", box_free_fn; StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn; diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index d8c212745376d..84222bfe56eee 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -193,9 +193,9 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem}; +use rustc::middle::lang_items::{BoxFreeFnLangItem, ExchangeMallocFnLangItem}; use rustc::traits; -use rustc::ty::subst::{Substs, Subst}; +use rustc::ty::subst::{Kind, Substs, Subst}; use rustc::ty::{self, TypeFoldable, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::mir::{self, Location}; @@ -215,6 +215,8 @@ use util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use trans_item::{TransItem, DefPathBasedNames}; +use std::iter; + #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum TransItemCollectionMode { Eager, @@ -723,23 +725,17 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, debug!("find_drop_glue_neighbors: {}", type_to_string(scx.tcx(), ty)); - // Make sure the exchange_free_fn() lang-item gets translated if - // there is a boxed value. - if let ty::TyBox(_) = ty.sty { - let exchange_free_fn_def_id = scx.tcx() - .lang_items - .require(ExchangeFreeFnLangItem) - .unwrap_or_else(|e| scx.sess().fatal(&e)); - - assert!(can_have_local_instance(scx.tcx(), exchange_free_fn_def_id)); - let fn_substs = scx.empty_substs_for_def_id(exchange_free_fn_def_id); - let exchange_free_fn_trans_item = + // Make sure the BoxFreeFn lang-item gets translated if there is a boxed value. + if let ty::TyBox(content_type) = ty.sty { + let def_id = scx.tcx().require_lang_item(BoxFreeFnLangItem); + assert!(can_have_local_instance(scx.tcx(), def_id)); + let box_free_fn_trans_item = create_fn_trans_item(scx, - exchange_free_fn_def_id, - fn_substs, + def_id, + scx.tcx().mk_substs(iter::once(Kind::from(content_type))), scx.tcx().intern_substs(&[])); - output.push(exchange_free_fn_trans_item); + output.push(box_free_fn_trans_item); } // If the type implements Drop, also add a translation item for the diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 7549f80f94db8..3989dae553ffc 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -13,13 +13,15 @@ // Code relating to drop glue. use std; +use std::iter; use llvm; use llvm::{ValueRef, get_param}; -use middle::lang_items::ExchangeFreeFnLangItem; +use middle::lang_items::BoxFreeFnLangItem; use rustc::ty::subst::{Substs}; use rustc::traits; use rustc::ty::{self, AdtKind, Ty, TypeFoldable}; +use rustc::ty::subst::Kind; use adt::{self, MaybeSizedValue}; use base::*; use callee::Callee; @@ -36,38 +38,22 @@ use cleanup::CleanupScope; use syntax_pos::DUMMY_SP; -pub fn trans_exchange_free_dyn<'a, 'tcx>( +pub fn trans_exchange_free_ty<'a, 'tcx>( bcx: &BlockAndBuilder<'a, 'tcx>, - v: ValueRef, - size: ValueRef, - align: ValueRef + ptr: MaybeSizedValue, + content_ty: Ty<'tcx> ) { - let def_id = langcall(bcx.tcx(), None, "", ExchangeFreeFnLangItem); - let args = [bcx.pointercast(v, Type::i8p(bcx.ccx)), size, align]; - let callee = Callee::def(bcx.ccx, def_id, bcx.tcx().intern_substs(&[])); + let def_id = langcall(bcx.tcx(), None, "", BoxFreeFnLangItem); + let substs = bcx.tcx().mk_substs(iter::once(Kind::from(content_ty))); + let callee = Callee::def(bcx.ccx, def_id, substs); - let ccx = bcx.ccx; - let fn_ty = callee.direct_fn_type(ccx, &[]); + let fn_ty = callee.direct_fn_type(bcx.ccx, &[]); - let llret = bcx.call(callee.reify(ccx), &args[..], None); + let llret = bcx.call(callee.reify(bcx.ccx), + &[ptr.value, ptr.meta][..1 + ptr.has_meta() as usize], None); fn_ty.apply_attrs_callsite(llret); } -pub fn trans_exchange_free_ty<'a, 'tcx>( - bcx: &BlockAndBuilder<'a, 'tcx>, ptr: ValueRef, content_ty: Ty<'tcx> -) { - assert!(bcx.ccx.shared().type_is_sized(content_ty)); - let sizing_type = sizing_type_of(bcx.ccx, content_ty); - let content_size = llsize_of_alloc(bcx.ccx, sizing_type); - - // `Box` does not allocate. - if content_size != 0 { - let content_align = align_of(bcx.ccx, content_ty); - let ccx = bcx.ccx; - trans_exchange_free_dyn(bcx, ptr, C_uint(ccx, content_size), C_uint(ccx, content_align)); - } -} - pub fn get_drop_glue_type<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Ty<'tcx> { assert!(t.is_normalized_for_trans()); @@ -224,30 +210,16 @@ pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKi // special. It may move to library and have Drop impl. As // a safe-guard, assert TyBox not used with TyContents. assert!(!skip_dtor); - if !bcx.ccx.shared().type_is_sized(content_ty) { + let ptr = if !bcx.ccx.shared().type_is_sized(content_ty) { let llbox = bcx.load(get_dataptr(&bcx, ptr.value)); let info = bcx.load(get_meta(&bcx, ptr.value)); - drop_ty(&bcx, MaybeSizedValue::unsized_(llbox, info), content_ty); - let (llsize, llalign) = size_and_align_of_dst(&bcx, content_ty, info); - - // `Box` does not allocate. - let needs_free = bcx.icmp(llvm::IntNE, llsize, C_uint(bcx.ccx, 0u64)); - if const_to_opt_uint(needs_free) == Some(0) { - bcx - } else { - let next_cx = bcx.fcx().build_new_block("next"); - let cond_cx = bcx.fcx().build_new_block("cond"); - bcx.cond_br(needs_free, cond_cx.llbb(), next_cx.llbb()); - trans_exchange_free_dyn(&cond_cx, llbox, llsize, llalign); - cond_cx.br(next_cx.llbb()); - next_cx - } + MaybeSizedValue::unsized_(llbox, info) } else { - let llbox = bcx.load(ptr.value); - drop_ty(&bcx, MaybeSizedValue::sized(llbox), content_ty); - trans_exchange_free_ty(&bcx, llbox, content_ty); - bcx - } + MaybeSizedValue::sized(bcx.load(ptr.value)) + }; + drop_ty(&bcx, ptr, content_ty); + trans_exchange_free_ty(&bcx, ptr, content_ty); + bcx } ty::TyDynamic(..) => { // No support in vtable for distinguishing destroying with