Skip to content

Commit 4451c71

Browse files
committed
perf: cache interface_hash in ArtifactsCacheInner
1 parent 59ebda6 commit 4451c71

File tree

6 files changed

+38
-44
lines changed

6 files changed

+38
-44
lines changed

crates/compilers/src/cache.rs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use crate::{
44
buildinfo::RawBuildInfo,
55
compilers::{Compiler, CompilerSettings, Language},
66
output::Builds,
7+
preprocessor::interface_repr_hash,
78
resolver::GraphEdges,
8-
ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Graph, OutputContext, ParsedSource,
9-
Project, ProjectPaths, ProjectPathsConfig, SourceCompilationKind,
9+
ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Graph, OutputContext, Project,
10+
ProjectPaths, ProjectPathsConfig, SourceCompilationKind,
1011
};
1112
use foundry_compilers_artifacts::{
1213
sources::{Source, Sources},
@@ -681,11 +682,8 @@ impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
681682
.map(|import| strip_prefix(import, self.project.root()).into())
682683
.collect();
683684

684-
let interface_repr_hash = if self.cache.preprocessed && self.is_source_file(&file) {
685-
self.edges.get_parsed_source(&file).and_then(ParsedSource::interface_repr_hash)
686-
} else {
687-
None
688-
};
685+
let interface_repr_hash = (self.cache.preprocessed && self.is_source_file(&file))
686+
.then(|| self.interface_repr_hash(source, &file).to_string());
689687

690688
let entry = CacheEntry {
691689
last_modification_date: CacheEntry::read_last_modification_date(&file)
@@ -703,6 +701,27 @@ impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
703701
self.cache.files.insert(file, entry);
704702
}
705703

704+
/// Gets or calculates the content hash for the given source file.
705+
fn content_hash(&mut self, source: &Source, file: &Path) -> &str {
706+
self.content_hashes.entry(file.to_path_buf()).or_insert_with(|| source.content_hash())
707+
}
708+
709+
/// Gets or calculates the interface representation hash for the given source file.
710+
fn interface_repr_hash(&mut self, source: &Source, file: &Path) -> &str {
711+
self.interface_repr_hashes
712+
.entry(file.to_path_buf())
713+
.or_insert_with(|| {
714+
if let Some(r) = interface_repr_hash(&source.content, file) {
715+
return r;
716+
}
717+
self.content_hashes
718+
.entry(file.to_path_buf())
719+
.or_insert_with(|| source.content_hash())
720+
.clone()
721+
})
722+
.as_str()
723+
}
724+
706725
/// Returns the set of [Source]s that need to be compiled to produce artifacts for requested
707726
/// input.
708727
///
@@ -956,17 +975,11 @@ impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
956975
/// Adds the file's hashes to the set if not set yet
957976
fn fill_hashes(&mut self, sources: &Sources) {
958977
for (file, source) in sources {
959-
let content_hash =
960-
self.content_hashes.entry(file.clone()).or_insert_with(|| source.content_hash());
978+
let _ = self.content_hash(source, file);
961979

962980
// Fill interface representation hashes for source files
963981
if self.cache.preprocessed && self.project.paths.is_source_file(file) {
964-
self.interface_repr_hashes.entry(file.clone()).or_insert_with(|| {
965-
self.edges
966-
.get_parsed_source(file)
967-
.and_then(ParsedSource::interface_repr_hash)
968-
.unwrap_or_else(|| content_hash.clone())
969-
});
982+
let _ = self.interface_repr_hash(source, file);
970983
}
971984
}
972985
}

crates/compilers/src/compilers/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@ pub trait ParsedSource: Debug + Sized + Send + Clone {
186186
{
187187
vec![].into_iter()
188188
}
189-
190-
/// Returns the hash of the interface of the source.
191-
fn interface_repr_hash(&self) -> Option<String> {
192-
None
193-
}
194189
}
195190

196191
/// Error returned by compiler. Might also represent a warning or informational message.

crates/compilers/src/compilers/multi.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,6 @@ impl ParsedSource for MultiCompilerParsedSource {
387387
}
388388
.into_iter()
389389
}
390-
391-
fn interface_repr_hash(&self) -> Option<String> {
392-
match self {
393-
Self::Solc(parsed) => parsed.interface_repr_hash(),
394-
Self::Vyper(parsed) => parsed.interface_repr_hash(),
395-
}
396-
}
397390
}
398391

399392
impl CompilationError for MultiCompilerError {

crates/compilers/src/compilers/solc/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,6 @@ impl ParsedSource for SolData {
397397
{
398398
imported_nodes.filter_map(|(path, node)| (!node.libraries.is_empty()).then_some(path))
399399
}
400-
401-
fn interface_repr_hash(&self) -> Option<String> {
402-
self.interface_repr_hash.clone()
403-
}
404400
}
405401

406402
impl CompilationError for Error {

crates/compilers/src/preprocessor/mod.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ impl Preprocessor<MultiCompiler> for TestOptimizerPreprocessor {
134134
}
135135
}
136136

137+
pub(crate) fn interface_repr_hash(content: &str, path: &Path) -> Option<String> {
138+
let src = interface_repr(content, path).ok()?;
139+
Some(foundry_compilers_artifacts::Source::content_hash_of(&src))
140+
}
141+
142+
pub(crate) fn interface_repr(content: &str, path: &Path) -> Result<String, EmittedDiagnostics> {
143+
parse_one_source(content, path, |ast| interface_representation_ast(content, &ast))
144+
}
145+
137146
pub(crate) fn parse_one_source<R>(
138147
content: &str,
139148
path: &Path,
@@ -210,11 +219,6 @@ pub(crate) fn interface_representation_ast(
210219
mod tests {
211220
use super::*;
212221

213-
fn interface_representation(content: &str) -> String {
214-
parse_one_source(content, Path::new(""), |ast| interface_representation_ast(content, &ast))
215-
.unwrap()
216-
}
217-
218222
#[test]
219223
fn test_interface_representation() {
220224
let content = r#"
@@ -235,7 +239,7 @@ contract A {
235239
}
236240
}"#;
237241

238-
let result = interface_representation(content);
242+
let result = interface_repr(content, Path::new("")).unwrap();
239243
assert_eq!(
240244
result,
241245
r#"library Lib {function libFn() internal {// logic to keep}}contract A {function a() externalfunction b() publicfunction e() external }"#

crates/compilers/src/resolver/parse.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub struct SolData {
1919
pub contract_names: Vec<String>,
2020
pub is_yul: bool,
2121
pub parse_result: Result<(), String>,
22-
pub interface_repr_hash: Option<String>,
2322
}
2423

2524
impl SolData {
@@ -51,7 +50,6 @@ impl SolData {
5150
let mut libraries = Vec::new();
5251
let mut contract_names = Vec::new();
5352
let mut parse_result = Ok(());
54-
let mut interface_repr_hash = None;
5553

5654
let result = crate::preprocessor::parse_one_source(content, file, |ast| {
5755
for item in ast.items.iter() {
@@ -103,10 +101,6 @@ impl SolData {
103101

104102
_ => {}
105103
}
106-
107-
interface_repr_hash = Some(foundry_compilers_artifacts::Source::content_hash_of(
108-
&crate::preprocessor::interface_representation_ast(content, &ast),
109-
));
110104
}
111105
});
112106
if let Err(e) = result {
@@ -153,7 +147,6 @@ impl SolData {
153147
contract_names,
154148
is_yul,
155149
parse_result,
156-
interface_repr_hash,
157150
}
158151
}
159152

0 commit comments

Comments
 (0)