1
Fork 0

Arena-allocate hir::Lifetime.

This shrinks `hir::Ty` from 72 to 48 bytes.

`visit_lifetime` is added to the HIR stats collector because these types
are now stored in memory on their own, instead of being within other
types.
This commit is contained in:
Nicholas Nethercote 2022-09-01 12:06:48 +10:00
parent 512bd84f51
commit 4314615ff8
6 changed files with 65 additions and 56 deletions

View file

@ -1196,7 +1196,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetime_bound = this.elided_dyn_bound(t.span); let lifetime_bound = this.elided_dyn_bound(t.span);
(bounds, lifetime_bound) (bounds, lifetime_bound)
}); });
let kind = hir::TyKind::TraitObject(bounds, lifetime_bound, TraitObjectSyntax::None); let kind = hir::TyKind::TraitObject(bounds, &lifetime_bound, TraitObjectSyntax::None);
return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() }; return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
} }
@ -1934,8 +1934,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let res = res.unwrap_or( let res = res.unwrap_or(
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
); );
let l = self.new_named_lifetime_with_res(id, span, ident, res); hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res))
hir::GenericArg::Lifetime(l)
}, },
)); ));
@ -2004,7 +2003,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
} }
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
let span = self.lower_span(l.ident.span); let span = self.lower_span(l.ident.span);
let ident = self.lower_ident(l.ident); let ident = self.lower_ident(l.ident);
self.new_named_lifetime(l.id, l.id, span, ident) self.new_named_lifetime(l.id, l.id, span, ident)
@ -2017,7 +2016,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: Span, span: Span,
ident: Ident, ident: Ident,
res: LifetimeRes, res: LifetimeRes,
) -> hir::Lifetime { ) -> &'hir hir::Lifetime {
let name = match res { let name = match res {
LifetimeRes::Param { param, .. } => { LifetimeRes::Param { param, .. } => {
let p_name = ParamName::Plain(ident); let p_name = ParamName::Plain(ident);
@ -2038,7 +2037,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}; };
debug!(?name); debug!(?name);
hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name } self.arena.alloc(hir::Lifetime {
hir_id: self.lower_node_id(id),
span: self.lower_span(span),
name,
})
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
@ -2048,7 +2051,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
new_id: NodeId, new_id: NodeId,
span: Span, span: Span,
ident: Ident, ident: Ident,
) -> hir::Lifetime { ) -> &'hir hir::Lifetime {
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
self.new_named_lifetime_with_res(new_id, span, ident, res) self.new_named_lifetime_with_res(new_id, span, ident, res)
} }
@ -2462,14 +2465,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// bound, like the bound in `Box<dyn Debug>`. This method is not invoked /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
/// when the bound is written, even if it is written with `'_` like in /// when the bound is written, even if it is written with `'_` like in
/// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked. /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime { fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
let r = hir::Lifetime { let r = hir::Lifetime {
hir_id: self.next_id(), hir_id: self.next_id(),
span: self.lower_span(span), span: self.lower_span(span),
name: hir::LifetimeName::ImplicitObjectLifetimeDefault, name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
}; };
debug!("elided_dyn_bound: r={:?}", r); debug!("elided_dyn_bound: r={:?}", r);
r self.arena.alloc(r)
} }
} }

View file

