From d9592c2d9f0db851b090c10c0cc3560b87fc7789 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Apr 2022 12:08:39 +1000 Subject: [PATCH] Shrink `Nonterminal`. By heap allocating the argument within `NtPath`, `NtVis`, and `NtStmt`. This slightly reduces cumulative and peak allocation amounts, most notably on `deep-vector`. --- compiler/rustc_ast/src/attr/mod.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 4 +++- compiler/rustc_ast/src/token.rs | 8 ++++---- compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_expand/src/proc_macro.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 2 +- compiler/rustc_parse/src/parser/nonterminal.rs | 6 +++--- compiler/rustc_parse/src/parser/path.rs | 2 +- compiler/rustc_parse/src/parser/stmt.rs | 4 ++-- 10 files changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 550c66e3d3b20..80caf37d7099d 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -439,7 +439,7 @@ impl MetaItem { } Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt { token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span), - token::Nonterminal::NtPath(ref path) => path.clone(), + token::Nonterminal::NtPath(ref path) => (**path).clone(), _ => return None, }, _ => return None, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 32621eb5f2f66..15f7aceb83d7a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -772,7 +772,9 @@ pub fn visit_interpolated(nt: &mut token::Nonterminal, vis: &mut token::NtBlock(block) => vis.visit_block(block), token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { // See reasoning above. - vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") + stmt.map(|stmt| { + vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") + }) }), token::NtPat(pat) => vis.visit_pat(pat), token::NtExpr(expr) => vis.visit_expr(expr), diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 2132cdfc001b6..031c6cae793e2 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -668,7 +668,7 @@ impl PartialEq for Token { pub enum Nonterminal { NtItem(P), NtBlock(P), - NtStmt(ast::Stmt), + NtStmt(P), NtPat(P), NtExpr(P), NtTy(P), @@ -677,13 +677,13 @@ pub enum Nonterminal { NtLiteral(P), /// Stuff inside brackets for attributes NtMeta(P), - NtPath(ast::Path), - NtVis(ast::Visibility), + NtPath(P), + NtVis(P), } // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Nonterminal, 48); +rustc_data_structures::static_assert_size!(Nonterminal, 16); #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)] pub enum NonterminalKind { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 06a90ab05ac82..12b117d6fc9b4 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -118,7 +118,7 @@ impl Annotatable { Annotatable::ForeignItem(item) => { token::NtItem(P(item.and_then(ast::ForeignItem::into_item))) } - Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()), + Annotatable::Stmt(stmt) => token::NtStmt(stmt), Annotatable::Expr(expr) => token::NtExpr(expr), Annotatable::Arm(..) | Annotatable::ExprField(..) diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index b4bae8ce5fbeb..aec401a041ca3 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -90,7 +90,7 @@ impl MultiItemModifier for ProcMacroDerive { // A proc macro can't observe the fact that we're passing // them an `NtStmt` - it can only see the underlying tokens // of the wrapped item - token::NtStmt(stmt.into_inner()) + token::NtStmt(stmt) } _ => unreachable!(), }; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7978a1a7f5fff..7efc0ca2da234 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -41,7 +41,7 @@ macro_rules! maybe_whole_expr { return Ok(e); } token::NtPath(path) => { - let path = path.clone(); + let path = (**path).clone(); $p.bump(); return Ok($p.mk_expr( $p.prev_token.span, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 792f9d9ccce56..f1956fb695bf7 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1289,7 +1289,7 @@ impl<'a> Parser<'a> { /// so emit a proper diagnostic. // Public for rustfmt usage. pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> { - maybe_whole!(self, NtVis, |x| x); + maybe_whole!(self, NtVis, |x| x.into_inner()); self.expected_tokens.push(TokenType::Keyword(kw::Crate)); if self.is_crate_vis() { diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index c105fbfaee053..b45bca3d2e024 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -118,7 +118,7 @@ impl<'a> Parser<'a> { token::NtBlock(self.collect_tokens_no_attrs(|this| this.parse_block())?) } NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? { - Some(s) => token::NtStmt(s), + Some(s) => token::NtStmt(P(s)), None => { return Err(self.struct_span_err(self.token.span, "expected a statement")); } @@ -161,11 +161,11 @@ impl<'a> Parser<'a> { return Err(self.struct_span_err(self.token.span, msg)); } NonterminalKind::Path => token::NtPath( - self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?, + P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?), ), NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)), NonterminalKind::Vis => token::NtVis( - self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?, + P(self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?), ), NonterminalKind::Lifetime => { if self.check_lifetime() { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 93663a349f51e..207ecd00e0c0a 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -165,7 +165,7 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPath, |path| { reject_generics_if_mod_style(self, &path); - path + path.into_inner() }); if let token::Interpolated(nt) = &self.token.kind { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index e3bcd945db716..5b7ae5f7a7b82 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -54,7 +54,7 @@ impl<'a> Parser<'a> { stmt.visit_attrs(|stmt_attrs| { attrs.prepend_to_nt_inner(stmt_attrs); }); - return Ok(Some(stmt)); + return Ok(Some(stmt.into_inner())); } Ok(Some(if self.token.is_keyword(kw::Let) { @@ -535,7 +535,7 @@ impl<'a> Parser<'a> { recover: AttemptLocalParseRecovery, ) -> PResult<'a, Option> { // Skip looking for a trailing semicolon when we have an interpolated statement. - maybe_whole!(self, NtStmt, |x| Some(x)); + maybe_whole!(self, NtStmt, |x| Some(x.into_inner())); let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else { return Ok(None);