about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-02-27 19:28:21 +0100
committerMichael Woerister <michaelwoerister@posteo>2018-03-06 09:58:47 +0100
commit8bc005c8bb26f8d84066a096780c765ba431d721 (patch)
treee580f9a7fb68df63feaa78bf83ac09cabf634e6a
parentaec6c85b0c6281d938bdd80e98fa9473d8b27780 (diff)
downloadrust-8bc005c8bb26f8d84066a096780c765ba431d721.tar.gz
rust-8bc005c8bb26f8d84066a096780c765ba431d721.zip
Don't recompute SymbolExportLevel for upstream crates.
-rw-r--r--src/librustc/middle/exported_symbols.rs4
-rw-r--r--src/librustc/ty/context.rs8
-rw-r--r--src/librustc_metadata/cstore_impl.rs32
-rw-r--r--src/librustc_metadata/decoder.rs7
-rw-r--r--src/librustc_metadata/encoder.rs28
-rw-r--r--src/librustc_metadata/schema.rs4
-rw-r--r--src/librustc_trans/back/symbol_export.rs98
7 files changed, 91 insertions, 90 deletions
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
index c9b3acdd836..fb971dd2515 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc/middle/exported_symbols.rs
@@ -17,7 +17,7 @@ use ty;
 /// kind of crate, including cdylibs which export very few things.
 /// `Rust` will only be exported if the crate produced is a Rust
 /// dylib.
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
 pub enum SymbolExportLevel {
     C,
     Rust,
@@ -39,7 +39,7 @@ impl SymbolExportLevel {
     }
 }
 
-#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+#[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
 pub enum ExportedSymbol {
     NonGeneric(DefId),
     NoDefId(ty::SymbolName),
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index aac6b3dc08a..47a3580e867 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2460,4 +2460,12 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(tcx.sess.features_untracked().clone())
     };
+    providers.is_panic_runtime = |tcx, cnum| {
+        assert_eq!(cnum, LOCAL_CRATE);
+        attr::contains_name(tcx.hir.krate_attrs(), "panic_runtime")
+    };
+    providers.is_compiler_builtins = |tcx, cnum| {
+        assert_eq!(cnum, LOCAL_CRATE);
+        attr::contains_name(tcx.hir.krate_attrs(), "compiler_builtins")
+    };
 }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 00862816d57..0a2270571f3 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -18,6 +18,7 @@ use rustc::ty::maps::QueryConfig;
 use rustc::middle::cstore::{CrateStore, DepKind,
                             MetadataLoader, LinkMeta,
                             LoadedMacro, EncodedMetadata, NativeLibraryKind};
+use rustc::middle::exported_symbols::ExportedSymbol;
 use rustc::middle::stability::DeprecationEntry;
 use rustc::hir::def;
 use rustc::session::{CrateDisambiguator, Session};
@@ -31,6 +32,7 @@ use rustc::util::nodemap::DefIdMap;
 
 use std::any::Any;
 use rustc_data_structures::sync::Lrc;
+use std::sync::Arc;
 
 use syntax::ast;
 use syntax::attr;
@@ -176,7 +178,21 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     extern_crate => { Lrc::new(cdata.extern_crate.get()) }
     is_no_builtins => { cdata.is_no_builtins(tcx.sess) }
     impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