@ -259,7 +259,7 @@ impl InferArg {
#[derive(Debug, HashStable_Generic)] #[derive(Debug, HashStable_Generic)]
pub enum GenericArg<'hir> { pub enum GenericArg<'hir> {
Lifetime(Lifetime), Lifetime(&'hir Lifetime),
Type(&'hir Ty<'hir>), Type(&'hir Ty<'hir>),
Const(ConstArg), Const(ConstArg),
Infer(InferArg), Infer(InferArg),
@ -430,7 +430,7 @@ pub enum GenericBound<'hir> {
Trait(PolyTraitRef<'hir>, TraitBoundModifier), Trait(PolyTraitRef<'hir>, TraitBoundModifier),
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>), LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
Outlives(Lifetime), Outlives(&'hir Lifetime),
} }
impl GenericBound<'_> { impl GenericBound<'_> {
@ -756,7 +756,7 @@ impl<'hir> WhereBoundPredicate<'hir> {
pub struct WhereRegionPredicate<'hir> { pub struct WhereRegionPredicate<'hir> {
pub span: Span, pub span: Span,
pub in_where_clause: bool, pub in_where_clause: bool,
pub lifetime: Lifetime, pub lifetime: &'hir Lifetime,
pub bounds: GenericBounds<'hir>, pub bounds: GenericBounds<'hir>,
} }
@ -2499,7 +2499,7 @@ pub enum TyKind<'hir> {
/// A raw pointer (i.e., `*const T` or `*mut T`). /// A raw pointer (i.e., `*const T` or `*mut T`).
Ptr(MutTy<'hir>), Ptr(MutTy<'hir>),
/// A reference (i.e., `&'a T` or `&'a mut T`). /// A reference (i.e., `&'a T` or `&'a mut T`).
Rptr(Lifetime, MutTy<'hir>), Rptr(&'hir Lifetime, MutTy<'hir>),
/// A bare function (e.g., `fn(usize) -> bool`). /// A bare function (e.g., `fn(usize) -> bool`).
BareFn(&'hir BareFnTy<'hir>), BareFn(&'hir BareFnTy<'hir>),
/// The never type (`!`). /// The never type (`!`).
@ -2518,7 +2518,7 @@ pub enum TyKind<'hir> {
OpaqueDef(ItemId, &'hir [GenericArg<'hir>]), OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
/// A trait object type `Bound1 + Bound2 + Bound3` /// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime. /// where `Bound` is a trait or a lifetime.
TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime, TraitObjectSyntax), TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
/// Unused for now. /// Unused for now.
Typeof(AnonConst), Typeof(AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been /// `TyKind::Infer` means the type should be inferred instead of it having been
@ -3474,7 +3474,7 @@ mod size_asserts {
static_assert_size!(ForeignItem<'_>, 72); static_assert_size!(ForeignItem<'_>, 72);
static_assert_size!(ForeignItemKind<'_>, 40); static_assert_size!(ForeignItemKind<'_>, 40);
#[cfg(not(bootstrap))] #[cfg(not(bootstrap))]
static_assert_size!(GenericArg<'_>, 32); static_assert_size!(GenericArg<'_>, 24);
static_assert_size!(GenericBound<'_>, 48); static_assert_size!(GenericBound<'_>, 48);
static_assert_size!(Generics<'_>, 56); static_assert_size!(Generics<'_>, 56);
static_assert_size!(Impl<'_>, 80); static_assert_size!(Impl<'_>, 80);
@ -3494,9 +3494,9 @@ mod size_asserts {
static_assert_size!(Stmt<'_>, 32); static_assert_size!(Stmt<'_>, 32);
static_assert_size!(StmtKind<'_>, 16); static_assert_size!(StmtKind<'_>, 16);
#[cfg(not(bootstrap))] #[cfg(not(bootstrap))]
static_assert_size!(TraitItem<'static>, 88); static_assert_size!(TraitItem<'_>, 88);
#[cfg(not(bootstrap))] #[cfg(not(bootstrap))]
static_assert_size!(TraitItemKind<'_>, 48); static_assert_size!(TraitItemKind<'_>, 48);
static_assert_size!(Ty<'_>, 72); static_assert_size!(Ty<'_>, 48);
static_assert_size!(TyKind<'_>, 56); static_assert_size!(TyKind<'_>, 32);
} }

View file

@ -437,6 +437,11 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
} }
} }
fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
self.record("Lifetime", Id::Node(lifetime.hir_id), lifetime);
hir_visit::walk_lifetime(self, lifetime)
}
fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) { fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) {
self.record("Path", Id::None, path); self.record("Path", Id::None, path);
hir_visit::walk_path(self, path) hir_visit::walk_path(self, path)

View file

@ -190,7 +190,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
) )
} }
fn clean_lifetime<'tcx>(lifetime: hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime {
let def = cx.tcx.named_region(lifetime.hir_id); let def = cx.tcx.named_region(lifetime.hir_id);
if let Some( if let Some(
rl::Region::EarlyBound(node_id) rl::Region::EarlyBound(node_id)
@ -495,7 +495,7 @@ fn clean_generic_param<'tcx>(
.filter(|bp| !bp.in_where_clause) .filter(|bp| !bp.in_where_clause)
.flat_map(|bp| bp.bounds) .flat_map(|bp| bp.bounds)
.map(|bound| match bound { .map(|bound| match bound {
hir::GenericBound::Outlives(lt) => clean_lifetime(*lt, cx), hir::GenericBound::Outlives(lt) => clean_lifetime(lt, cx),
_ => panic!(), _ => panic!(),
}) })
.collect() .collect()
@ -1392,7 +1392,7 @@ fn maybe_expand_private_type_alias<'tcx>(
} }
_ => None, _ => None,
}); });
if let Some(lt) = lifetime.cloned() { if let Some(lt) = lifetime {
let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id); let lt_def_id = cx.tcx.hir().local_def_id(param.hir_id);
let cleaned = let cleaned =
if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() }; if !lt.is_elided() { clean_lifetime(lt, cx) } else { Lifetime::elided() };

