Skip to content

Commit 7d39b13

Browse files
bors[bot]alexmaco
andauthored
Merge #8364
8364: Memory usage improvements r=jonas-schievink a=alexmaco These are mostly focused on splitting up enum variants with large size differences between variants by `Box`-ing things up. In my testing this reduces the memory usage somewhere in the low percentages, even though the measurements are quite noisy. Co-authored-by: Alexandru Macovei <[email protected]>
2 parents 12e8643 + 4e2a6ac commit 7d39b13

File tree

8 files changed

+54
-33
lines changed

8 files changed

+54
-33
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir_def/src/body/lower.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,10 @@ impl ExprCollector<'_> {
322322
Vec::new()
323323
};
324324
let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing);
325-
let generic_args =
326-
e.generic_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it));
325+
let generic_args = e
326+
.generic_arg_list()
327+
.and_then(|it| GenericArgs::from_ast(&self.ctx(), it))
328+
.map(Box::new);
327329
self.alloc_expr(
328330
Expr::MethodCall { receiver, method_name, args, generic_args },
329331
syntax_ptr,
@@ -385,7 +387,7 @@ impl ExprCollector<'_> {
385387
self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
386388
}
387389
ast::Expr::RecordExpr(e) => {
388-
let path = e.path().and_then(|path| self.expander.parse_path(path));
390+
let path = e.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
389391
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
390392
let fields = nfl
391393
.fields()
@@ -430,7 +432,7 @@ impl ExprCollector<'_> {
430432
}
431433
ast::Expr::CastExpr(e) => {
432434
let expr = self.collect_expr_opt(e.expr());
433-
let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.ty());
435+
let type_ref = Box::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
434436
self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
435437
}
436438
ast::Expr::RefExpr(e) => {
@@ -469,8 +471,10 @@ impl ExprCollector<'_> {
469471
arg_types.push(type_ref);
470472
}
471473
}
472-
let ret_type =
473-
e.ret_type().and_then(|r| r.ty()).map(|it| TypeRef::from_ast(&self.ctx(), it));
474+
let ret_type = e
475+
.ret_type()
476+
.and_then(|r| r.ty())
477+
.map(|it| Box::new(TypeRef::from_ast(&self.ctx(), it)));
474478
let body = self.collect_expr_opt(e.body());
475479
self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
476480
}
@@ -755,7 +759,7 @@ impl ExprCollector<'_> {
755759
}
756760
}
757761
ast::Pat::TupleStructPat(p) => {
758-
let path = p.path().and_then(|path| self.expander.parse_path(path));
762+
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
759763
let (args, ellipsis) = self.collect_tuple_pat(p.fields());
760764
Pat::TupleStruct { path, args, ellipsis }
761765
}
@@ -765,7 +769,7 @@ impl ExprCollector<'_> {
765769
Pat::Ref { pat, mutability }
766770
}
767771
ast::Pat::PathPat(p) => {
768-
let path = p.path().and_then(|path| self.expander.parse_path(path));
772+
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
769773
path.map(Pat::Path).unwrap_or(Pat::Missing)
770774
}
771775
ast::Pat::OrPat(p) => {
@@ -779,7 +783,7 @@ impl ExprCollector<'_> {
779783
}
780784
ast::Pat::WildcardPat(_) => Pat::Wild,
781785
ast::Pat::RecordPat(p) => {
782-
let path = p.path().and_then(|path| self.expander.parse_path(path));
786+
let path = p.path().and_then(|path| self.expander.parse_path(path)).map(Box::new);
783787
let args: Vec<_> = p
784788
.record_pat_field_list()
785789
.expect("every struct should have a field list")

crates/hir_def/src/expr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub enum Expr {
8686
receiver: ExprId,
8787
method_name: Name,
8888
args: Vec<ExprId>,
89-
generic_args: Option<GenericArgs>,
89+
generic_args: Option<Box<GenericArgs>>,
9090
},
9191
Match {
9292
expr: ExprId,
@@ -106,7 +106,7 @@ pub enum Expr {
106106
expr: Option<ExprId>,
107107
},
108108
RecordLit {
109-
path: Option<Path>,
109+
path: Option<Box<Path>>,
110110
fields: Vec<RecordLitField>,
111111
spread: Option<ExprId>,
112112
},
@@ -131,7 +131,7 @@ pub enum Expr {
131131
},
132132
Cast {
133133
expr: ExprId,
134-
type_ref: TypeRef,
134+
type_ref: Box<TypeRef>,
135135
},
136136
Ref {
137137
expr: ExprId,
@@ -162,7 +162,7 @@ pub enum Expr {
162162
Lambda {
163163
args: Vec<PatId>,
164164
arg_types: Vec<Option<TypeRef>>,
165-
ret_type: Option<TypeRef>,
165+
ret_type: Option<Box<TypeRef>>,
166166
body: ExprId,
167167
},
168168
Tuple {
@@ -412,13 +412,13 @@ pub enum Pat {
412412
Wild,
413413
Tuple { args: Vec<PatId>, ellipsis: Option<usize> },
414414
Or(Vec<PatId>),
415-
Record { path: Option<Path>, args: Vec<RecordFieldPat>, ellipsis: bool },
415+
Record { path: Option<Box<Path>>, args: Vec<RecordFieldPat>, ellipsis: bool },
416416
Range { start: ExprId, end: ExprId },
417417
Slice { prefix: Vec<PatId>, slice: Option<PatId>, suffix: Vec<PatId> },
418-
Path(Path),
418+
Path(Box<Path>),
419419
Lit(ExprId),
420420
Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> },
421-
TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
421+
TupleStruct { path: Option<Box<Path>>, args: Vec<PatId>, ellipsis: Option<usize> },
422422
Ref { pat: PatId, mutability: Mutability },
423423
Box { inner: PatId },
424424
ConstBlock(ExprId),

crates/hir_def/src/path.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ impl From<Name> for Path {
289289
}
290290
}
291291

292+
impl From<Name> for Box<Path> {
293+
fn from(name: Name) -> Box<Path> {
294+
Box::new(Path::from(name))
295+
}
296+
}
297+
292298
impl From<Name> for ModPath {
293299
fn from(name: Name) -> ModPath {
294300
ModPath::from_segments(PathKind::Plain, iter::once(name))

crates/hir_ty/src/infer/expr.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,13 @@ impl<'a> InferenceContext<'a> {
318318
self.normalize_associated_types_in(ret_ty)
319319
}
320320
Expr::MethodCall { receiver, args, method_name, generic_args } => self
321-
.infer_method_call(tgt_expr, *receiver, &args, &method_name, generic_args.as_ref()),
321+
.infer_method_call(
322+
tgt_expr,
323+
*receiver,
324+
&args,
325+
&method_name,
326+
generic_args.as_deref(),
327+
),
322328
Expr::Match { expr, arms } => {
323329
let input_ty = self.infer_expr(*expr, &Expectation::none());
324330

@@ -399,7 +405,7 @@ impl<'a> InferenceContext<'a> {
399405
TyKind::Never.intern(&Interner)
400406
}
401407
Expr::RecordLit { path, fields, spread } => {
402-
let (ty, def_id) = self.resolve_variant(path.as_ref());
408+
let (ty, def_id) = self.resolve_variant(path.as_deref());
403409
if let Some(variant) = def_id {
404410
self.write_variant_resolution(tgt_expr.into(), variant);
405411
}

crates/hir_ty/src/infer/pat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,15 @@ impl<'a> InferenceContext<'a> {
174174
TyKind::Ref(mutability, static_lifetime(), subty).intern(&Interner)
175175
}
176176
Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
177-
p.as_ref(),
177+
p.as_deref(),
178178
subpats,
179179
expected,
180180
default_bm,
181181
pat,
182182
*ellipsis,
183183
),
184184
Pat::Record { path: p, args: fields, ellipsis: _ } => {
185-
self.infer_record_pat(p.as_ref(), fields, expected, default_bm, pat)
185+
self.infer_record_pat(p.as_deref(), fields, expected, default_bm, pat)
186186
}
187187
Pat::Path(path) => {
188188
// FIXME use correct resolver for the surrounding expression

crates/vfs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ rustc-hash = "1.0"
1414
fst = "0.4"
1515

1616
paths = { path = "../paths", version = "0.0.0" }
17+
indexmap = "1.6.2"

crates/vfs/src/path_interner.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
//! Maps paths to compact integer ids. We don't care about clearings paths which
22
//! no longer exist -- the assumption is total size of paths we ever look at is
33
//! not too big.
4-
use rustc_hash::FxHashMap;
4+
use std::hash::BuildHasherDefault;
5+
6+
use indexmap::IndexSet;
7+
use rustc_hash::FxHasher;
58

69
use crate::{FileId, VfsPath};
710

811
/// Structure to map between [`VfsPath`] and [`FileId`].
9-
#[derive(Default)]
1012
pub(crate) struct PathInterner {
11-
map: FxHashMap<VfsPath, FileId>,
12-
vec: Vec<VfsPath>,
13+
map: IndexSet<VfsPath, BuildHasherDefault<FxHasher>>,
14+
}
15+
16+
impl Default for PathInterner {
17+
fn default() -> Self {
18+
Self { map: IndexSet::default() }
19+
}
1320
}
1421

1522
impl PathInterner {
1623
/// Get the id corresponding to `path`.
1724
///
1825
/// If `path` does not exists in `self`, returns [`None`].
1926
pub(crate) fn get(&self, path: &VfsPath) -> Option<FileId> {
20-
self.map.get(path).copied()
27+
self.map.get_index_of(path).map(|i| FileId(i as u32))
2128
}
2229

2330
/// Insert `path` in `self`.
2431
///
2532
/// - If `path` already exists in `self`, returns its associated id;
2633
/// - Else, returns a newly allocated id.
2734
pub(crate) fn intern(&mut self, path: VfsPath) -> FileId {
28-
if let Some(id) = self.get(&path) {
29-
return id;
30-
}
31-
let id = FileId(self.vec.len() as u32);
32-
self.map.insert(path.clone(), id);
33-
self.vec.push(path);
34-
id
35+
let (id, _added) = self.map.insert_full(path);
36+
assert!(id < u32::MAX as usize);
37+
FileId(id as u32)
3538
}
3639

3740
/// Returns the path corresponding to `id`.
@@ -40,6 +43,6 @@ impl PathInterner {
4043
///
4144
/// Panics if `id` does not exists in `self`.
4245
pub(crate) fn lookup(&self, id: FileId) -> &VfsPath {
43-
&self.vec[id.0 as usize]
46+
self.map.get_index(id.0 as usize).unwrap()
4447
}
4548
}

0 commit comments

Comments
 (0)