-    reachable_non_generics => { Lrc::new(cdata.reachable_non_generics()) }
+    reachable_non_generics => {
+        let reachable_non_generics = tcx
+            .exported_symbols(cdata.cnum)
+            .iter()
+            .filter_map(|&(exported_symbol, _)| {
+                if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
+                    return Some(def_id)
+                } else {
+                    None
+                }
+            })
+            .collect();
+
+        Lrc::new(reachable_non_generics)
+    }
     native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
     plugin_registrar_fn => {
         cdata.root.plugin_registrar_fn.map(|index| {
@@ -235,6 +251,20 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     has_copy_closures => { cdata.has_copy_closures(tcx.sess) }
     has_clone_closures => { cdata.has_clone_closures(tcx.sess) }
+
+    exported_symbols => {
+        let cnum = cdata.cnum;
+        assert!(cnum != LOCAL_CRATE);
+
+        // If this crate is a plugin and/or a custom derive crate, then
+        // we're not even going to link those in so we skip those crates.
+        if cdata.root.plugin_registrar_fn.is_some() ||
+           cdata.root.macro_derive_registrar.is_some() {
+            return Arc::new(Vec::new())
+        }
+
+        Arc::new(cdata.exported_symbols())
+    }
 }
 
 pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 2831b63bbac..60a0d4e03b5 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -18,6 +18,7 @@ use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::hir;
 use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
                             ExternBodyNestedBodies};
+use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
                          CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -27,7 +28,6 @@ use rustc::mir;
 use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::codec::TyDecoder;
-use rustc::util::nodemap::DefIdSet;
 use rustc::mir::Mir;
 
 use std::cell::Ref;
@@ -1006,11 +1006,10 @@ impl<'a, 'tcx> CrateMetadata {
         arg_names.decode(self).collect()
     }
 
-    pub fn reachable_non_generics(&self) -> DefIdSet {
+    pub fn exported_symbols(&self) -> Vec<(ExportedSymbol, SymbolExportLevel)> {
         self.root
-            .reachable_non_generics
+            .exported_symbols
             .decode(self)
-            .map(|index| self.local_def_id(index))
             .collect()
     }
 
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index c649cf62dc5..1c54b7aa133 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -20,6 +20,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::ich::Fingerprint;
 use rustc::middle::dependency_format::Linkage;
+use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::traits::specialization_graph;
@@ -27,7 +28,7 @@ use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
 use rustc::ty::codec::{self as ty_codec, TyEncoder};
 
 use rustc::session::config::{self, CrateTypeProcMacro};
-use rustc::util::nodemap::{FxHashMap, DefIdSet};
+use rustc::util::nodemap::FxHashMap;
 
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
@@ -394,11 +395,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         // Encode exported symbols info.
         i = self.position();
-        let reachable_non_generics = self.tcx.reachable_non_generics(LOCAL_CRATE);
-        let reachable_non_generics = self.tracked(
-            IsolatedEncoder::encode_reachable_non_generics,
-            &reachable_non_generics);
-        let reachable_non_generics_bytes = self.position() - i;
+        let exported_symbols = self.tcx.exported_symbols(LOCAL_CRATE);
+        let exported_symbols = self.tracked(
+            IsolatedEncoder::encode_exported_symbols,
+            &exported_symbols);
+        let exported_symbols_bytes = self.position() - i;
 
         // Encode and index the items.
         i = self.position();
@@ -442,7 +443,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             codemap,
             def_path_table,
             impls,
-            reachable_non_generics,
+            exported_symbols,
             index,
         });
 
@@ -462,7 +463,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             println!("          native bytes: {}", native_lib_bytes);
             println!("         codemap bytes: {}", codemap_bytes);
             println!("            impl bytes: {}", impl_bytes);
-            println!("    exp. symbols bytes: {}", reachable_non_generics_bytes);
+            println!("    exp. symbols bytes: {}", exported_symbols_bytes);
             println!("  def-path table bytes: {}", def_path_table_bytes);
             println!("            item bytes: {}", item_bytes);
             println!("           index bytes: {}", index_bytes);
@@ -1388,13 +1389,10 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
     // middle::reachable module but filters out items that either don't have a
     // symbol associated with them (they weren't translated) or if they're an FFI
     // definition (as that's not defined in this crate).
