Skip to content

Commit 58924cf

Browse files
Merge #8334
8334: Intern and shrink more data to reduce memory usage r=jonas-schievink a=jonas-schievink bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 19e09a4 + 6f1ee9a commit 58924cf

File tree

12 files changed

+75
-99
lines changed

12 files changed

+75
-99
lines changed

crates/hir_def/src/db.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
1414
generics::GenericParams,
1515
import_map::ImportMap,
16+
intern::Interned,
1617
item_tree::ItemTree,
1718
lang_item::{LangItemTarget, LangItems},
1819
nameres::DefMap,
@@ -113,7 +114,7 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
113114
fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>;
114115

115116
#[salsa::invoke(GenericParams::generic_params_query)]
116-
fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
117+
fn generic_params(&self, def: GenericDefId) -> Interned<GenericParams>;
117118

118119
#[salsa::invoke(Attrs::variants_attrs_query)]
119120
fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>;

crates/hir_def/src/generics.rs

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! structs, impls, traits, etc. This module provides a common HIR for these
33
//! generic parameters. See also the `Generics` type and the `generics_of` query
44
//! in rustc.
5-
use std::sync::Arc;
65
76
use base_db::FileId;
87
use either::Either;
@@ -18,6 +17,7 @@ use crate::{
1817
child_by_source::ChildBySource,
1918
db::DefDatabase,
2019
dyn_map::DynMap,
20+
intern::Interned,
2121
keys,
2222
src::{HasChildSource, HasSource},
2323
type_ref::{LifetimeRef, TypeBound, TypeRef},
@@ -26,35 +26,35 @@ use crate::{
2626
};
2727

2828
/// Data about a generic type parameter (to a function, struct, impl, ...).
29-
#[derive(Clone, PartialEq, Eq, Debug)]
29+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
3030
pub struct TypeParamData {
3131
pub name: Option<Name>,
32-
pub default: Option<TypeRef>,
32+
pub default: Option<Interned<TypeRef>>,
3333
pub provenance: TypeParamProvenance,
3434
}
3535

3636
/// Data about a generic lifetime parameter (to a function, struct, impl, ...).
37-
#[derive(Clone, PartialEq, Eq, Debug)]
37+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
3838
pub struct LifetimeParamData {
3939
pub name: Name,
4040
}
4141

4242
/// Data about a generic const parameter (to a function, struct, impl, ...).
43-
#[derive(Clone, PartialEq, Eq, Debug)]
43+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
4444
pub struct ConstParamData {
4545
pub name: Name,
46-
pub ty: TypeRef,
46+
pub ty: Interned<TypeRef>,
4747
}
4848

49-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
49+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
5050
pub enum TypeParamProvenance {
5151
TypeParamList,
5252
TraitSelf,
5353
ArgumentImplTrait,
5454
}
5555

5656
/// Data about the generic parameters of a function, struct, impl, etc.
57-
#[derive(Clone, PartialEq, Eq, Debug, Default)]
57+
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
5858
pub struct GenericParams {
5959
pub types: Arena<TypeParamData>,
6060
pub lifetimes: Arena<LifetimeParamData>,
@@ -66,16 +66,16 @@ pub struct GenericParams {
6666
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
6767
/// It might still result in multiple actual predicates though, because of
6868
/// associated type bindings like `Iterator<Item = u32>`.
69-
#[derive(Clone, PartialEq, Eq, Debug)]
69+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
7070
pub enum WherePredicate {
7171
TypeBound { target: WherePredicateTypeTarget, bound: TypeBound },
7272
Lifetime { target: LifetimeRef, bound: LifetimeRef },
7373
ForLifetime { lifetimes: Box<[Name]>, target: WherePredicateTypeTarget, bound: TypeBound },
7474
}
7575

76-
#[derive(Clone, PartialEq, Eq, Debug)]
76+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
7777
pub enum WherePredicateTypeTarget {
78-
TypeRef(TypeRef),
78+
TypeRef(Interned<TypeRef>),
7979
/// For desugared where predicates that can directly refer to a type param.
8080
TypeParam(LocalTypeParamId),
8181
}
@@ -91,55 +91,57 @@ impl GenericParams {
9191
pub(crate) fn generic_params_query(
9292
db: &dyn DefDatabase,
9393
def: GenericDefId,
94-
) -> Arc<GenericParams> {
94+
) -> Interned<GenericParams> {
9595
let _p = profile::span("generic_params_query");
9696

9797
let generics = match def {
9898
GenericDefId::FunctionId(id) => {
9999
let id = id.lookup(db).id;
100100
let tree = id.item_tree(db);
101101
let item = &tree[id.value];
102-
tree[item.generic_params].clone()
102+
item.generic_params.clone()
103103
}
104104
GenericDefId::AdtId(AdtId::StructId(id)) => {
105105
let id = id.lookup(db).id;
106106
let tree = id.item_tree(db);
107107
let item = &tree[id.value];
108-
tree[item.generic_params].clone()
108+
item.generic_params.clone()
109109
}
110110
GenericDefId::AdtId(AdtId::EnumId(id)) => {
111111
let id = id.lookup(db).id;
112112
let tree = id.item_tree(db);
113113
let item = &tree[id.value];
114-
tree[item.generic_params].clone()
114+
item.generic_params.clone()
115115
}
116116
GenericDefId::AdtId(AdtId::UnionId(id)) => {
117117
let id = id.lookup(db).id;
118118
let tree = id.item_tree(db);
119119
let item = &tree[id.value];
120-
tree[item.generic_params].clone()
120+
item.generic_params.clone()
121121
}
122122
GenericDefId::TraitId(id) => {
123123
let id = id.lookup(db).id;
124124
let tree = id.item_tree(db);
125125
let item = &tree[id.value];
126-
tree[item.generic_params].clone()
126+
item.generic_params.clone()
127127
}
128128
GenericDefId::TypeAliasId(id) => {
129129
let id = id.lookup(db).id;
130130
let tree = id.item_tree(db);
131131
let item = &tree[id.value];
132-
tree[item.generic_params].clone()
132+
item.generic_params.clone()
133133
}
134134
GenericDefId::ImplId(id) => {
135135
let id = id.lookup(db).id;
136136
let tree = id.item_tree(db);
137137
let item = &tree[id.value];
138-
tree[item.generic_params].clone()
138+
item.generic_params.clone()
139+
}
140+
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
141+
Interned::new(GenericParams::default())
139142
}
140-
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => GenericParams::default(),
141143
};
142-
Arc::new(generics)
144+
generics
143145
}
144146

145147
fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
@@ -217,6 +219,7 @@ impl GenericParams {
217219
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => FileId(!0).into(),
218220
};
219221

222+
generics.shrink_to_fit();
220223
(generics, InFile::new(file_id, sm))
221224
}
222225

@@ -256,7 +259,8 @@ impl GenericParams {
256259
for type_param in params.type_params() {
257260
let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
258261
// FIXME: Use `Path::from_src`
259-
let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it));
262+
let default =
263+
type_param.default_type().map(|it| Interned::new(TypeRef::from_ast(lower_ctx, it)));
260264
let param = TypeParamData {
261265
name: Some(name.clone()),
262266
default,
@@ -280,7 +284,7 @@ impl GenericParams {
280284
for const_param in params.const_params() {
281285
let name = const_param.name().map_or_else(Name::missing, |it| it.as_name());
282286
let ty = const_param.ty().map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it));
283-
let param = ConstParamData { name, ty };
287+
let param = ConstParamData { name, ty: Interned::new(ty) };
284288
let param_id = self.consts.alloc(param);
285289
sm.const_params.insert(param_id, const_param.clone());
286290
}
@@ -334,11 +338,11 @@ impl GenericParams {
334338
(Either::Left(type_ref), bound) => match hrtb_lifetimes {
335339
Some(hrtb_lifetimes) => WherePredicate::ForLifetime {
336340
lifetimes: hrtb_lifetimes.clone(),
337-
target: WherePredicateTypeTarget::TypeRef(type_ref),
341+
target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
338342
bound,
339343
},
340344
None => WherePredicate::TypeBound {
341-
target: WherePredicateTypeTarget::TypeRef(type_ref),
345+
target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
342346
bound,
343347
},
344348
},
@@ -369,6 +373,14 @@ impl GenericParams {
369373
});
370374
}
371375

376+
pub(crate) fn shrink_to_fit(&mut self) {
377+
let Self { consts, lifetimes, types, where_predicates } = self;
378+
consts.shrink_to_fit();
379+
lifetimes.shrink_to_fit();
380+
types.shrink_to_fit();
381+
where_predicates.shrink_to_fit();
382+
}
383+
372384
pub fn find_type_by_name(&self, name: &Name) -> Option<LocalTypeParamId> {
373385
self.types
374386
.iter()

crates/hir_def/src/intern.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use dashmap::{lock::RwLockWriteGuard, DashMap, SharedValue};
1414
use once_cell::sync::OnceCell;
1515
use rustc_hash::FxHasher;
1616

17+
use crate::generics::GenericParams;
18+
1719
type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
1820
type Guard<T> =
1921
RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>;
@@ -194,4 +196,10 @@ macro_rules! impl_internable {
194196
)+ };
195197
}
196198

