X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_codegen_ssa%2Fback%2Fsymbol_export.rs;h=7e888a271e316e5f0134967b2d61ccf16fcbccad;hb=2ceb92bc53a849e36341c3fd619cb49470e224e2;hp=a406b5f103b9d2f85f73109b6bb4cb33e7625699;hpb=8de73bc10c4bba39b4e5f898e17981b81e3b9443;p=rust.git diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index a406b5f103b..7e888a271e3 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -3,11 +3,12 @@ use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc::middle::exported_symbols::{metadata_symbol_name, ExportedSymbol, SymbolExportLevel}; -use rustc::session::config; +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; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; @@ -16,8 +17,6 @@ use rustc_index::vec::IndexVec; use syntax::expand::allocator::ALLOCATOR_METHODS; -pub type ExportedSymbols = FxHashMap>>; - pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(&tcx.sess.crate_types.borrow()) } @@ -95,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 { @@ -205,6 +204,16 @@ fn exported_symbols_provider_local( })); } + if let Some(Sanitizer::Memory) = tcx.sess.opts.debugging_opts.sanitizer { + // Similar to profiling, preserve weak msan symbol during LTO. + const MSAN_WEAK_SYMBOLS: [&str; 2] = ["__msan_track_origins", "__msan_keep_going"]; + + symbols.extend(MSAN_WEAK_SYMBOLS.iter().map(|sym| { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym)); + (exported_symbol, SymbolExportLevel::C) + })); + } + if tcx.sess.crate_types.borrow().contains(&config::CrateType::Dylib) { let symbol_name = metadata_symbol_name(tcx); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name)); @@ -239,19 +248,31 @@ 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(def_id, Some(ty)), substs }) => { + // A little sanity-check + debug_assert_eq!( + substs.non_erasable_generics().next(), + Some(GenericArgKind::Type(ty)) + ); + let symbol = ExportedSymbol::Generic(def_id, substs); + symbols.push((symbol, 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) } @@ -358,3 +379,32 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel SymbolExportLevel::Rust } } + +/// This is the symbol name of the given instance instantiated in a specific crate. +pub fn symbol_name_for_instance_in_crate<'tcx>( + tcx: TyCtxt<'tcx>, + symbol: ExportedSymbol<'tcx>, + instantiating_crate: CrateNum, +) -> String { + // If this is something instantiated in the local crate then we might + // already have cached the name as a query result. + if instantiating_crate == LOCAL_CRATE { + return symbol.symbol_name_for_local_instance(tcx).to_string(); + } + + // This is something instantiated in an upstream crate, so we have to use + // the slower (because uncached) version of computing the symbol name. + match symbol { + ExportedSymbol::NonGeneric(def_id) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::mono(tcx, def_id), + instantiating_crate, + ), + ExportedSymbol::Generic(def_id, substs) => symbol_names::symbol_name_for_instance_in_crate( + tcx, + Instance::new(def_id, substs), + instantiating_crate, + ), + ExportedSymbol::NoDefId(symbol_name) => symbol_name.to_string(), + } +}