]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Never register syntax crates in CStore
authorAlex Crichton <alex@alexcrichton.com>
Mon, 7 Apr 2014 19:16:43 +0000 (12:16 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 8 Apr 2014 07:03:11 +0000 (00:03 -0700)
When linking, all crates in the local CStore are used to link the final product.
With #[phase(syntax)], crates want to be omitted from this linkage phase, and
this was achieved by dumping the entire CStore after loading crates. This causes
crates like the standard library to get loaded twice. This loading process is a
fairly expensive operation when dealing with decompressing metadata.

This commit alters the loading process to never register syntax crates in
CStore. Instead, only phase(link) crates ever make their way into the map of
crates. The CrateLoader trait was altered to return everything in one method
instead of having separate methods for finding information.

src/librustc/driver/driver.rs
src/librustc/metadata/creader.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs

index 0668abea2b12f1c1e7dfd4bbf24af1410ee8114a..8a593d5f92a2add5a7ba6a3bae490598f8b76be6 100644 (file)
@@ -241,8 +241,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
                                           cfg,
                                           krate)
     });
-    // dump the syntax-time crates
-    sess.cstore.reset();
 
     // strip again, in case expansion added anything with a #[cfg].
     krate = time(time_passes, "configuration 2", krate, |krate|
index 9c0c73288eb0d007059d1ceaf6d4e69c9922cb33..50c22f6bf1bba6985bb1ec82e0f7ecff32bd08c8 100644 (file)
@@ -114,22 +114,25 @@ fn visit_crate(e: &Env, c: &ast::Crate) {
     }
 }
 
-fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
-    let should_load = i.attrs.iter().all(|attr| {
+fn should_link(i: &ast::ViewItem) -> bool {
+    i.attrs.iter().all(|attr| {
         attr.name().get() != "phase" ||
             attr.meta_item_list().map_or(false, |phases| {
                 attr::contains_name(phases.as_slice(), "link")
             })
-    });
+    })
+}
 
-    if !should_load {
+fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
+    if !should_link(i) {
         return;
     }
 
     match extract_crate_info(e, i) {
         Some(info) => {
-            let cnum = resolve_crate(e, &None, info.ident, &info.crate_id, None,
-                                     i.span);
+            let (cnum, _, _) = resolve_crate(e, &None, info.ident,
+                                             &info.crate_id, None, true,
+                                             i.span);
             e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
         }
         None => ()
@@ -140,6 +143,7 @@ struct CrateInfo {
     ident: ~str,
     crate_id: CrateId,
     id: ast::NodeId,
+    should_link: bool,
 }
 
 fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
@@ -165,6 +169,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
                 ident: ident.get().to_str(),
                 crate_id: crate_id,
                 id: id,
+                should_link: should_link(i),
             })
         }
         _ => None
@@ -274,8 +279,10 @@ fn resolve_crate<'a>(e: &mut Env,
                      ident: &str,
                      crate_id: &CrateId,
                      hash: Option<&Svh>,
+                     should_link: bool,
                      span: Span)