197-
impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath, str);
199+
impl_internable!(
200+
crate::type_ref::TypeRef,
201+
crate::type_ref::TraitRef,
202+
crate::path::ModPath,
203+
GenericParams,
204+
str
205+
);

crates/hir_def/src/item_tree.rs

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,6 @@ impl fmt::Debug for RawVisibilityId {
5858
}
5959
}
6060

61-
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
62-
pub struct GenericParamsId(u32);
63-
64-
impl GenericParamsId {
65-
pub const EMPTY: Self = GenericParamsId(u32::max_value());
66-
}
67-
6861
/// The item tree of a source file.
6962
#[derive(Debug, Default, Eq, PartialEq)]
7063
pub struct ItemTree {
@@ -146,7 +139,6 @@ impl ItemTree {
146139
macro_rules,
147140
macro_defs,
148141
vis,
149-
generics,
150142
inner_items,
151143
} = &mut **data;
152144

@@ -170,7 +162,6 @@ impl ItemTree {
170162
macro_defs.shrink_to_fit();
171163

172164
vis.arena.shrink_to_fit();
173-
generics.arena.shrink_to_fit();
174165

175166
inner_items.shrink_to_fit();
176167
}
@@ -241,32 +232,6 @@ static VIS_PUB: RawVisibility = RawVisibility::Public;
241232
static VIS_PRIV: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Super(0)));
242233
static VIS_PUB_CRATE: RawVisibility = RawVisibility::Module(ModPath::from_kind(PathKind::Crate));
243234

