about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIsaac Whitfield <iw@whitfin.io>2018-05-09 18:00:18 -0700
committerIsaac Whitfield <iw@whitfin.io>2018-05-18 09:37:13 -0700
commit466fc6815d23dc201e26aa3210f3476443805e80 (patch)
treeba04719a0c6bea5949f253f8a88ad7fbf73a6552
parentf418f1dd7889a5896df43ce1ef5be0eb57bf341c (diff)
downloadrust-466fc6815d23dc201e26aa3210f3476443805e80.tar.gz
rust-466fc6815d23dc201e26aa3210f3476443805e80.zip
Avoid generating attributes more than once for CrateMetadata
-rw-r--r--src/librustc_metadata/creader.rs29
-rw-r--r--src/librustc_metadata/cstore.rs50
-rw-r--r--src/librustc_metadata/cstore_impl.rs10
3 files changed, 49 insertions, 40 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 4197d34c0e8..796048b58d1 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -214,7 +214,6 @@ impl<'a> CrateLoader<'a> {
         let root = if root.is_some() { root } else { &crate_paths };
 
         let Library { dylib, rlib, rmeta, metadata } = lib;
-
         let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
 
         let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
@@ -229,7 +228,7 @@ impl<'a> CrateLoader<'a> {
             .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
             .collect();
 
-        let cmeta = cstore::CrateMetadata {
+        let mut cmeta = cstore::CrateMetadata {
             name,
             extern_crate: Lock::new(None),
             def_path_table: Lrc::new(def_path_table),
@@ -249,8 +248,17 @@ impl<'a> CrateLoader<'a> {
                 rlib,
                 rmeta,
             },
+            compiler_builtins: None,
+            needs_allocator: None,
+            needs_panic_runtime: None,
+            no_builtins: None,
+            panic_runtime: None,
+            profiler_runtime: None,
+            sanitizer_runtime: None,
         };
 
+        cmeta.derive_attributes(self.sess);
+
         let cmeta = Lrc::new(cmeta);
         self.cstore.set_crate_data(cnum, cmeta.clone());
         (cnum, cmeta)
@@ -641,15 +649,14 @@ impl<'a> CrateLoader<'a> {
         let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
                                                           "needs_panic_runtime");
 
-        let sess = self.sess;
         self.cstore.iter_crate_data(|cnum, data| {
             needs_panic_runtime = needs_panic_runtime ||
-                                  data.needs_panic_runtime(sess);
-            if data.is_panic_runtime(sess) {
+                                  data.needs_panic_runtime();
+            if data.is_panic_runtime() {
                 // Inject a dependency from all #![needs_panic_runtime] to this
                 // #![panic_runtime] crate.
                 self.inject_dependency_if(cnum, "a panic runtime",
-                                          &|data| data.needs_panic_runtime(sess));
+                                          &|data| data.needs_panic_runtime());
                 runtime_found = runtime_found || *data.dep_kind.lock() == DepKind::Explicit;
             }
         });
@@ -686,7 +693,7 @@ impl<'a> CrateLoader<'a> {
 
         // Sanity check the loaded crate to ensure it is indeed a panic runtime
         // and the panic strategy is indeed what we thought it was.
-        if !data.is_panic_runtime(self.sess) {
+        if !data.is_panic_runtime() {
             self.sess.err(&format!("the crate `{}` is not a panic runtime",
                                    name));
         }
@@ -698,7 +705,7 @@ impl<'a> CrateLoader<'a> {
 
         self.sess.injected_panic_runtime.set(Some(cnum));
         self.inject_dependency_if(cnum, "a panic runtime",
-                                  &|data| data.needs_panic_runtime(self.sess));
+                                  &|data| data.needs_panic_runtime());
     }
 
     fn inject_sanitizer_runtime(&mut self) {
@@ -793,7 +800,7 @@ impl<'a> CrateLoader<'a> {
                                        PathKind::Crate, dep_kind);
 
                 // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
-                if !data.is_sanitizer_runtime(self.sess) {
+                if !data.is_sanitizer_runtime() {
                     self.sess.err(&format!("the crate `{}` is not a sanitizer runtime",
                                            name));
                 }
@@ -816,7 +823,7 @@ impl<'a> CrateLoader<'a> {
                                    PathKind::Crate, dep_kind);
 
             // Sanity check the loaded crate to ensure it is indeed a profiler runtime
-            if !data.is_profiler_runtime(self.sess) {
+            if !data.is_profiler_runtime() {
                 self.sess.err(&format!("the crate `profiler_builtins` is not \
                                         a profiler runtime"));
             }
@@ -833,7 +840,7 @@ impl<'a> CrateLoader<'a> {
         let mut needs_allocator = attr::contains_name(&krate.attrs,
                                                       "needs_allocator");
         self.cstore.iter_crate_data(|_, data| {
-            needs_allocator = needs_allocator || data.needs_allocator(self.sess);
+            needs_allocator = needs_allocator || data.needs_allocator();
         });
         if !needs_allocator {
             self.sess.injected_allocator.set(None);
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 97f0a01c00c..4650c64543f 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -17,7 +17,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
-use rustc::session::{Session, CrateDisambiguator};
+use rustc::session::{CrateDisambiguator, Session};
 use rustc_target::spec::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::util::nodemap::{FxHashMap, NodeMap};
@@ -85,6 +85,15 @@ pub struct CrateMetadata {
     pub source: CrateSource,
 
     pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
+
+    // Booleans derived from attributes
+    pub compiler_builtins: Option<bool>,
+    pub needs_allocator: Option<bool>,
+    pub needs_panic_runtime: Option<bool>,
+    pub no_builtins: Option<bool>,
+    pub panic_runtime: Option<bool>,
+    pub profiler_runtime: Option<bool>,
+    pub sanitizer_runtime: Option<bool>,
 }
 
 pub struct CStore {
@@ -188,47 +197,40 @@ impl CrateMetadata {
         self.root.disambiguator
     }
 
-    pub fn needs_allocator(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "needs_allocator")
+    pub fn needs_allocator(&self) -> bool {
+        self.needs_allocator.unwrap_or(false)
     }
 
     pub fn has_global_allocator(&self) -> bool {
-        self.root.has_global_allocator.clone()
+        self.root.has_global_allocator
     }
 
     pub fn has_default_lib_allocator(&self) -> bool {
-        self.root.has_default_lib_allocator.clone()
+        self.root.has_default_lib_allocator
     }
 
-    pub fn is_panic_runtime(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "panic_runtime")
+    pub fn is_panic_runtime(&self) -> bool {
+        self.panic_runtime.unwrap_or(false)
     }
 
-    pub fn needs_panic_runtime(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "needs_panic_runtime")
+    pub fn needs_panic_runtime(&self) -> bool {
+        self.needs_panic_runtime.unwrap_or(false)
     }
 
-    pub fn is_compiler_builtins(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "compiler_builtins")
+    pub fn is_compiler_builtins(&self) -> bool {
+        self.compiler_builtins.unwrap_or(false)
     }
 
-    pub fn is_sanitizer_runtime(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "sanitizer_runtime")
+    pub fn is_sanitizer_runtime(&self) -> bool {
+        self.sanitizer_runtime.unwrap_or(false)
     }
 
-    pub fn is_profiler_runtime(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "profiler_runtime")
+    pub fn is_profiler_runtime(&self) -> bool {
+        self.profiler_runtime.unwrap_or(false)
     }
 
-    pub fn is_no_builtins(&self, sess: &Session) -> bool {
-        let attrs = self.get_item_attrs(CRATE_DEF_INDEX, sess);
-        attr::contains_name(&attrs, "no_builtins")
+    pub fn is_no_builtins(&self) -> bool {
+        self.no_builtins.unwrap_or(false)
     }
 
     pub fn panic_strategy(&self) -> PanicStrategy {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index c8f25f935e9..6bb6b1a1747 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -170,17 +170,17 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
 
     dylib_dependency_formats => { Lrc::new(cdata.get_dylib_dependency_formats()) }
-    is_panic_runtime => { cdata.is_panic_runtime(tcx.sess) }
-    is_compiler_builtins => { cdata.is_compiler_builtins(tcx.sess) }
+    is_panic_runtime => { cdata.is_panic_runtime() }
+    is_compiler_builtins => { cdata.is_compiler_builtins() }
     has_global_allocator => { cdata.has_global_allocator() }
-    is_sanitizer_runtime => { cdata.is_sanitizer_runtime(tcx.sess) }
-    is_profiler_runtime => { cdata.is_profiler_runtime(tcx.sess) }
+    is_sanitizer_runtime => { cdata.is_sanitizer_runtime() }
+    is_profiler_runtime => { cdata.is_profiler_runtime() }
     panic_strategy => { cdata.panic_strategy() }
     extern_crate => {
         let r = Lrc::new(*cdata.extern_crate.lock());
         r
     }
-    is_no_builtins => { cdata.is_no_builtins(tcx.sess) }
+    is_no_builtins => { cdata.is_no_builtins() }
     impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
     reachable_non_generics => {
         let reachable_non_generics = tcx