1
Fork 0

Avoid many CrateConfig clones.

This commit changes `ExtCtx::cfg()` so it returns a `CrateConfig`
reference instead of a clone. As a result, it also changes all of the
`cfg()` callsites to explicitly clone... except one, because the commit
also changes `macro_parser::parse()` to take `&CrateConfig`. This is
good, because that function can be hot, and `CrateConfig` is expensive
to clone.

This change almost halves the number of heap allocations done by rustc
for `html5ever` in rustc-benchmarks suite, which makes compilation 1.20x
faster.
This commit is contained in:
Nicholas Nethercote 2016-10-14 09:44:42 +11:00
parent d34318dd53
commit 029dceedb9
8 changed files with 18 additions and 14 deletions

View file

@ -617,11 +617,11 @@ impl<'a> ExtCtxt<'a> {
pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree])
-> parser::Parser<'a> {
parse::tts_to_parser(self.parse_sess, tts.to_vec(), self.cfg())
parse::tts_to_parser(self.parse_sess, tts.to_vec(), self.cfg().clone())
}
pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() }
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() }
pub fn cfg(&self) -> &ast::CrateConfig { &self.cfg }
pub fn call_site(&self) -> Span {
self.codemap().with_expn_info(self.backtrace(), |ei| match ei {
Some(expn_info) => expn_info.call_site,

View file

@ -331,7 +331,7 @@ pub mod rt {
panictry!(parse::parse_item_from_source_str(
"<quote expansion>".to_string(),
s,
self.cfg(),
self.cfg().clone(),
self.parse_sess())).expect("parse error")
}
@ -339,7 +339,7 @@ pub mod rt {
panictry!(parse::parse_stmt_from_source_str(
"<quote expansion>".to_string(),
s,
self.cfg(),
self.cfg().clone(),
self.parse_sess())).expect("parse error")
}
@ -347,7 +347,7 @@ pub mod rt {
panictry!(parse::parse_expr_from_source_str(
"<quote expansion>".to_string(),
s,
self.cfg(),
self.cfg().clone(),
self.parse_sess()))
}
@ -355,7 +355,7 @@ pub mod rt {
panictry!(parse::parse_tts_from_source_str(
"<quote expansion>".to_string(),
s,
self.cfg(),
self.cfg().clone(),
self.parse_sess()))
}
}
@ -924,6 +924,10 @@ fn expand_parse_call(cx: &ExtCtxt,
sp, cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("cfg"), Vec::new());
let cfg_clone_call = || cx.expr_method_call(
sp, cfg_call(),
id_ext("clone"), Vec::new());
let parse_sess_call = || cx.expr_method_call(
sp, cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("parse_sess"), Vec::new());
@ -931,7 +935,7 @@ fn expand_parse_call(cx: &ExtCtxt,
let new_parser_call =
cx.expr_call(sp,
cx.expr_ident(sp, id_ext("new_parser_from_tts")),
vec!(parse_sess_call(), cfg_call(), tts_expr));
vec!(parse_sess_call(), cfg_clone_call(), tts_expr));
let path = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext(parse_method)];
let mut args = vec![cx.expr_mut_addr_of(sp, new_parser_call)];

View file

@ -94,7 +94,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
// The file will be added to the code map by the parser
let p =
parse::new_sub_parser_from_file(cx.parse_sess(),
cx.cfg(),
cx.cfg().clone(),
&res_rel_file(cx,
sp,
Path::new(&file)),

View file

@ -272,7 +272,7 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
}
pub fn parse(sess: &ParseSess,
cfg: ast::CrateConfig,
cfg: &ast::CrateConfig,
mut rdr: TtReader,
ms: &[TokenTree])
-> NamedParseResult {

View file

@ -120,7 +120,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
Some(named_matches),
imported_from,
rhs);
let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
let mut p = Parser::new(cx.parse_sess(), cx.cfg().clone(), Box::new(trncbr));
p.directory = cx.current_expansion.module.directory.clone();
p.restrictions = match cx.current_expansion.no_noninline_mod {
true => Restrictions::NO_NONINLINE_MOD,
@ -225,7 +225,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
// Parse the macro_rules! invocation (`none` is for no interpolations):
let arg_reader = new_tt_reader(&sess.span_diagnostic, None, None, def.body.clone());
let argument_map = match parse(sess, Vec::new(), arg_reader, &argument_gram) {
let argument_map = match parse(sess, &Vec::new(), arg_reader, &argument_gram) {
Success(m) => m,
Failure(sp, str) | Error(sp, str) => {
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &str));

View file

@ -107,7 +107,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
if p2.token != token::Eof {
let mut extra_tts = panictry!(p2.parse_all_token_trees());
extra_tts.extend(tts[first_colon..].iter().cloned());
p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg());
p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg().clone());
}
asm = s;

View file

@ -57,7 +57,7 @@ fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
-> Box<MacResult+'static> {
// Parse an expression and emit it unchanged.
let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(), tts.to_vec());
cx.cfg().clone(), tts.to_vec());
let expr = parser.parse_expr().unwrap();
MacEager::expr(quote_expr!(&mut *cx, $expr))
}

View file

@ -60,7 +60,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResu
// See Issue #15750
fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) -> Box<MacResult + 'static> {
// Parse an expression and emit it unchanged.
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_vec());
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg().clone(), tts.to_vec());
let expr = parser.parse_expr().unwrap();
MacEager::expr(quote_expr!(&mut *cx, $expr))
}