View file

@ -119,59 +119,60 @@ hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size hir-stats Name Accumulated Size Count Item Size
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats ForeignItemRef 24 ( 0.2%) 1 24 hir-stats ForeignItemRef 24 ( 0.2%) 1 24
hir-stats Lifetime 32 ( 0.3%) 1 32
hir-stats Mod 32 ( 0.3%) 1 32 hir-stats Mod 32 ( 0.3%) 1 32
hir-stats ExprField 40 ( 0.4%) 1 40 hir-stats ExprField 40 ( 0.4%) 1 40
hir-stats TraitItemRef 56 ( 0.6%) 2 28 hir-stats TraitItemRef 56 ( 0.6%) 2 28
hir-stats Param 64 ( 0.6%) 2 32 hir-stats Local 64 ( 0.7%) 1 64
hir-stats Local 64 ( 0.6%) 1 64 hir-stats Param 64 ( 0.7%) 2 32
hir-stats InlineAsm 72 ( 0.7%) 1 72 hir-stats InlineAsm 72 ( 0.7%) 1 72
hir-stats ImplItemRef 72 ( 0.7%) 2 36 hir-stats ImplItemRef 72 ( 0.7%) 2 36
hir-stats FieldDef 96 ( 0.9%) 2 48 hir-stats Body 96 ( 1.0%) 3 32
hir-stats Arm 96 ( 0.9%) 2 48 hir-stats GenericArg 96 ( 1.0%) 4 24
hir-stats Body 96 ( 0.9%) 3 32 hir-stats - Type 24 ( 0.2%) 1
hir-stats Stmt 96 ( 0.9%) 3 32 hir-stats - Lifetime 72 ( 0.7%) 3
hir-stats FieldDef 96 ( 1.0%) 2 48
hir-stats Arm 96 ( 1.0%) 2 48
hir-stats Stmt 96 ( 1.0%) 3 32
hir-stats - Local 32 ( 0.3%) 1 hir-stats - Local 32 ( 0.3%) 1
hir-stats - Semi 32 ( 0.3%) 1 hir-stats - Semi 32 ( 0.3%) 1
hir-stats - Expr 32 ( 0.3%) 1 hir-stats - Expr 32 ( 0.3%) 1
hir-stats FnDecl 120 ( 1.2%) 3 40 hir-stats FnDecl 120 ( 1.2%) 3 40
hir-stats Attribute 128 ( 1.3%) 4 32 hir-stats Attribute 128 ( 1.3%) 4 32
hir-stats GenericArg 128 ( 1.3%) 4 32 hir-stats GenericArgs 144 ( 1.5%) 3 48
hir-stats - Type 32 ( 0.3%) 1
hir-stats - Lifetime 96 ( 0.9%) 3
hir-stats GenericArgs 144 ( 1.4%) 3 48
hir-stats Variant 160 ( 1.6%) 2 80 hir-stats Variant 160 ( 1.6%) 2 80
hir-stats GenericBound 192 ( 1.9%) 4 48 hir-stats WherePredicate 168 ( 1.7%) 3 56
hir-stats - Trait 192 ( 1.9%) 4 hir-stats - BoundPredicate 168 ( 1.7%) 3
hir-stats WherePredicate 216 ( 2.1%) 3 72 hir-stats GenericBound 192 ( 2.0%) 4 48
hir-stats - BoundPredicate 216 ( 2.1%) 3 hir-stats - Trait 192 ( 2.0%) 4
hir-stats Block 288 ( 2.8%) 6 48 hir-stats Block 288 ( 3.0%) 6 48
hir-stats GenericParam 400 ( 3.9%) 5 80 hir-stats GenericParam 400 ( 4.1%) 5 80
hir-stats Pat 440 ( 4.3%) 5 88 hir-stats Pat 440 ( 4.5%) 5 88
hir-stats - Wild 88 ( 0.9%) 1 hir-stats - Wild 88 ( 0.9%) 1
hir-stats - Struct 88 ( 0.9%) 1 hir-stats - Struct 88 ( 0.9%) 1
hir-stats - Binding 264 ( 2.6%) 3 hir-stats - Binding 264 ( 2.7%) 3
hir-stats Generics 560 ( 5.5%) 10 56 hir-stats Generics 560 ( 5.7%) 10 56
hir-stats Expr 768 ( 7.6%) 12 64 hir-stats Ty 720 ( 7.4%) 15 48
hir-stats - Path 64 ( 0.6%) 1 hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Struct 64 ( 0.6%) 1 hir-stats - Rptr 48 ( 0.5%) 1
hir-stats - Match 64 ( 0.6%) 1 hir-stats - Path 624 ( 6.4%) 13
hir-stats - InlineAsm 64 ( 0.6%) 1 hir-stats Expr 768 ( 7.9%) 12 64
hir-stats - Path 64 ( 0.7%) 1
hir-stats - Struct 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Lit 128 ( 1.3%) 2 hir-stats - Lit 128 ( 1.3%) 2
hir-stats - Block 384 ( 3.8%) 6 hir-stats - Block 384 ( 3.9%) 6
hir-stats Item 960 ( 9.4%) 12 80 hir-stats Item 960 ( 9.8%) 12 80
hir-stats - Trait 80 ( 0.8%) 1 hir-stats - Trait 80 ( 0.8%) 1
hir-stats - Enum 80 ( 0.8%) 1 hir-stats - Enum 80 ( 0.8%) 1
hir-stats - ExternCrate 80 ( 0.8%) 1 hir-stats - ExternCrate 80 ( 0.8%) 1
hir-stats - ForeignMod 80 ( 0.8%) 1 hir-stats - ForeignMod 80 ( 0.8%) 1
hir-stats - Impl 80 ( 0.8%) 1 hir-stats - Impl 80 ( 0.8%) 1
hir-stats - Fn 160 ( 1.6%) 2 hir-stats - Fn 160 ( 1.6%) 2
hir-stats - Use 400 ( 3.9%) 5 hir-stats - Use 400 ( 4.1%) 5
hir-stats Ty 1_080 (10.6%) 15 72 hir-stats Path 1_536 (15.7%) 32 48
hir-stats - Ptr 72 ( 0.7%) 1 hir-stats PathSegment 2_240 (23.0%) 40 56
hir-stats - Rptr 72 ( 0.7%) 1
hir-stats - Path 936 ( 9.2%) 13
hir-stats Path 1_536 (15.1%) 32 48
hir-stats PathSegment 2_240 (22.0%) 40 56
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats Total 10_168 hir-stats Total 9_760
hir-stats hir-stats

View file

@ -929,7 +929,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
} }
} }
pub fn hash_lifetime(&mut self, lifetime: Lifetime) { pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
std::mem::discriminant(&lifetime.name).hash(&mut self.s); std::mem::discriminant(&lifetime.name).hash(&mut self.s);
if let LifetimeName::Param(param_id, ref name) = lifetime.name { if let LifetimeName::Param(param_id, ref name) = lifetime.name {
std::mem::discriminant(name).hash(&mut self.s); std::mem::discriminant(name).hash(&mut self.s);