From 2d1240e6f7709d06caddc396f689ba0bc77f80a3 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sun, 22 Aug 2021 21:35:01 -0700 Subject: [PATCH] Box `GenericArgs::Parenthesized.output` This reduces the size of `GenericArgs` from 104 bytes to 56 bytes, essentially reducing it by half. `GenericArgs` is one of the fields of `PathSegment`, so this should reduce the amount of memory allocated for `PathSegment`s in the cases where the generics are not for a `Fn`, `FnMut`, or `FnOnce` trait. I also added `static_assert_size!`s to `GenericArgs` and `PathSegment` to ensure they don't increase in size unexpectedly. --- src/librustdoc/clean/auto_trait.rs | 6 ++++-- src/librustdoc/clean/mod.rs | 7 +++---- src/librustdoc/clean/simplify.rs | 4 ++-- src/librustdoc/clean/types.rs | 12 +++++++++++- src/librustdoc/json/conversions.rs | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 8ad09a9edc01c..f98059b1a7483 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -350,8 +350,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { .into_iter() .flat_map(|(ty, mut bounds)| { if let Some(data) = ty_to_fn.get(&ty) { - let (poly_trait, output) = - (data.0.as_ref().expect("as_ref failed").clone(), data.1.as_ref().cloned()); + let (poly_trait, output) = ( + data.0.as_ref().expect("as_ref failed").clone(), + data.1.as_ref().cloned().map(Box::new), + ); let new_ty = match poly_trait.trait_ { Type::ResolvedPath { ref path, ref did, ref is_generic } => { let mut new_path = path.clone(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 640acffb114d9..b866455e51b22 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1763,10 +1763,9 @@ impl Clean for hir::GenericArgs<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs { if self.parenthesized { let output = self.bindings[0].ty().clean(cx); - GenericArgs::Parenthesized { - inputs: self.inputs().clean(cx), - output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }, - } + let output = + if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; + GenericArgs::Parenthesized { inputs: self.inputs().clean(cx), output } } else { GenericArgs::AngleBracketed { args: self diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index c0d52d349280f..d139b19f5dc43 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -116,10 +116,10 @@ crate fn merge_bounds( }); } PP::Parenthesized { ref mut output, .. } => match output { - Some(o) => assert_eq!(o, rhs), + Some(o) => assert_eq!(o.as_ref(), rhs), None => { if *rhs != clean::Type::Tuple(Vec::new()) { - *output = Some(rhs.clone()); + *output = Some(Box::new(rhs.clone())); } } }, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7025574914331..1cbcf621eb6b1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2018,15 +2018,25 @@ crate enum GenericArg { #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate enum GenericArgs { AngleBracketed { args: Vec, bindings: Vec }, - Parenthesized { inputs: Vec, output: Option }, + Parenthesized { inputs: Vec, output: Option> }, } +// `GenericArgs` is in every `PathSegment`, so its size can significantly +// affect rustdoc's memory usage. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +rustc_data_structures::static_assert_size!(GenericArgs, 56); + #[derive(Clone, PartialEq, Eq, Debug, Hash)] crate struct PathSegment { crate name: Symbol, crate args: GenericArgs, } +// `PathSegment` usually occurs multiple times in every `Path`, so its size can +// significantly affect rustdoc's memory usage. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +rustc_data_structures::static_assert_size!(PathSegment, 64); + #[derive(Clone, Debug)] crate struct Typedef { crate type_: Type, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index f3eeea6c6ae0b..da6428a58cb11 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -127,7 +127,7 @@ impl FromWithTcx for GenericArgs { }, Parenthesized { inputs, output } => GenericArgs::Parenthesized { inputs: inputs.into_iter().map(|a| a.into_tcx(tcx)).collect(), - output: output.map(|a| a.into_tcx(tcx)), + output: output.map(|a| (*a).into_tcx(tcx)), }, } }