Skip to content

Commit

Permalink
Pre-allocate an empty Lrc<NamedMatchVec>.
Browse files Browse the repository at this point in the history
This avoids some allocations.
  • Loading branch information
nnethercote committed Mar 29, 2022
1 parent 524d21b commit 6b0a16a
Showing 1 changed file with 26 additions and 8 deletions.
34 changes: 26 additions & 8 deletions compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,11 @@ struct MatcherPos<'tt> {
rustc_data_structures::static_assert_size!(MatcherPos<'_>, 104);

impl<'tt> MatcherPos<'tt> {
fn top_level(matcher: &'tt [TokenTree]) -> Self {
fn top_level(matcher: &'tt [TokenTree], empty_matches: Lrc<NamedMatchVec>) -> Self {
MatcherPos {
tts: matcher,
idx: 0,
matches: Lrc::new(smallvec![]),
matches: empty_matches,
seq_depth: 0,
match_lo: 0,
match_cur: 0,
Expand All @@ -168,7 +168,11 @@ impl<'tt> MatcherPos<'tt> {
}
}

fn sequence(parent: Box<MatcherPos<'tt>>, seq: &'tt SequenceRepetition) -> Self {
fn sequence(
parent: Box<MatcherPos<'tt>>,
seq: &'tt SequenceRepetition,
empty_matches: Lrc<NamedMatchVec>,
) -> Self {
let mut mp = MatcherPos {
tts: &seq.tts,
idx: 0,
Expand All @@ -182,7 +186,7 @@ impl<'tt> MatcherPos<'tt> {
// Start with an empty vec for each metavar within the sequence. Note that `mp.seq_depth`
// must have the parent's depth at this point for these `push_match` calls to work.
for idx in mp.match_lo..mp.match_lo + seq.num_captures {
mp.push_match(idx, MatchedSeq(Lrc::new(smallvec![])));
mp.push_match(idx, MatchedSeq(empty_matches.clone()));
}
mp.seq_depth += 1;
mp
Expand Down Expand Up @@ -415,11 +419,21 @@ pub struct TtParser<'tt> {

/// The set of mps that are waiting for the black-box parser.
bb_mps: Vec<Box<MatcherPos<'tt>>>,

/// Pre-allocate an empty match array, so it can be cloned cheaply for macros with many rules
/// that have no metavars.
empty_matches: Lrc<NamedMatchVec>,
}

impl<'tt> TtParser<'tt> {
pub(super) fn new(macro_name: Ident) -> TtParser<'tt> {
TtParser { macro_name, cur_mps: vec![], next_mps: vec![], bb_mps: vec![] }
TtParser {
macro_name,
cur_mps: vec![],
next_mps: vec![],
bb_mps: vec![],
empty_matches: Lrc::new(smallvec![]),
}
}

/// Process the matcher positions of `cur_mps` until it is empty. In the process, this will
Expand Down Expand Up @@ -469,13 +483,17 @@ impl<'tt> TtParser<'tt> {
new_mp.match_cur += seq.num_captures;
new_mp.idx += 1;
for idx in mp.match_cur..mp.match_cur + seq.num_captures {
new_mp.push_match(idx, MatchedSeq(Lrc::new(smallvec![])));
new_mp.push_match(idx, MatchedSeq(self.empty_matches.clone()));
}
self.cur_mps.push(new_mp);
}

// Allow for the possibility of one or more matches of this sequence.
self.cur_mps.push(box MatcherPos::sequence(mp, &seq));
self.cur_mps.push(box MatcherPos::sequence(
mp,
&seq,
self.empty_matches.clone(),
));
}

&TokenTree::MetaVarDecl(span, _, None) => {
Expand Down Expand Up @@ -621,7 +639,7 @@ impl<'tt> TtParser<'tt> {
// possible next positions into `next_mps`. After some post-processing, the contents of
// `next_mps` replenish `cur_mps` and we start over again.
self.cur_mps.clear();
self.cur_mps.push(box MatcherPos::top_level(matcher));
self.cur_mps.push(box MatcherPos::top_level(matcher, self.empty_matches.clone()));

loop {
self.next_mps.clear();
Expand Down

0 comments on commit 6b0a16a

Please sign in to comment.