-    fn encode_reachable_non_generics(&mut self,
-                                     reachable_non_generics: &DefIdSet)
-                                     -> LazySeq<DefIndex> {
-        self.lazy_seq(reachable_non_generics.iter().map(|def_id| {
-            debug_assert!(def_id.is_local());
-            def_id.index
-        }))
+    fn encode_exported_symbols(&mut self,
+                               exported_symbols: &[(ExportedSymbol, SymbolExportLevel)])
+                               -> LazySeq<(ExportedSymbol, SymbolExportLevel)> {
+        self.lazy_seq(exported_symbols.iter().cloned())
     }
 
     fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq<Option<LinkagePreference>> {
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 3e7d31513a2..ce94e4f912f 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -16,6 +16,7 @@ use rustc::hir::def::{self, CtorKind};
 use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
 use rustc::ich::StableHashingContext;
 use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
+use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::session::CrateDisambiguator;
@@ -202,7 +203,8 @@ pub struct CrateRoot {
     pub codemap: LazySeq<syntax_pos::FileMap>,
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: LazySeq<TraitImpls>,
-    pub reachable_non_generics: LazySeq<DefIndex>,
+    pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>,
+
     pub index: LazySeq<index::Index>,
 }
 
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 4e3a3710488..0873c1632f5 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -78,10 +78,9 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let reachable_non_generics = tcx
         .exported_symbols(LOCAL_CRATE)
         .iter()
-        .filter_map(|&(exported_symbol, _)| {
+        .filter_map(|&(exported_symbol, level)| {
             if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
-                if tcx.symbol_export_level(def_id)
-                      .is_below_threshold(export_threshold) {
+                if level.is_below_threshold(export_threshold) {
                     return Some(def_id)
                 }
             }
@@ -110,6 +109,16 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         return Arc::new(vec![])
     }
 
+    // Check to see if this crate is a "special runtime crate". These
+    // crates, implementation details of the standard library, typically
+    // have a bunch of `pub extern` and `#[no_mangle]` functions as the
+    // ABI between them. We don't want their symbols to have a `C`
+    // export level, however, as they're just implementation details.
+    // Down below we'll hardwire all of the symbols to the `Rust` export
+    // level instead.
+    let special_runtime_crate = tcx.is_panic_runtime(LOCAL_CRATE) ||
+        tcx.is_compiler_builtins(LOCAL_CRATE);
+
     let mut reachable_non_generics: DefIdSet = tcx.reachable_set(LOCAL_CRATE).0
         .iter()
         .filter_map(|&node_id| {
@@ -176,7 +185,25 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut symbols: Vec<_> = reachable_non_generics
         .iter()
         .map(|&def_id| {
-            let export_level = tcx.symbol_export_level(def_id);
+            let export_level = if special_runtime_crate {
+                let name = tcx.symbol_name(Instance::mono(tcx, def_id));
+                // We can probably do better here by just ensuring that
+                // it has hidden visibility rather than public
+                // visibility, as this is primarily here to ensure it's
+                // not stripped during LTO.
+                //
+                // In general though we won't link right if these
+                // symbols are stripped, and LTO currently strips them.
+                if &*name == "rust_eh_personality" ||
+                   &*name == "rust_eh_register_frames" ||
+                   &*name == "rust_eh_unregister_frames" {
+                    SymbolExportLevel::C
+                } else {
+                    SymbolExportLevel::Rust
+                }
+            } else {
+                tcx.symbol_export_level(def_id)
+            };
             debug!("EXPORTED SYMBOL (local): {} ({:?})",
                    tcx.symbol_name(Instance::mono(tcx, def_id)),
                    export_level);
@@ -222,70 +249,7 @@ pub fn provide(providers: &mut Providers) {
     providers.symbol_export_level = symbol_export_level_provider;
 }
 
-fn exported_symbols_provider_extern<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                              cnum: CrateNum)
-                                              -> Arc<Vec<(ExportedSymbol,
-                                                          SymbolExportLevel)>>
-{
-    // If this crate is a plugin and/or a custom derive crate, then
-    // we're not even going to link those in so we skip those crates.
-    if tcx.plugin_registrar_fn(cnum).is_some() ||
-       tcx.derive_registrar_fn(cnum).is_some() {
-        return Arc::new(Vec::new())
-    }
-
-    // Check to see if this crate is a "special runtime crate". These
-    // crates, implementation details of the standard library, typically
-    // have a bunch of `pub extern` and `#[no_mangle]` functions as the
-    // ABI between them. We don't want their symbols to have a `C`
-    // export level, however, as they're just implementation details.
-    // Down below we'll hardwire all of the symbols to the `Rust` export
-    // level instead.
-    let special_runtime_crate =
-        tcx.is_panic_runtime(cnum) || tcx.is_compiler_builtins(cnum);
-
-    let mut crate_exports: Vec<_> = tcx
-        .reachable_non_generics(cnum)
-        .iter()
-        .map(|&def_id| {
-            let export_level = if special_runtime_crate {
-                let name = tcx.symbol_name(Instance::mono(tcx, def_id));
-                // We can probably do better here by just ensuring that
-                // it has hidden visibility rather than public
-                // visibility, as this is primarily here to ensure it's
-                // not stripped during LTO.
-                //
-                // In general though we won't link right if these
-                // symbols are stripped, and LTO currently strips them.
-                if &*name == "rust_eh_personality" ||
-                   &*name == "rust_eh_register_frames" ||
-                   &*name == "rust_eh_unregister_frames" {
-                    SymbolExportLevel::C
-                } else {
-                    SymbolExportLevel::Rust
-                }
-            } else {
-                tcx.symbol_export_level(def_id)
-            };
-
-            debug!("EXPORTED SYMBOL (re-export): {} ({:?})",
-                   tcx.symbol_name(Instance::mono(tcx, def_id)),
-                   export_level);
-
-            (ExportedSymbol::NonGeneric(def_id), export_level)
-        })
-        .collect();
-
-    // Sort so we get a stable incr. comp. hash.
-    crate_exports.sort_unstable_by(|&(ref symbol1, ..), &(ref symbol2, ..)| {
-        symbol1.compare_stable(tcx, symbol2)
-    });
-
-    Arc::new(crate_exports)
-}
-
 pub fn provide_extern(providers: &mut Providers) {
-    providers.exported_symbols = exported_symbols_provider_extern;
     providers.is_reachable_non_generic = is_reachable_non_generic_provider;
     providers.symbol_export_level = symbol_export_level_provider;
 }