244-
#[derive(Default, Debug, Eq, PartialEq)]
245-
struct GenericParamsStorage {
246-
arena: Arena<GenericParams>,
247-
}
248-
249-
impl GenericParamsStorage {
250-
fn alloc(&mut self, params: GenericParams) -> GenericParamsId {
251-
if params.types.is_empty()
252-
&& params.lifetimes.is_empty()
253-
&& params.consts.is_empty()
254-
&& params.where_predicates.is_empty()
255-
{
256-
return GenericParamsId::EMPTY;
257-
}
258-
259-
GenericParamsId(self.arena.alloc(params).into_raw().into())
260-
}
261-
}
262-
263-
static EMPTY_GENERICS: GenericParams = GenericParams {
264-
types: Arena::new(),
265-
lifetimes: Arena::new(),
266-
consts: Arena::new(),
267-
where_predicates: Vec::new(),
268-
};
269-
270235
#[derive(Default, Debug, Eq, PartialEq)]
271236
struct ItemTreeData {
272237
imports: Arena<Import>,
@@ -289,7 +254,6 @@ struct ItemTreeData {
289254
macro_defs: Arena<MacroDef>,
290255

291256
vis: ItemVisibilities,
292-
generics: GenericParamsStorage,
293257

294258
inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
295259
}
@@ -508,17 +472,6 @@ impl Index<RawVisibilityId> for ItemTree {
508472
}
509473
}
510474

