Skip to content

Commit f4d5698

Browse files
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 <jonasschievink@gmail.com>
2 parents 9bcdbef + 6e227b8 commit f4d5698

File tree

15 files changed

+230
-136
lines changed

15 files changed

+230
-136
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir/src/display.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl HirDisplay for Function {
9191
let ret_type = if !qual.is_async {
9292
&data.ret_type
9393
} else {
94-
match &data.ret_type {
94+
match &*data.ret_type {
9595
TypeRef::ImplTrait(bounds) => match &bounds[0] {
9696
TypeBound::Path(path) => {
9797
path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings

crates/hir/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ impl SelfParam {
957957
func_data
958958
.params
959959
.first()
960-
.map(|param| match *param {
960+
.map(|param| match &**param {
961961
TypeRef::Reference(.., mutability) => match mutability {
962962
hir_def::type_ref::Mutability::Shared => Access::Shared,
963963
hir_def::type_ref::Mutability::Mut => Access::Exclusive,
@@ -1011,7 +1011,7 @@ impl Const {
10111011
}
10121012

10131013
pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef {
1014-
db.const_data(self.id).type_ref.clone()
1014+
db.const_data(self.id).type_ref.as_ref().clone()
10151015
}
10161016
}
10171017

@@ -1101,7 +1101,7 @@ impl TypeAlias {
11011101
}
11021102

11031103
pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1104-
db.type_alias_data(self.id).type_ref.clone()
1104+
db.type_alias_data(self.id).type_ref.as_deref().cloned()
11051105
}
11061106

11071107
pub fn ty(self, db: &dyn HirDatabase) -> Type {
@@ -1615,7 +1615,7 @@ impl Impl {
16151615
// FIXME: the return type is wrong. This should be a hir version of
16161616
// `TraitRef` (ie, resolved `TypeRef`).
16171617
pub fn trait_(self, db: &dyn HirDatabase) -> Option<TraitRef> {
1618-
db.impl_data(self.id).target_trait.clone()
1618+
db.impl_data(self.id).target_trait.as_deref().cloned()
16191619
}
16201620

16211621
pub fn self_ty(self, db: &dyn HirDatabase) -> Type {

crates/hir_def/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ doctest = false
1111

1212
[dependencies]
1313
cov-mark = { version = "1.1", features = ["thread-local"] }
14+
dashmap = { version = "4.0.2", features = ["raw-api"] }
1415
log = "0.4.8"
1516
once_cell = "1.3.1"
1617
rustc-hash = "1.1.0"

crates/hir_def/src/adt.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
1515
use crate::{
1616
body::{CfgExpander, LowerCtx},
1717
db::DefDatabase,
18+
intern::Interned,
1819
item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem, RawVisibilityId},
1920
src::HasChildSource,
2021
src::HasSource,
@@ -58,7 +59,7 @@ pub enum VariantData {
5859
#[derive(Debug, Clone, PartialEq, Eq)]
5960
pub struct FieldData {
6061
pub name: Name,
61-
pub type_ref: TypeRef,
62+
pub type_ref: Interned<TypeRef>,
6263
pub visibility: RawVisibility,
6364
}
6465

@@ -292,7 +293,7 @@ fn lower_struct(
292293
|| Either::Left(fd.clone()),
293294
|| FieldData {
294295
name: Name::new_tuple_field(i),
295-
type_ref: TypeRef::from_ast_opt(&ctx, fd.ty()),
296+
type_ref: Interned::new(TypeRef::from_ast_opt(&ctx, fd.ty())),
296297
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
297298
},
298299
);
@@ -309,7 +310,7 @@ fn lower_struct(
309310
|| Either::Right(fd.clone()),
310311
|| FieldData {
311312
name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
312-
type_ref: TypeRef::from_ast_opt(&ctx, fd.ty()),
313+
type_ref: Interned::new(TypeRef::from_ast_opt(&ctx, fd.ty())),
313314
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
314315
},
315316
);
@@ -358,7 +359,7 @@ fn lower_field(
358359
) -> FieldData {
359360
FieldData {
360361
name: field.name.clone(),
361-
type_ref: item_tree[field.type_ref].clone(),
362+
type_ref: field.type_ref.clone(),
362363
visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
363364
}
364365
}

crates/hir_def/src/attr.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use tt::Subtree;
1818

1919
use crate::{
2020
db::DefDatabase,
21+
intern::Interned,
2122
item_tree::{ItemTreeId, ItemTreeNode},
2223
nameres::ModuleSource,
2324
path::{ModPath, PathKind},
@@ -98,7 +99,7 @@ impl RawAttrs {
9899
Either::Right(comment) => comment.doc_comment().map(|doc| Attr {
99100
index: i as u32,
100101
input: Some(AttrInput::Literal(SmolStr::new(doc))),
101-
path: ModPath::from(hir_expand::name!(doc)),
102+
path: Interned::new(ModPath::from(hir_expand::name!(doc))),
102103
}),
103104
})
104105
.collect::<Arc<_>>();
@@ -510,7 +511,7 @@ impl AttrSourceMap {
510511
#[derive(Debug, Clone, PartialEq, Eq)]
511512
pub struct Attr {
512513
index: u32,
513-
pub(crate) path: ModPath,
514+
pub(crate) path: Interned<ModPath>,
514515
pub(crate) input: Option<AttrInput>,
515516
}
516517

@@ -524,7 +525,7 @@ pub enum AttrInput {
524525

525526
impl Attr {
526527
fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> {
527-
let path = ModPath::from_src(ast.path()?, hygiene)?;
528+
let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?);
528529
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
529530
let value = match lit.kind() {
530531
ast::LiteralKind::String(string) => string.value()?.into(),

crates/hir_def/src/data.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::{
99
attr::Attrs,
1010
body::Expander,
1111
db::DefDatabase,
12+
intern::Interned,
1213
item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param},
1314
type_ref::{TraitRef, TypeBound, TypeRef},
1415
visibility::RawVisibility,
@@ -19,8 +20,8 @@ use crate::{
1920
#[derive(Debug, Clone, PartialEq, Eq)]
2021
pub struct FunctionData {
2122
pub name: Name,
22-
pub params: Vec<TypeRef>,
23-
pub ret_type: TypeRef,
23+
pub params: Vec<Interned<TypeRef>>,
24+
pub ret_type: Interned<TypeRef>,
2425
pub attrs: Attrs,
2526
/// True if the first param is `self`. This is relevant to decide whether this
2627
/// can be called as a method.
@@ -57,11 +58,11 @@ impl FunctionData {
5758
params: enabled_params
5859
.clone()
5960
.filter_map(|id| match &item_tree[id] {
60-
Param::Normal(ty) => Some(item_tree[*ty].clone()),
61+
Param::Normal(ty) => Some(ty.clone()),
6162
Param::Varargs => None,
6263
})
6364
.collect(),
64-
ret_type: item_tree[func.ret_type].clone(),
65+
ret_type: func.ret_type.clone(),
6566
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
6667
has_self_param: func.has_self_param,
6768
has_body: func.has_body,
@@ -76,7 +77,7 @@ impl FunctionData {
7677
#[derive(Debug, Clone, PartialEq, Eq)]
7778
pub struct TypeAliasData {
7879
pub name: Name,
79-
pub type_ref: Option<TypeRef>,
80+
pub type_ref: Option<Interned<TypeRef>>,
8081
pub visibility: RawVisibility,
8182
pub is_extern: bool,
8283
/// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl).
@@ -94,7 +95,7 @@ impl TypeAliasData {
9495

9596
Arc::new(TypeAliasData {
9697
name: typ.name.clone(),
97-
type_ref: typ.type_ref.map(|id| item_tree[id].clone()),
98+
type_ref: typ.type_ref.clone(),
9899
visibility: item_tree[typ.visibility].clone(),
99100
is_extern: typ.is_extern,
100101
bounds: typ.bounds.to_vec(),
@@ -156,8 +157,8 @@ impl TraitData {
156157

157158
#[derive(Debug, Clone, PartialEq, Eq)]
158159
pub struct ImplData {
159-
pub target_trait: Option<TraitRef>,
160-
pub self_ty: TypeRef,
160+
pub target_trait: Option<Interned<TraitRef>>,
161+
pub self_ty: Interned<TypeRef>,
161162
pub items: Vec<AssocItemId>,
162163
pub is_negative: bool,
163164
}
@@ -169,8 +170,8 @@ impl ImplData {
169170

170171
let item_tree = impl_loc.id.item_tree(db);
171172
let impl_def = &item_tree[impl_loc.id.value];
172-
let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone());
173-
let self_ty = item_tree[impl_def.self_ty].clone();
173+
let target_trait = impl_def.target_trait.clone();
174+
let self_ty = impl_def.self_ty.clone();
174175
let is_negative = impl_def.is_negative;
175176
let module_id = impl_loc.container;
176177
let container = AssocContainerId::ImplId(id);
@@ -195,7 +196,7 @@ impl ImplData {
195196
pub struct ConstData {
196197
/// const _: () = ();
197198
pub name: Option<Name>,
198-
pub type_ref: TypeRef,
199+
pub type_ref: Interned<TypeRef>,
199200
pub visibility: RawVisibility,
200201
}
201202

@@ -207,7 +208,7 @@ impl ConstData {
207208

208209
Arc::new(ConstData {
209210
name: konst.name.clone(),
210-
type_ref: item_tree[konst.type_ref].clone(),
211+
type_ref: konst.type_ref.clone(),
211212
visibility: item_tree[konst.visibility].clone(),
212213
})
213214
}
@@ -216,7 +217,7 @@ impl ConstData {
216217
#[derive(Debug, Clone, PartialEq, Eq)]
217218
pub struct StaticData {
218219
pub name: Option<Name>,
219-
pub type_ref: TypeRef,
220+
pub type_ref: Interned<TypeRef>,
220221
pub visibility: RawVisibility,
221222
pub mutable: bool,
222223
pub is_extern: bool,
@@ -230,7 +231,7 @@ impl StaticData {
230231

231232
Arc::new(StaticData {
232233
name: Some(statik.name.clone()),
233-
type_ref: item_tree[statik.type_ref].clone(),
234+
type_ref: statik.type_ref.clone(),
234235
visibility: item_tree[statik.visibility].clone(),
235236
mutable: statik.mutable,
236237
is_extern: statik.is_extern,

0 commit comments

Comments
 (0)