Skip to content

Commit

Permalink
Rollup merge of rust-lang#37318 - nnethercote:html5ever-more, r=nrc,e…
Browse files Browse the repository at this point in the history
…ddyb

Avoid some allocations in the macro parser

These three commits reduce the number of heap allocations done when compiling rustc-benchmarks/html5ever-2016-08-25 by 20%, from 16.5M to 13.3M. This speeds up (debug) compilation of it with a stage1 compiler by about 7%.
  • Loading branch information
Manishearth committed Oct 22, 2016
2 parents 14e7c6d + b817cf8 commit 2e4d80d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 16 deletions.
21 changes: 14 additions & 7 deletions src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,22 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])

pub enum ParseResult<T> {
Success(T),
/// Arm failed to match
Failure(syntax_pos::Span, String),
/// Arm failed to match. If the second parameter is `token::Eof`, it
/// indicates an unexpected end of macro invocation. Otherwise, it
/// indicates that no rules expected the given token.
Failure(syntax_pos::Span, Token),
/// Fatal error (malformed macro?). Abort compilation.
Error(syntax_pos::Span, String)
}

pub fn parse_failure_msg(tok: Token) -> String {
match tok {
token::Eof => "unexpected end of macro invocation".to_string(),
_ => format!("no rules expected the token `{}`", pprust::token_to_string(&tok)),
}
}

pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>;

/// Perform a token equality check, ignoring syntax context (that is, an
/// unhygienic comparison)
Expand Down Expand Up @@ -425,8 +433,8 @@ pub fn parse(sess: &ParseSess,
cur_eis.push(ei);
}
TokenTree::Token(_, ref t) => {
let mut ei_t = ei.clone();
if token_name_eq(t,&tok) {
let mut ei_t = ei.clone();
ei_t.idx += 1;
next_eis.push(ei_t);
}
Expand All @@ -446,7 +454,7 @@ pub fn parse(sess: &ParseSess,
} else if eof_eis.len() > 1 {
return Error(sp, "ambiguity: multiple successful parses".to_string());
} else {
return Failure(sp, "unexpected end of macro invocation".to_string());
return Failure(sp, token::Eof);
}
} else {
if (!bb_eis.is_empty() && !next_eis.is_empty())
Expand All @@ -467,8 +475,7 @@ pub fn parse(sess: &ParseSess,
}
))
} else if bb_eis.is_empty() && next_eis.is_empty() {
return Failure(sp, format!("no rules expected the token `{}`",
pprust::token_to_string(&tok)));
return Failure(sp, tok);
} else if !next_eis.is_empty() {
/* Now process the next token */
while !next_eis.is_empty() {
Expand Down
19 changes: 12 additions & 7 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ext::expand::{Expansion, ExpansionKind};
use ext::placeholders;
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::parse;
use ext::tt::macro_parser::{parse, parse_failure_msg};
use parse::ParseSess;
use parse::lexer::new_tt_reader;
use parse::parser::{Parser, Restrictions};
Expand Down Expand Up @@ -97,7 +97,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,

// Which arm's failure should we report? (the one furthest along)
let mut best_fail_spot = DUMMY_SP;
let mut best_fail_msg = "internal error: ran no matchers".to_string();
let mut best_fail_tok = None;

for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers
let lhs_tt = match *lhs {
Expand Down Expand Up @@ -134,17 +134,18 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
macro_ident: name
})
}
Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo {
Failure(sp, tok) => if sp.lo >= best_fail_spot.lo {
best_fail_spot = sp;
best_fail_msg = (*msg).clone();
best_fail_tok = Some(tok);
},
Error(err_sp, ref msg) => {
cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..])
}
}
}

cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]);
let best_fail_msg = parse_failure_msg(best_fail_tok.expect("ran no matchers"));
cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg);
}

pub struct MacroRulesExpander;
Expand Down Expand Up @@ -222,8 +223,12 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {

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));
Failure(sp, tok) => {
let s = parse_failure_msg(tok);
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s));
}
Error(sp, s) => {
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s));
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
use syntax::ext::build::AstBuilder;
use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
use syntax::ext::tt::macro_parser::{Success, Failure, Error};
use syntax::ext::tt::macro_parser::parse_failure_msg;
use syntax::ptr::P;
use syntax_pos::Span;
use rustc_plugin::Registry;
Expand Down Expand Up @@ -58,8 +59,11 @@ fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
_ => unreachable!()
}
}
Failure(_, s) | Error(_, s) => {
panic!("expected Success, but got Error/Failure: {}", s);
Failure(_, tok) => {
panic!("expected Success, but got Failure: {}", parse_failure_msg(tok));
}
Error(_, s) => {
panic!("expected Success, but got Error: {}", s);
}
};

Expand Down

0 comments on commit 2e4d80d

Please sign in to comment.