diff options
author | Aleksey Kladov <[email protected]> | 2019-06-02 18:15:10 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-06-02 18:15:10 +0100 |
commit | 8b7f58976b32ccc768e35151b77aa9ea004b7495 (patch) | |
tree | 272f93a4431ca77d6cce8ee43c0d6d4f3c636701 /crates/ra_hir | |
parent | b40c6de8a6887e6c184fca5c9188d26ee402df23 (diff) |
don't cache parses twice
Before this commit, `Parse`s for original file ended up two times in
salsa's db: first, when we parse original file, and second, when we
parse macro or a file.
Given that parse trees are the worst ofenders in terms of memory, it
makes sense to make sure we store them only once.
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/db.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 |
3 files changed, 32 insertions, 26 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 872103219..3afd0994c 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -33,8 +33,11 @@ pub trait AstDatabase: SourceDatabase { | |||
33 | #[salsa::transparent] | 33 | #[salsa::transparent] |
34 | #[salsa::invoke(crate::source_id::AstIdMap::file_item_query)] | 34 | #[salsa::invoke(crate::source_id::AstIdMap::file_item_query)] |
35 | fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> TreeArc<SyntaxNode>; | 35 | fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> TreeArc<SyntaxNode>; |
36 | #[salsa::transparent] | ||
36 | #[salsa::invoke(crate::ids::HirFileId::parse_or_expand_query)] | 37 | #[salsa::invoke(crate::ids::HirFileId::parse_or_expand_query)] |
37 | fn parse_or_expand(&self, file_id: HirFileId) -> Option<TreeArc<SyntaxNode>>; | 38 | fn parse_or_expand(&self, file_id: HirFileId) -> Option<TreeArc<SyntaxNode>>; |
39 | #[salsa::invoke(crate::ids::HirFileId::parse_macro_query)] | ||
40 | fn parse_macro(&self, macro_file: ids::MacroFile) -> Option<TreeArc<SyntaxNode>>; | ||
38 | 41 | ||
39 | #[salsa::invoke(crate::ids::macro_def_query)] | 42 | #[salsa::invoke(crate::ids::macro_def_query)] |
40 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; | 43 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 79e32e579..a95561812 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -62,32 +62,35 @@ impl HirFileId { | |||
62 | file_id: HirFileId, | 62 | file_id: HirFileId, |
63 | ) -> Option<TreeArc<SyntaxNode>> { | 63 | ) -> Option<TreeArc<SyntaxNode>> { |
64 | db.check_canceled(); | 64 | db.check_canceled(); |
65 | let _p = profile("parse_or_expand_query"); | ||
66 | match file_id.0 { | 65 | match file_id.0 { |
67 | HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree.syntax().to_owned()), | 66 | HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree.syntax().to_owned()), |
68 | HirFileIdRepr::Macro(macro_file) => { | 67 | HirFileIdRepr::Macro(macro_file) => db.parse_macro(macro_file), |
69 | let macro_call_id = macro_file.macro_call_id; | 68 | } |
70 | let tt = db | 69 | } |
71 | .macro_expand(macro_call_id) | 70 | |
72 | .map_err(|err| { | 71 | pub(crate) fn parse_macro_query( |
73 | // Note: | 72 | db: &impl AstDatabase, |
74 | // The final goal we would like to make all parse_macro success, | 73 | macro_file: MacroFile, |
75 | // such that the following log will not call anyway. | 74 | ) -> Option<TreeArc<SyntaxNode>> { |
76 | log::warn!( | 75 | let _p = profile("parse_macro_query"); |
77 | "fail on macro_parse: (reason: {}) {}", | 76 | let macro_call_id = macro_file.macro_call_id; |
78 | err, | 77 | let tt = db |
79 | macro_call_id.debug_dump(db) | 78 | .macro_expand(macro_call_id) |
80 | ); | 79 | .map_err(|err| { |
81 | }) | 80 | // Note: |
82 | .ok()?; | 81 | // The final goal we would like to make all parse_macro success, |
83 | match macro_file.macro_file_kind { | 82 | // such that the following log will not call anyway. |
84 | MacroFileKind::Items => { | 83 | log::warn!( |
85 | Some(mbe::token_tree_to_ast_item_list(&tt).syntax().to_owned()) | 84 | "fail on macro_parse: (reason: {}) {}", |
86 | } | 85 | err, |
87 | MacroFileKind::Expr => { | 86 | macro_call_id.debug_dump(db) |
88 | mbe::token_tree_to_expr(&tt).ok().map(|it| it.syntax().to_owned()) | 87 | ); |
89 | } | 88 | }) |
90 | } | 89 | .ok()?; |
90 | match macro_file.macro_file_kind { | ||
91 | MacroFileKind::Items => Some(mbe::token_tree_to_ast_item_list(&tt).syntax().to_owned()), | ||
92 | MacroFileKind::Expr => { | ||
93 | mbe::token_tree_to_expr(&tt).ok().map(|it| it.syntax().to_owned()) | ||
91 | } | 94 | } |
92 | } | 95 | } |
93 | } | 96 | } |
@@ -100,7 +103,7 @@ enum HirFileIdRepr { | |||
100 | } | 103 | } |
101 | 104 | ||
102 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 105 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
103 | struct MacroFile { | 106 | pub struct MacroFile { |
104 | macro_call_id: MacroCallId, | 107 | macro_call_id: MacroCallId, |
105 | macro_file_kind: MacroFileKind, | 108 | macro_file_kind: MacroFileKind, |
106 | } | 109 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index f2a31795d..18dea5f17 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -60,7 +60,7 @@ pub use self::{ | |||
60 | path::{Path, PathKind}, | 60 | path::{Path, PathKind}, |
61 | name::Name, | 61 | name::Name, |
62 | source_id::{AstIdMap, ErasedFileAstId}, | 62 | source_id::{AstIdMap, ErasedFileAstId}, |
63 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc}, | 63 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, MacroFile}, |
64 | nameres::{PerNs, Namespace, ImportId}, | 64 | nameres::{PerNs, Namespace, ImportId}, |
65 | ty::{Ty, ApplicationTy, TypeCtor, TraitRef, Substs, display::HirDisplay, CallableDef}, | 65 | ty::{Ty, ApplicationTy, TypeCtor, TraitRef, Substs, display::HirDisplay, CallableDef}, |
66 | impl_block::{ImplBlock, ImplItem}, | 66 | impl_block::{ImplBlock, ImplItem}, |