Skip to content

Commit 4b29a9d

Browse files
Merge pull request #20219 from ChayimFriedman2/expr-store-mem
perf: Put the expression stuff in the expression store behind an `Option<Box>`
2 parents eaeee0b + ad708fd commit 4b29a9d

File tree

28 files changed

+419
-271
lines changed

28 files changed

+419
-271
lines changed

crates/hir-def/src/expr_store.rs

Lines changed: 285 additions & 120 deletions
Large diffs are not rendered by default.

crates/hir-def/src/expr_store/body.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct Body {
3636
impl ops::Deref for Body {
3737
type Target = ExpressionStore;
3838

39+
#[inline]
3940
fn deref(&self) -> &Self::Target {
4041
&self.store
4142
}
@@ -61,6 +62,7 @@ pub struct BodySourceMap {
6162
impl ops::Deref for BodySourceMap {
6263
type Target = ExpressionStoreSourceMap;
6364

65+
#[inline]
6466
fn deref(&self) -> &Self::Target {
6567
&self.store
6668
}
@@ -102,9 +104,7 @@ impl Body {
102104
}
103105
};
104106
let module = def.module(db);
105-
let (body, mut source_map) =
106-
lower_body(db, def, file_id, module, params, body, is_async_fn);
107-
source_map.store.shrink_to_fit();
107+
let (body, source_map) = lower_body(db, def, file_id, module, params, body, is_async_fn);
108108

109109
(Arc::new(body), Arc::new(source_map))
110110
}

crates/hir-def/src/expr_store/lower.rs

Lines changed: 66 additions & 73 deletions
Large diffs are not rendered by default.

crates/hir-def/src/expr_store/lower/asm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ impl ExprCollector<'_> {
282282
Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options, kind }),
283283
syntax_ptr,
284284
);
285-
self.source_map
285+
self.store
286286
.template_map
287287
.get_or_insert_with(Default::default)
288288
.asm_to_captures

crates/hir-def/src/expr_store/lower/path/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn lower_path(path: ast::Path) -> (TestDB, ExpressionStore, Option<Path>) {
2323
let mut ctx =
2424
ExprCollector::new(&db, crate_def_map(&db, krate).root_module_id(), file_id.into());
2525
let lowered_path = ctx.lower_path(path, &mut ExprCollector::impl_trait_allocator);
26-
let store = ctx.store.finish();
26+
let (store, _) = ctx.store.finish();
2727
(db, store, lowered_path)
2828
}
2929

