Skip to content

Commit 13f96b6

Browse files
committed
Add type cache to Fuel ABI.
1 parent 28881f2 commit 13f96b6

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

forc-pkg/src/pkg.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,8 @@ pub fn compile(
18111811
abi_with_callpaths: true,
18121812
type_ids_to_full_type_str: HashMap::<String, String>::new(),
18131813
unique_names: HashMap::new(),
1814+
metadata_declaration_cache: HashMap::new(),
1815+
concrete_declaration_cache: HashMap::new(),
18141816
experimental,
18151817
},
18161818
engines,

sway-core/src/abi_generation/fuel_abi.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ pub struct AbiContext<'a> {
4646
pub abi_with_callpaths: bool,
4747
pub type_ids_to_full_type_str: HashMap<String, String>,
4848
pub unique_names: HashMap<String, AbiNameDiagnosticSpan>,
49+
pub metadata_declaration_cache: HashMap<TypeCacheKey, program_abi::TypeMetadataDeclaration>,
50+
pub concrete_declaration_cache: HashMap<TypeCacheKey, program_abi::TypeConcreteDeclaration>,
4951
pub experimental: ExperimentalFeatures,
5052
}
5153

@@ -61,6 +63,41 @@ impl AbiContext<'_> {
6163
}
6264
}
6365

66+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
67+
pub struct TypeCacheKey(u64);
68+
69+
impl TypeCacheKey {
70+
fn from_type_id(engines: &Engines, abi_type_aliases_enabled: bool, type_id: TypeId) -> Self {
71+
let type_engine = engines.te();
72+
let type_info = &*type_engine.get(type_id);
73+
Self::from_type_info(type_info, engines, abi_type_aliases_enabled)
74+
}
75+
76+
fn from_type_info(
77+
type_info: &TypeInfo,
78+
engines: &Engines,
79+
abi_type_aliases_enabled: bool,
80+
) -> Self {
81+
if abi_type_aliases_enabled {
82+
if let TypeInfo::Alias { name, ty } = type_info {
83+
let mut hasher = DefaultHasher::new();
84+
name.hash(&mut hasher);
85+
86+
let target_type_id = engines.te().get_unaliased_type_id(ty.type_id);
87+
let target_key =
88+
TypeCacheKey::from_type_id(engines, abi_type_aliases_enabled, target_type_id);
89+
target_key.0.hash(&mut hasher);
90+
91+
return TypeCacheKey(hasher.finish());
92+
}
93+
}
94+
95+
let mut hasher = DefaultHasher::new();
96+
type_info.hash(&mut hasher, engines);
97+
TypeCacheKey(hasher.finish())
98+
}
99+
}
100+
64101
pub fn extract_abi_name_inner(span: &Span) -> Option<Span> {
65102
let text = &span.src().text;
66103
let full_attr = span.as_str();
@@ -619,6 +656,12 @@ fn generate_concrete_type_declaration(
619656
type_id: TypeId,
620657
resolved_type_id: TypeId,
621658
) -> Result<ConcreteTypeId, ErrorEmitted> {
659+
let cache_key =
660+
TypeCacheKey::from_type_id(engines, ctx.experimental.abi_type_aliases, resolved_type_id);
661+
if let Some(cached_decl) = ctx.concrete_declaration_cache.get(&cache_key) {
662+
return Ok(cached_decl.concrete_type_id.clone());
663+
}
664+
622665
let mut metadata_types_to_add = Vec::<program_abi::TypeMetadataDeclaration>::new();
623666

624667
let type_metadata_decl = generate_type_metadata_declaration(
@@ -670,6 +713,8 @@ fn generate_concrete_type_declaration(
670713
alias_of: None,
671714
};
672715

716+
ctx.concrete_declaration_cache
717+
.insert(cache_key, concrete_type_decl.clone());
673718
concrete_types.push(concrete_type_decl);
674719

675720
Ok(concrete_type_id)
@@ -686,6 +731,12 @@ fn generate_type_metadata_declaration(
686731
resolved_type_id: TypeId,
687732
metadata_types_to_add: &mut Vec<program_abi::TypeMetadataDeclaration>,
688733
) -> Result<program_abi::TypeMetadataDeclaration, ErrorEmitted> {
734+
let cache_key =
735+
TypeCacheKey::from_type_id(engines, ctx.experimental.abi_type_aliases, resolved_type_id);
736+
if let Some(cached_decl) = ctx.metadata_declaration_cache.get(&cache_key) {
737+
return Ok(cached_decl.clone());
738+
}
739+
689740
let mut alias_metadata_types_to_add = Vec::<program_abi::TypeMetadataDeclaration>::new();
690741

691742
let type_engine = engines.te();
@@ -747,6 +798,8 @@ fn generate_type_metadata_declaration(
747798
alias_of,
748799
};
749800

801+
ctx.metadata_declaration_cache
802+
.insert(cache_key, type_metadata_decl.clone());
750803
metadata_types_to_add.push(type_metadata_decl.clone());
751804
metadata_types_to_add.extend(new_metadata_types_to_add);
752805
metadata_types_to_add.extend(alias_metadata_types_to_add);
@@ -1748,6 +1801,16 @@ impl GenericTypeParameter {
17481801
metadata_types_to_add: &mut Vec<program_abi::TypeMetadataDeclaration>,
17491802
) -> Result<MetadataTypeId, ErrorEmitted> {
17501803
let type_id = MetadataTypeId(self.initial_type_id.index());
1804+
let cache_key = TypeCacheKey::from_type_id(
1805+
engines,
1806+
ctx.experimental.abi_type_aliases,
1807+
self.initial_type_id,
1808+
);
1809+
1810+
if let Some(cached) = ctx.metadata_declaration_cache.get(&cache_key) {
1811+
return Ok(cached.metadata_type_id.clone());
1812+
}
1813+
17511814
let type_field = self.initial_type_id.get_abi_type_str(
17521815
handler,
17531816
&ctx.to_str_context(),
@@ -1771,6 +1834,8 @@ impl GenericTypeParameter {
17711834
type_parameters: None,
17721835
alias_of: None,
17731836
};
1837+
ctx.metadata_declaration_cache
1838+
.insert(cache_key, type_parameter.clone());
17741839
metadata_types_to_add.push(type_parameter);
17751840
Ok(type_id)
17761841
}

0 commit comments

Comments
 (0)