aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-02 17:43:16 +0100
committerGitHub <[email protected]>2021-04-02 17:43:16 +0100
commitf4d56989b657b15aec6675cf1ba697e3f87eb088 (patch)
tree23e4d8265444257f2e4018a003659a711fde0414 /crates/hir_def/src/item_tree.rs
parent9bcdbefc7b657f34704439d068113180b14359dc (diff)
parent6e227b80a7686a7ea5bc039d54c307fda29c99ba (diff)
Merge #8284
8284: Reduce memory usage by using global `Arc`-based interning r=jonas-schievink a=jonas-schievink This saves around 50 mb when running `analysis-stats` on r-a itself. Not a lot, but this infra can be easily reused to intern more stuff. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r--crates/hir_def/src/item_tree.rs94
1 files changed, 10 insertions, 84 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 5449bbf5d..69a313c7e 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -30,6 +30,7 @@ use crate::{
30 attr::{Attrs, RawAttrs}, 30 attr::{Attrs, RawAttrs},
31 db::DefDatabase, 31 db::DefDatabase,
32 generics::GenericParams, 32 generics::GenericParams,
33 intern::Interned,
33 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, 34 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
34 type_ref::{Mutability, TraitRef, TypeBound, TypeRef}, 35 type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
35 visibility::RawVisibility, 36 visibility::RawVisibility,
@@ -146,8 +147,6 @@ impl ItemTree {
146 macro_defs, 147 macro_defs,
147 vis, 148 vis,
148 generics, 149 generics,
149 type_refs,
150 trait_refs,
151 inner_items, 150 inner_items,
152 } = &mut **data; 151 } = &mut **data;
153 152
@@ -172,9 +171,6 @@ impl ItemTree {
172 171
173 vis.arena.shrink_to_fit(); 172 vis.arena.shrink_to_fit();
174 generics.arena.shrink_to_fit(); 173 generics.arena.shrink_to_fit();
175 type_refs.arena.shrink_to_fit();
176 type_refs.map.shrink_to_fit();
177 trait_refs.map.shrink_to_fit();
178 174
179 inner_items.shrink_to_fit(); 175 inner_items.shrink_to_fit();
180 } 176 }
@@ -271,58 +267,6 @@ static EMPTY_GENERICS: GenericParams = GenericParams {
271 where_predicates: Vec::new(), 267 where_predicates: Vec::new(),
272}; 268};
273 269
274/// `TypeRef` interner.
275#[derive(Default, Debug, Eq, PartialEq)]
276struct TypeRefStorage {
277 arena: Arena<Arc<TypeRef>>,
278 map: FxHashMap<Arc<TypeRef>, Idx<Arc<TypeRef>>>,
279}
280
281impl TypeRefStorage {
282 // Note: We lie about the `Idx<TypeRef>` to hide the interner details.
283
284 fn intern(&mut self, ty: TypeRef) -> Idx<TypeRef> {
285 if let Some(id) = self.map.get(&ty) {
286 return Idx::from_raw(id.into_raw());
287 }
288
289 let ty = Arc::new(ty);
290 let idx = self.arena.alloc(ty.clone());
291 self.map.insert(ty, idx);
292 Idx::from_raw(idx.into_raw())
293 }
294
295 fn lookup(&self, id: Idx<TypeRef>) -> &TypeRef {
296 &self.arena[Idx::from_raw(id.into_raw())]
297 }
298}
299
300/// `TraitRef` interner.
301#[derive(Default, Debug, Eq, PartialEq)]
302struct TraitRefStorage {
303 arena: Arena<Arc<TraitRef>>,
304 map: FxHashMap<Arc<TraitRef>, Idx<Arc<TraitRef>>>,
305}
306
307impl TraitRefStorage {
308 // Note: We lie about the `Idx<TraitRef>` to hide the interner details.
309
310 fn intern(&mut self, ty: TraitRef) -> Idx<TraitRef> {
311 if let Some(id) = self.map.get(&ty) {
312 return Idx::from_raw(id.into_raw());
313 }
314
315 let ty = Arc::new(ty);
316 let idx = self.arena.alloc(ty.clone());
317 self.map.insert(ty, idx);
318 Idx::from_raw(idx.into_raw())
319 }
320
321 fn lookup(&self, id: Idx<TraitRef>) -> &TraitRef {
322 &self.arena[Idx::from_raw(id.into_raw())]
323 }
324}
325
326#[derive(Default, Debug, Eq, PartialEq)] 270#[derive(Default, Debug, Eq, PartialEq)]
327struct ItemTreeData { 271struct ItemTreeData {
328 imports: Arena<Import>, 272 imports: Arena<Import>,
@@ -346,8 +290,6 @@ struct ItemTreeData {
346 290
347 vis: ItemVisibilities, 291 vis: ItemVisibilities,
348 generics: GenericParamsStorage, 292 generics: GenericParamsStorage,
349 type_refs: TypeRefStorage,
350 trait_refs: TraitRefStorage,
351 293
352 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, 294 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
353} 295}
@@ -577,22 +519,6 @@ impl Index<GenericParamsId> for ItemTree {
577 } 519 }
578} 520}
579 521
580impl Index<Idx<TypeRef>> for ItemTree {
581 type Output = TypeRef;
582
583 fn index(&self, id: Idx<TypeRef>) -> &Self::Output {
584 self.data().type_refs.lookup(id)
585 }
586}
587
588impl Index<Idx<TraitRef>> for ItemTree {
589 type Output = TraitRef;
590
591 fn index(&self, id: Idx<TraitRef>) -> &Self::Output {
592 self.data().trait_refs.lookup(id)
593 }
594}
595
596impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { 522impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
597 type Output = N; 523 type Output = N;
598 fn index(&self, id: FileItemTreeId<N>) -> &N { 524 fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -637,13 +563,13 @@ pub struct Function {
637 /// `extern "abi" fn`). 563 /// `extern "abi" fn`).
638 pub is_in_extern_block: bool, 564 pub is_in_extern_block: bool,
639 pub params: IdRange<Param>, 565 pub params: IdRange<Param>,
640 pub ret_type: Idx<TypeRef>, 566 pub ret_type: Interned<TypeRef>,
641 pub ast_id: FileAstId<ast::Fn>, 567 pub ast_id: FileAstId<ast::Fn>,
642} 568}
643 569
644#[derive(Debug, Clone, Eq, PartialEq)] 570#[derive(Debug, Clone, Eq, PartialEq)]
645pub enum Param { 571pub enum Param {
646 Normal(Idx<TypeRef>), 572 Normal(Interned<TypeRef>),
647 Varargs, 573 Varargs,
648} 574}
649 575
@@ -699,7 +625,7 @@ pub struct Const {
699 /// const _: () = (); 625 /// const _: () = ();
700 pub name: Option<Name>, 626 pub name: Option<Name>,
701 pub visibility: RawVisibilityId, 627 pub visibility: RawVisibilityId,
702 pub type_ref: Idx<TypeRef>, 628 pub type_ref: Interned<TypeRef>,
703 pub ast_id: FileAstId<ast::Const>, 629 pub ast_id: FileAstId<ast::Const>,
704} 630}
705 631
@@ -710,7 +636,7 @@ pub struct Static {
710 pub mutable: bool, 636 pub mutable: bool,
711 /// Whether the static is in an `extern` block. 637 /// Whether the static is in an `extern` block.
712 pub is_extern: bool, 638 pub is_extern: bool,
713 pub type_ref: Idx<TypeRef>, 639 pub type_ref: Interned<TypeRef>,
714 pub ast_id: FileAstId<ast::Static>, 640 pub ast_id: FileAstId<ast::Static>,
715} 641}
716 642
@@ -729,8 +655,8 @@ pub struct Trait {
729#[derive(Debug, Clone, Eq, PartialEq)] 655#[derive(Debug, Clone, Eq, PartialEq)]
730pub struct Impl { 656pub struct Impl {
731 pub generic_params: GenericParamsId, 657 pub generic_params: GenericParamsId,
732 pub target_trait: Option<Idx<TraitRef>>, 658 pub target_trait: Option<Interned<TraitRef>>,
733 pub self_ty: Idx<TypeRef>, 659 pub self_ty: Interned<TypeRef>,
734 pub is_negative: bool, 660 pub is_negative: bool,
735 pub items: Box<[AssocItem]>, 661 pub items: Box<[AssocItem]>,
736 pub ast_id: FileAstId<ast::Impl>, 662 pub ast_id: FileAstId<ast::Impl>,
@@ -743,7 +669,7 @@ pub struct TypeAlias {
743 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. 669 /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`.
744 pub bounds: Box<[TypeBound]>, 670 pub bounds: Box<[TypeBound]>,
745 pub generic_params: GenericParamsId, 671 pub generic_params: GenericParamsId,
746 pub type_ref: Option<Idx<TypeRef>>, 672 pub type_ref: Option<Interned<TypeRef>>,
747 pub is_extern: bool, 673 pub is_extern: bool,
748 pub ast_id: FileAstId<ast::TypeAlias>, 674 pub ast_id: FileAstId<ast::TypeAlias>,
749} 675}
@@ -768,7 +694,7 @@ pub enum ModKind {
768#[derive(Debug, Clone, Eq, PartialEq)] 694#[derive(Debug, Clone, Eq, PartialEq)]
769pub struct MacroCall { 695pub struct MacroCall {
770 /// Path to the called macro. 696 /// Path to the called macro.
771 pub path: ModPath, 697 pub path: Interned<ModPath>,
772 pub ast_id: FileAstId<ast::MacroCall>, 698 pub ast_id: FileAstId<ast::MacroCall>,
773} 699}
774 700
@@ -933,6 +859,6 @@ pub enum Fields {
933#[derive(Debug, Clone, PartialEq, Eq)] 859#[derive(Debug, Clone, PartialEq, Eq)]
934pub struct Field { 860pub struct Field {
935 pub name: Name, 861 pub name: Name,
936 pub type_ref: Idx<TypeRef>, 862 pub type_ref: Interned<TypeRef>,
937 pub visibility: RawVisibilityId, 863 pub visibility: RawVisibilityId,
938} 864}