crates/hir-def/src/expr_store/pretty.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ impl Printer<'_> {
902902
let mut same_name = false;
903903
if let Pat::Bind { id, subpat: None } = &self.store[arg.pat] {
904904
if let Binding { name, mode: BindingAnnotation::Unannotated, .. } =
905-
&self.store.bindings[*id]
905+
&self.store.assert_expr_only().bindings[*id]
906906
{
907907
if name.as_str() == field_name {
908908
same_name = true;
@@ -1063,7 +1063,7 @@ impl Printer<'_> {
10631063
}
10641064

10651065
fn print_binding(&mut self, id: BindingId) {
1066-
let Binding { name, mode, .. } = &self.store.bindings[id];
1066+
let Binding { name, mode, .. } = &self.store.assert_expr_only().bindings[id];
10671067
let mode = match mode {
10681068
BindingAnnotation::Unannotated => "",
10691069
BindingAnnotation::Mutable => "mut ",

crates/hir-def/src/expr_store/scope.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ impl ExprScopes {
106106
let mut scopes = ExprScopes {
107107
scopes: Arena::default(),
108108
scope_entries: Arena::default(),
109-
scope_by_expr: ArenaMap::with_capacity(body.exprs.len()),
109+
scope_by_expr: ArenaMap::with_capacity(
110+
body.expr_only.as_ref().map_or(0, |it| it.exprs.len()),
111+
),
110112
};
111113
let mut root = scopes.root_scope();
112114
if let Some(self_param) = body.self_param {
@@ -179,7 +181,7 @@ impl ExprScopes {
179181
binding: BindingId,
180182
hygiene: HygieneId,
181183
) {
182-
let Binding { name, .. } = &store.bindings[binding];
184+
let Binding { name, .. } = &store[binding];
183185
let entry = self.scope_entries.alloc(ScopeEntry { name: name.clone(), binding, hygiene });
184186
self.scopes[scope].entries =
185187
IdxRange::new_inclusive(self.scopes[scope].entries.start()..=entry);
@@ -251,7 +253,7 @@ fn compute_expr_scopes(
251253
scope: &mut ScopeId,
252254
) {
253255
let make_label =
254-
|label: &Option<LabelId>| label.map(|label| (label, store.labels[label].name.clone()));
256+
|label: &Option<LabelId>| label.map(|label| (label, store[label].name.clone()));
255257

256258
let compute_expr_scopes = |scopes: &mut ExprScopes, expr: ExprId, scope: &mut ScopeId| {
257259
compute_expr_scopes(expr, store, scopes, scope)
@@ -534,9 +536,8 @@ fn foo() {
534536
};
535537

536538
let resolved = scopes.resolve_name_in_scope(expr_scope, &name_ref.as_name()).unwrap();
537-
let pat_src = source_map
538-
.pat_syntax(*source_map.binding_definitions[resolved.binding()].first().unwrap())
539-
.unwrap();
539+
let pat_src =
540+
source_map.pat_syntax(source_map.patterns_for_binding(resolved.binding())[0]).unwrap();
540541

541542
let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());
542543
assert_eq!(local_name.text_range(), expected_name.syntax().text_range());

crates/hir-def/src/expr_store/tests/body.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -508,9 +508,9 @@ fn f() {
508508
}
509509
"#,
510510
);
511-
assert_eq!(body.bindings.len(), 1, "should have a binding for `B`");
511+
assert_eq!(body.assert_expr_only().bindings.len(), 1, "should have a binding for `B`");
512512
assert_eq!(
513-
body.bindings[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(),
513+
body[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(),
514514
"B",
515515
"should have a binding for `B`",
516516
);
@@ -566,6 +566,7 @@ const fn f(x: i32) -> i32 {
566566
);
567567

568568
let mtch_arms = body
569+
.assert_expr_only()
569570
.exprs
570571
.iter()
571572
.find_map(|(_, expr)| {
@@ -578,10 +579,10 @@ const fn f(x: i32) -> i32 {
578579
.unwrap();
579580

580581
let MatchArm { pat, .. } = mtch_arms[1];
581-
match body.pats[pat] {
582+
match body[pat] {
582583
Pat::Range { start, end } => {
583-
let hir_start = &body.exprs[start.unwrap()];
584-
let hir_end = &body.exprs[end.unwrap()];
584+
let hir_start = &body[start.unwrap()];
585+
let hir_end = &body[end.unwrap()];
585586

586587
assert!(matches!(hir_start, Expr::Path { .. }));
587588
assert!(matches!(hir_end, Expr::Path { .. }));

crates/hir-def/src/signatures.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -779,14 +779,10 @@ impl VariantFields {
779779
Arc::new(VariantFields { fields, store: Arc::new(store), shape }),
780780
Arc::new(source_map),
781781
),
782-
None => (
783-
Arc::new(VariantFields {
784-
fields: Arena::default(),
785-
store: ExpressionStore::empty_singleton(),
786-
shape,
787-
}),
788-
ExpressionStoreSourceMap::empty_singleton(),
789-
),
782+
None => {
783+
let (store, source_map) = ExpressionStore::empty_singleton();
784+
(Arc::new(VariantFields { fields: Arena::default(), store, shape }), source_map)
785+
}
790786
}
791787
}
792788

@@ -878,7 +874,7 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
878874
idx += 1;
879875
}
880876
Err(cfg) => {
881-
col.source_map.diagnostics.push(
877+
col.store.diagnostics.push(
882878
crate::expr_store::ExpressionStoreDiagnostics::InactiveCode {
883879
node: InFile::new(fields.file_id, SyntaxNodePtr::new(field.syntax())),
884880
cfg,
@@ -891,9 +887,9 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
891887
if !has_fields {
892888
return None;
893889
}
894-
let store = col.store.finish();
890+
let (store, source_map) = col.store.finish();
895891
arena.shrink_to_fit();
896-
Some((arena, store, col.source_map))
892+
Some((arena, store, source_map))
897893
}
898894

899895
#[derive(Debug, PartialEq, Eq)]
@@ -980,7 +976,7 @@ impl EnumVariants {
980976
if !matches!(variant.shape, FieldsShape::Unit) {
981977
let body = db.body(v.into());
982978
// A variant with explicit discriminant
983-
if body.exprs[body.body_expr] != crate::hir::Expr::Missing {
979+
if !matches!(body[body.body_expr], crate::hir::Expr::Missing) {
984980
return false;
985981
}
986982
}

crates/hir-ty/src/consteval.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ pub(crate) fn const_eval_discriminant_variant(
281281
let def = variant_id.into();
282282
let body = db.body(def);
283283
let loc = variant_id.lookup(db);
284-
if body.exprs[body.body_expr] == Expr::Missing {
284+
if matches!(body[body.body_expr], Expr::Missing) {
285285
let prev_idx = loc.index.checked_sub(1);
286286
let value = match prev_idx {
287287
Some(prev_idx) => {
@@ -334,7 +334,7 @@ pub(crate) fn eval_to_const(
334334
// Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
335335
return unknown_const(infer[expr].clone());
336336
}
337-
if let Expr::Path(p) = &ctx.body.exprs[expr] {
337+
if let Expr::Path(p) = &ctx.body[expr] {
338338
let resolver = &ctx.resolver;
339339
if let Some(c) =
340340
path_to_const(db, resolver, p, mode, || ctx.generics(), debruijn, infer[expr].clone())

0 commit comments

Comments
 (0)