Skip to content

Commit 5367c32

Browse files
committed
rustc: Never register syntax crates in CStore
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.
1 parent 31755e2 commit 5367c32

File tree

4 files changed

+51
-43
lines changed

4 files changed

+51
-43
lines changed

src/librustc/driver/driver.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
241241
cfg,
242242
krate)
243243
});
244-
// dump the syntax-time crates
245-
sess.cstore.reset();
246244

247245
// strip again, in case expansion added anything with a #[cfg].
248246
krate = time(time_passes, "configuration 2", krate, |krate|

src/librustc/metadata/creader.rs

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,22 +114,25 @@ fn visit_crate(e: &Env, c: &ast::Crate) {
114114
}
115115
}
116116

117-
fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
118-
let should_load = i.attrs.iter().all(|attr| {
117+
fn should_link(i: &ast::ViewItem) -> bool {
118+
i.attrs.iter().all(|attr| {
119119
attr.name().get() != "phase" ||
120120
attr.meta_item_list().map_or(false, |phases| {
121121
attr::contains_name(phases.as_slice(), "link")
122122
})
123-
});
123+
})
124+
}
124125

125-
if !should_load {
126+
fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
127+
if !should_link(i) {
126128
return;
127129
}
128130

129131
match extract_crate_info(e, i) {
130132
Some(info) => {
131-
let cnum = resolve_crate(e, &None, info.ident, &info.crate_id, None,
132-
i.span);
133+
let (cnum, _, _) = resolve_crate(e, &None, info.ident,
134+
&info.crate_id, None, true,
135+
i.span);
133136
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
134137
}
135138
None => ()
@@ -140,6 +143,7 @@ struct CrateInfo {
140143
ident: ~str,
141144
crate_id: CrateId,
142145
id: ast::NodeId,
146+
should_link: bool,
143147
}
144148

145149
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> {
165169
ident: ident.get().to_str(),
166170
crate_id: crate_id,
167171
id: id,
172+
should_link: should_link(i),
168173
})
169174
}
170175
_ => None
@@ -274,8 +279,10 @@ fn resolve_crate<'a>(e: &mut Env,
274279
ident: &str,
275280
crate_id: &CrateId,
276281
hash: Option<&Svh>,
282+
should_link: bool,
277283
span: Span)
278-
-> ast::CrateNum {
284+
-> (ast::CrateNum, @cstore::crate_metadata,
285+
cstore::CrateSource) {
279286
match existing_match(e, crate_id, hash) {
280287
None => {
281288
let id_hash = link::crate_id_hash(crate_id);
@@ -312,8 +319,11 @@ fn resolve_crate<'a>(e: &mut Env,
312319
let root = if root.is_some() { root } else { &crate_paths };
313320

314321
// Now resolve the crates referenced by this crate
315-
let cnum_map = resolve_crate_deps(e, root, metadata.as_slice(),
316-
span);
322+
let cnum_map = if should_link {
323+
resolve_crate_deps(e, root, metadata.as_slice(), span)
324+
} else {
325+
@RefCell::new(HashMap::new())
326+
};
317327

318328
let cmeta = @cstore::crate_metadata {
319329
name: load_ctxt.crate_id.name.to_owned(),
@@ -323,15 +333,21 @@ fn resolve_crate<'a>(e: &mut Env,
323333
span: span,
324334
};
325335

326-
e.sess.cstore.set_crate_data(cnum, cmeta);
327-
e.sess.cstore.add_used_crate_source(cstore::CrateSource {
336+
let source = cstore::CrateSource {
328337
dylib: dylib,
329338
rlib: rlib,
330339
cnum: cnum,
331-
});
332-
cnum
340+
};
341+
342+
if should_link {
343+
e.sess.cstore.set_crate_data(cnum, cmeta);
344+
e.sess.cstore.add_used_crate_source(source.clone());
345+
}
346+
(cnum, cmeta, source)
333347
}
334-
Some(cnum) => cnum
348+
Some(cnum) => (cnum,
349+
e.sess.cstore.get_crate_data(cnum),
350+
e.sess.cstore.get_used_crate_source(cnum).unwrap())
335351
}
336352
}
337353

@@ -348,11 +364,12 @@ fn resolve_crate_deps(e: &mut Env,
348364
for dep in r.iter() {
349365
let extrn_cnum = dep.cnum;
350366
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
351-
let local_cnum = resolve_crate(e, root,
352-
dep.crate_id.name.as_slice(),
353-
&dep.crate_id,
354-
Some(&dep.hash),
355-
span);
367+
let (local_cnum, _, _) = resolve_crate(e, root,
368+
dep.crate_id.name.as_slice(),
369+
&dep.crate_id,
370+
Some(&dep.hash),
371+
true,
372+
span);
356373
cnum_map.insert(extrn_cnum, local_cnum);
357374
}
358375
return @RefCell::new(cnum_map);
@@ -380,23 +397,17 @@ impl<'a> Loader<'a> {
380397
impl<'a> CrateLoader for Loader<'a> {
381398
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
382399
let info = extract_crate_info(&self.env, krate).unwrap();
383-
let cnum = resolve_crate(&mut self.env, &None, info.ident,
384-
&info.crate_id, None, krate.span);
385-
let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
400+
let (cnum, data, library) = resolve_crate(&mut self.env, &None,
401+
info.ident, &info.crate_id,
402+
None, true, krate.span);
403+
let macros = decoder::get_exported_macros(data);
404+
let cstore = &self.env.sess.cstore;
405+
let registrar = csearch::get_macro_registrar_fn(cstore, cnum)
406+
.map(|did| csearch::get_symbol(cstore, did));
386407
MacroCrate {
387408
lib: library.dylib,
388-
cnum: cnum,
409+
macros: macros.move_iter().collect(),
410+
registrar_symbol: registrar,
389411
}
390412
}
391-
392-
fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> Vec<~str> {
393-
csearch::get_exported_macros(&self.env.sess.cstore, cnum).move_iter()
394-
.collect()
395-
}
396-
397-
fn get_registrar_symbol(&mut self, cnum: ast::CrateNum) -> Option<~str> {
398-
let cstore = &self.env.sess.cstore;
399-
csearch::get_macro_registrar_fn(cstore, cnum)
400-
.map(|did| csearch::get_symbol(cstore, did))
401-
}
402413
}

src/libsyntax/ext/base.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,12 @@ pub fn syntax_expander_table() -> SyntaxEnv {
293293

294294
pub struct MacroCrate {
295295
pub lib: Option<Path>,
296-
pub cnum: ast::CrateNum,
296+
pub macros: Vec<~str>,
297+
pub registrar_symbol: Option<~str>,
297298
}
298299

299300
pub trait CrateLoader {
300301
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate;
301-
fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> Vec<~str> ;
302-
fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>;
303302
}
304303

305304
// One of these is made during expansion and incrementally updated as we go;

src/libsyntax/ext/expand.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,16 +487,16 @@ pub fn expand_view_item(vi: &ast::ViewItem,
487487
}
488488

489489
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
490-
let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
490+
let MacroCrate { lib, macros, registrar_symbol } =
491+
fld.cx.ecfg.loader.load_crate(krate);
491492

492493
let crate_name = match krate.node {
493494
ast::ViewItemExternCrate(name, _, _) => name,
494495
_ => unreachable!()
495496
};
496497
let name = format!("<{} macros>", token::get_ident(crate_name));
497498

498-
let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
499-
for source in exported_macros.iter() {
499+
for source in macros.iter() {
500500
let item = parse::parse_item_from_source_str(name.clone(),
501501
(*source).clone(),
502502
fld.cx.cfg(),
@@ -512,7 +512,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
512512
// Make sure the path contains a / or the linker will search for it.
513513
let path = os::make_absolute(&path);
514514

515-
let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
515+
let registrar = match registrar_symbol {
516516
Some(registrar) => registrar,
517517
None => return
518518
};

0 commit comments

Comments
 (0)