diff options
Diffstat (limited to 'src/librustc_codegen_ssa')
| -rw-r--r-- | src/librustc_codegen_ssa/back/symbol_export.rs | 89 | ||||
| -rw-r--r-- | src/librustc_codegen_ssa/back/write.rs | 6 |
2 files changed, 71 insertions, 24 deletions
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index d680e14bbbd..a6cd0c09684 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -5,7 +5,7 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; use rustc::session::config::{self, Sanitizer}; use rustc::ty::query::Providers; -use rustc::ty::subst::SubstsRef; +use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::Instance; use rustc::ty::{SymbolName, TyCtxt}; use rustc_codegen_utils::symbol_names; @@ -17,8 +17,6 @@ use rustc_hir::Node; use rustc_index::vec::IndexVec; use syntax::expand::allocator::ALLOCATOR_METHODS; -pub type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportLevel)>>>; - pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(&tcx.sess.crate_types.borrow()) } @@ -96,7 +94,7 @@ fn reachable_non_generics_provider( if !generics.requires_monomorphization(tcx) && // Functions marked with #[inline] are only ever codegened // with "internal" linkage and are never exported. - !Instance::mono(tcx, def_id).def.requires_local(tcx) + !Instance::mono(tcx, def_id).def.generates_cgu_internal_copy(tcx) { Some(def_id) } else { @@ -250,19 +248,30 @@ fn exported_symbols_provider_local( continue; } - if let &MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) = mono_item { - if substs.non_erasable_generics().next().is_some() { - symbols - .push((ExportedSymbol::Generic(def_id, substs), SymbolExportLevel::Rust)); + match *mono_item { + MonoItem::Fn(Instance { def: InstanceDef::Item(def_id), substs }) => { + if substs.non_erasable_generics().next().is_some() { + let symbol = ExportedSymbol::Generic(def_id, substs); + symbols.push((symbol, SymbolExportLevel::Rust)); + } + } + MonoItem::Fn(Instance { def: InstanceDef::DropGlue(_, Some(ty)), substs }) => { + // A little sanity-check + debug_assert_eq!( + substs.non_erasable_generics().next(), + Some(GenericArgKind::Type(ty)) + ); + symbols.push((ExportedSymbol::DropGlue(ty), SymbolExportLevel::Rust)); + } + _ => { + // Any other symbols don't qualify for sharing } } } } // Sort so we get a stable incr. comp. hash. - symbols.sort_unstable_by(|&(ref symbol1, ..), &(ref symbol2, ..)| { - symbol1.compare_stable(tcx, symbol2) - }); + symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx)); Arc::new(symbols) } @@ -288,24 +297,41 @@ fn upstream_monomorphizations_provider( cnum_stable_ids }; + let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn(); + for &cnum in cnums.iter() { for (exported_symbol, _) in tcx.exported_symbols(cnum).iter() { - if let &ExportedSymbol::Generic(def_id, substs) = exported_symbol { - let substs_map = instances.entry(def_id).or_default(); - - match substs_map.entry(substs) { - Occupied(mut e) => { - // If there are multiple monomorphizations available, - // we select one deterministically. - let other_cnum = *e.get(); - if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { - e.insert(cnum); - } + let (def_id, substs) = match *exported_symbol { + ExportedSymbol::Generic(def_id, substs) => (def_id, substs), + ExportedSymbol::DropGlue(ty) => { + if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id { + (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()])) + } else { + // `drop_in_place` in place does not exist, don't try + // to use it. + continue; } - Vacant(e) => { + } + ExportedSymbol::NonGeneric(..) | ExportedSymbol::NoDefId(..) => { + // These are no monomorphizations + continue; + } + }; + + let substs_map = instances.entry(def_id).or_default(); + + match substs_map.entry(substs) { + Occupied(mut e) => { + // If there are multiple monomorphizations available, + // we select one deterministically. + let other_cnum = *e.get(); + if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] { e.insert(cnum); } } + Vacant(e) => { + e.insert(cnum); + } } } } @@ -321,6 +347,17 @@ fn upstream_monomorphizations_for_provider( tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id) } +fn upstream_drop_glue_for_provider<'tcx>( + tcx: TyCtxt<'tcx>, + substs: SubstsRef<'tcx>, +) -> Option<CrateNum> { + if let Some(def_id) = tcx.lang_items().drop_in_place_fn() { + tcx.upstream_monomorphizations_for(def_id).and_then(|monos| monos.get(&substs).cloned()) + } else { + None + } +} + fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: DefId) -> bool { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { !tcx.reachable_set(LOCAL_CRATE).contains(&hir_id) @@ -335,6 +372,7 @@ pub fn provide(providers: &mut Providers<'_>) { providers.exported_symbols = exported_symbols_provider_local; providers.upstream_monomorphizations = upstream_monomorphizations_provider; providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; + providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; } pub fn provide_extern(providers: &mut Providers<'_>) { @@ -395,6 +433,11 @@ pub fn symbol_name_for_instance_in_crate<'tcx>( Instance::new(def_id, substs), instantiating_crate, ), + ExportedSymbol::DropGlue(ty) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::resolve_drop_in_place(tcx, ty), + instantiating_crate, + ), ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), } } diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 049faff7c49..841827d15fe 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -2,7 +2,8 @@ use super::command::Command; use super::link::{self, get_linker, remove}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; -use super::symbol_export::{symbol_name_for_instance_in_crate, ExportedSymbols}; +use super::symbol_export::symbol_name_for_instance_in_crate; + use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION, @@ -12,6 +13,7 @@ use crate::traits::*; use jobserver::{Acquired, Client}; use rustc::dep_graph::{WorkProduct, WorkProductFileKind, WorkProductId}; use rustc::middle::cstore::EncodedMetadata; +use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{ self, Lto, OutputFilenames, OutputType, Passes, Sanitizer, SwitchWithOptPath, }; @@ -205,6 +207,8 @@ impl<B: WriteBackendMethods> Clone for TargetMachineFactory<B> { } } +pub type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportLevel)>>>; + /// Additional resources used by optimize_and_codegen (not module specific) #[derive(Clone)] pub struct CodegenContext<B: WriteBackendMethods> { |
