diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-04 18:33:57 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-04 18:33:57 +0000 |
commit | 36191543a679d4e01c206d2e98a2d7ae170a25e2 (patch) | |
tree | 91431506bde2965c819030eea14433926b82310f /crates/hir_def/src/item_tree | |
parent | 663d404a4ee52cf96e0de793e45290be1a43dcb5 (diff) | |
parent | 003ee0086ae424ec43ad14cd90af9cd5809a93c8 (diff) |
Merge #7557
7557: Intern `TypeRef`s in the containing `ItemTree` r=jonas-schievink a=jonas-schievink
This reduces the memory used by `ItemTreeQuery` by ~20%. As it turns out, `TypeRef` is very heavy, and is used a lot in `ItemTree`:
* Many types are frequently repeated throughout the same file. This is what this PR addresses by storing identical `TypeRef`s only once per `ItemTree`.
* The vast majority of `TypeRef` consist of a plain path with only a single element. "Type anchors" like in `<Ty>::func` are used incredibly rarely, and even multi-segment paths are much rarer than single-segment paths.
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index de2177933..93cdca55d 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -364,6 +364,7 @@ impl Ctx { | |||
364 | params.push(type_ref); | 364 | params.push(type_ref); |
365 | } | 365 | } |
366 | } | 366 | } |
367 | let params = params.into_iter().map(|param| self.data().type_refs.intern(param)).collect(); | ||
367 | 368 | ||
368 | let mut is_varargs = false; | 369 | let mut is_varargs = false; |
369 | if let Some(params) = func.param_list() { | 370 | if let Some(params) = func.param_list() { |
@@ -385,6 +386,8 @@ impl Ctx { | |||
385 | ret_type | 386 | ret_type |
386 | }; | 387 | }; |
387 | 388 | ||
389 | let ret_type = self.data().type_refs.intern(ret_type); | ||
390 | |||
388 | let has_body = func.body().is_some(); | 391 | let has_body = func.body().is_some(); |
389 | 392 | ||
390 | let ast_id = self.source_ast_id_map.ast_id(func); | 393 | let ast_id = self.source_ast_id_map.ast_id(func); |
@@ -396,7 +399,7 @@ impl Ctx { | |||
396 | has_body, | 399 | has_body, |
397 | is_unsafe: func.unsafe_token().is_some(), | 400 | is_unsafe: func.unsafe_token().is_some(), |
398 | is_extern: false, | 401 | is_extern: false, |
399 | params: params.into_boxed_slice(), | 402 | params, |
400 | is_varargs, | 403 | is_varargs, |
401 | ret_type, | 404 | ret_type, |
402 | ast_id, | 405 | ast_id, |
@@ -657,6 +660,7 @@ impl Ctx { | |||
657 | generics.fill(&self.body_ctx, sm, node); | 660 | generics.fill(&self.body_ctx, sm, node); |
658 | // lower `impl Trait` in arguments | 661 | // lower `impl Trait` in arguments |
659 | for param in &*func.params { | 662 | for param in &*func.params { |
663 | let param = self.data().type_refs.lookup(*param); | ||
660 | generics.fill_implicit_impl_trait_args(param); | 664 | generics.fill_implicit_impl_trait_args(param); |
661 | } | 665 | } |
662 | } | 666 | } |
@@ -709,11 +713,15 @@ impl Ctx { | |||
709 | self.data().vis.alloc(vis) | 713 | self.data().vis.alloc(vis) |
710 | } | 714 | } |
711 | 715 | ||
712 | fn lower_type_ref(&self, type_ref: &ast::Type) -> TypeRef { | 716 | fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> { |
713 | TypeRef::from_ast(&self.body_ctx, type_ref.clone()) | 717 | let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone()); |
718 | self.data().type_refs.intern(tyref) | ||
714 | } | 719 | } |
715 | fn lower_type_ref_opt(&self, type_ref: Option<ast::Type>) -> TypeRef { | 720 | fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> { |
716 | type_ref.map(|ty| self.lower_type_ref(&ty)).unwrap_or(TypeRef::Error) | 721 | match type_ref.map(|ty| self.lower_type_ref(&ty)) { |
722 | Some(it) => it, | ||
723 | None => self.data().type_refs.intern(TypeRef::Error), | ||
724 | } | ||
717 | } | 725 | } |
718 | 726 | ||
719 | /// Forces the visibility `vis` to be used for all items lowered during execution of `f`. | 727 | /// Forces the visibility `vis` to be used for all items lowered during execution of `f`. |