511-
impl Index<GenericParamsId> for ItemTree {
512-
type Output = GenericParams;
513-
514-
fn index(&self, index: GenericParamsId) -> &Self::Output {
515-
match index {
516-
GenericParamsId::EMPTY => &EMPTY_GENERICS,
517-
_ => &self.data().generics.arena[Idx::from_raw(index.0.into())],
518-
}
519-
}
520-
}
521-
522475
impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
523476
type Output = N;
524477
fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -555,7 +508,7 @@ pub struct ExternCrate {
555508
pub struct Function {
556509
pub name: Name,
557510
pub visibility: RawVisibilityId,
558-
pub generic_params: GenericParamsId,
511+
pub generic_params: Interned<GenericParams>,
559512
pub abi: Option<Interned<str>>,
560513
pub params: IdRange<Param>,
561514
pub ret_type: Interned<TypeRef>,
@@ -590,7 +543,7 @@ impl FnFlags {
590543
pub struct Struct {
591544
pub name: Name,
592545
pub visibility: RawVisibilityId,
593-
pub generic_params: GenericParamsId,
546+
pub generic_params: Interned<GenericParams>,
594547
pub fields: Fields,
595548
pub ast_id: FileAstId<ast::Struct>,
596549
pub kind: StructDefKind,
@@ -610,7 +563,7 @@ pub enum StructDefKind {
610563
pub struct Union {
611564
pub name: Name,
612565
pub visibility: RawVisibilityId,
613-
pub generic_params: GenericParamsId,
566+
pub generic_params: Interned<GenericParams>,
614567
pub fields: Fields,
615568
pub ast_id: FileAstId<ast::Union>,
616569
}
@@ -619,7 +572,7 @@ pub struct Union {
619572
pub struct Enum {
620573
pub name: Name,
621574
pub visibility: RawVisibilityId,
622-
pub generic_params: GenericParamsId,
575+
pub generic_params: Interned<GenericParams>,
623576
pub variants: IdRange<Variant>,
624577
pub ast_id: FileAstId<ast::Enum>,
625578
}
@@ -648,7 +601,7 @@ pub struct Static {
648601
pub struct Trait {
649602
pub name: Name,
650603
pub visibility: RawVisibilityId,
651-
pub generic_params: GenericParamsId,
604+
pub generic_params: Interned<GenericParams>,
652605
pub is_auto: bool,
653606
pub is_unsafe: bool,
654607
pub bounds: Box<[TypeBound]>,
@@ -658,7 +611,7 @@ pub struct Trait {
658611

659612
#[derive(Debug, Clone, Eq, PartialEq)]
660613
pub struct Impl {
661-
pub generic_params: GenericParamsId,
614+
pub generic_params: Interned<GenericParams>,
662615
pub target_trait: Option<Interned<TraitRef>>,
663616
pub self_ty: Interned<TypeRef>,
664617
pub is_negative: bool,
@@ -672,7 +625,7 @@ pub struct TypeAlias {
672625
pub visibility: RawVisibilityId,
673626
/// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
674627
pub bounds: Box<[TypeBound]>,
675-
pub generic_params: GenericParamsId,
628+
pub generic_params: Interned<GenericParams>,
676629
pub type_ref: Option<Interned<TypeRef>>,
677630
pub is_extern: bool,
678631
pub ast_id: FileAstId<ast::TypeAlias>,

0 commit comments

Comments
 (0)