-                     -> ast::CrateNum {
+                     -> (ast::CrateNum, @cstore::crate_metadata,
+                         cstore::CrateSource) {
     match existing_match(e, crate_id, hash) {
         None => {
             let id_hash = link::crate_id_hash(crate_id);
@@ -312,8 +319,11 @@ fn resolve_crate<'a>(e: &mut Env,
             let root = if root.is_some() { root } else { &crate_paths };
 
             // Now resolve the crates referenced by this crate
-            let cnum_map = resolve_crate_deps(e, root, metadata.as_slice(),
-                                              span);
+            let cnum_map = if should_link {
+                resolve_crate_deps(e, root, metadata.as_slice(), span)
+            } else {
+                @RefCell::new(HashMap::new())
+            };
 
             let cmeta = @cstore::crate_metadata {
                 name: load_ctxt.crate_id.name.to_owned(),
@@ -323,15 +333,21 @@ fn resolve_crate<'a>(e: &mut Env,
                 span: span,
             };
 
-            e.sess.cstore.set_crate_data(cnum, cmeta);
-            e.sess.cstore.add_used_crate_source(cstore::CrateSource {
+            let source = cstore::CrateSource {
                 dylib: dylib,
                 rlib: rlib,
                 cnum: cnum,
-            });
-            cnum
+            };
+
+            if should_link {
+                e.sess.cstore.set_crate_data(cnum, cmeta);
+                e.sess.cstore.add_used_crate_source(source.clone());
+            }
+            (cnum, cmeta, source)
         }
-        Some(cnum) => cnum
+        Some(cnum) => (cnum,
+                       e.sess.cstore.get_crate_data(cnum),
+                       e.sess.cstore.get_used_crate_source(cnum).unwrap())
     }
 }
 
@@ -348,11 +364,12 @@ fn resolve_crate_deps(e: &mut Env,
     for dep in r.iter() {
         let extrn_cnum = dep.cnum;
         debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
-        let local_cnum = resolve_crate(e, root,
-                                       dep.crate_id.name.as_slice(),
-                                       &dep.crate_id,
-                                       Some(&dep.hash),
-                                       span);
+        let (local_cnum, _, _) = resolve_crate(e, root,
+                                               dep.crate_id.name.as_slice(),
+                                               &dep.crate_id,
+                                               Some(&dep.hash),
+                                               true,
+                                               span);
         cnum_map.insert(extrn_cnum, local_cnum);
     }
     return @RefCell::new(cnum_map);
@@ -380,23 +397,17 @@ pub fn new(sess: &'a Session) -> Loader<'a> {
 impl<'a> CrateLoader for Loader<'a> {
     fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
         let info = extract_crate_info(&self.env, krate).unwrap();
-        let cnum = resolve_crate(&mut self.env, &None, info.ident,
-                                 &info.crate_id, None, krate.span);
-        let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
+        let (cnum, data, library) = resolve_crate(&mut self.env, &None,
+                                                  info.ident, &info.crate_id,
+                                                  None, true, krate.span);
+        let macros = decoder::get_exported_macros(data);
+        let cstore = &self.env.sess.cstore;
+        let registrar = csearch::get_macro_registrar_fn(cstore, cnum)
+                            .map(|did| csearch::get_symbol(cstore, did));
         MacroCrate {
             lib: library.dylib,
-            cnum: cnum,
+            macros: macros.move_iter().collect(),
+            registrar_symbol: registrar,
         }
     }
-
-    fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> Vec<~str> {
-        csearch::get_exported_macros(&self.env.sess.cstore, cnum).move_iter()
-                                                                 .collect()
-    }
-
-    fn get_registrar_symbol(&mut self, cnum: ast::CrateNum) -> Option<~str> {
-        let cstore = &self.env.sess.cstore;
-        csearch::get_macro_registrar_fn(cstore, cnum)
-            .map(|did| csearch::get_symbol(cstore, did))
-    }
 }
index 7ff779231325197dcdde806e77d277a3f7c4500d..3bf1ed95f380ef1f95df75bca0b9b55c77c8b4aa 100644 (file)
@@ -293,13 +293,12 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
 
 pub struct MacroCrate {
     pub lib: Option<Path>,
-    pub cnum: ast::CrateNum,
+    pub macros: Vec<~str>,
+    pub registrar_symbol: Option<~str>,
 }
 
 pub trait CrateLoader {
     fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate;
-    fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> Vec<~str> ;
-    fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>;
 }
 
 // One of these is made during expansion and incrementally updated as we go;
index 747ab583e792a27333acd5c4da0bf2b49ee120bc..5c3c7d995d67a56b8ab2e2cb3e351dc2e953bacf 100644 (file)
@@ -487,7 +487,8 @@ pub fn expand_view_item(vi: &ast::ViewItem,
 }
 
 fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
-    let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
+    let MacroCrate { lib, macros, registrar_symbol } =
+        fld.cx.ecfg.loader.load_crate(krate);
 
     let crate_name = match krate.node {
         ast::ViewItemExternCrate(name, _, _) => name,
@@ -495,8 +496,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
     };
     let name = format!("<{} macros>", token::get_ident(crate_name));
 
-    let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
-    for source in exported_macros.iter() {
+    for source in macros.iter() {
         let item = parse::parse_item_from_source_str(name.clone(),
                                                      (*source).clone(),
                                                      fld.cx.cfg(),
@@ -512,7 +512,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
     // Make sure the path contains a / or the linker will search for it.
     let path = os::make_absolute(&path);
 
-    let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
+    let registrar = match registrar_symbol {
         Some(registrar) => registrar,
         None => return
     };