Skip to content

Commit a37517b

Browse files
committed
Add type cache to Fuel ABI emitter.
1 parent ff5e5d3 commit a37517b

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

forc-pkg/src/pkg.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,9 @@ 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(),
1816+
type_cache_enabled: false,
18141817
},
18151818
engines,
18161819
if experimental.new_encoding {

sway-core/src/abi_generation/fuel_abi.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use fuel_abi_types::abi::program::{
33
PanickingCall, TypeConcreteDeclaration,
44
};
55
use sha2::{Digest, Sha256};
6-
use std::collections::{BTreeMap, HashMap, HashSet};
6+
use std::{
7+
collections::{hash_map::DefaultHasher, BTreeMap, HashMap, HashSet},
8+
hash::{Hash, Hasher},
9+
};
710
use sway_error::{
811
error::CompileError,
912
handler::{ErrorEmitted, Handler},
@@ -13,6 +16,7 @@ use sway_types::{BaseIdent, Named, Span, Spanned};
1316

1417
use crate::{
1518
ast_elements::type_parameter::GenericTypeParameter,
19+
engine_threading::HashWithEngines,
1620
language::ty::{TyFunctionDecl, TyProgram, TyProgramKind},
1721
transform::Attributes,
1822
AbiEncodeSizeHint, Engines, PanicOccurrences, PanickingCallOccurrences, TypeId, TypeInfo,
@@ -41,6 +45,9 @@ pub struct AbiContext<'a> {
4145
pub abi_with_callpaths: bool,
4246
pub type_ids_to_full_type_str: HashMap<String, String>,
4347
pub unique_names: HashMap<String, AbiNameDiagnosticSpan>,
48+
pub metadata_declaration_cache: HashMap<TypeCacheKey, program_abi::TypeMetadataDeclaration>,
49+
pub concrete_declaration_cache: HashMap<TypeCacheKey, program_abi::TypeConcreteDeclaration>,
50+
pub type_cache_enabled: bool,
4451
}
4552

4653
impl AbiContext<'_> {
@@ -54,6 +61,23 @@ impl AbiContext<'_> {
5461
}
5562
}
5663

64+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
65+
pub struct TypeCacheKey(u64);
66+
67+
impl TypeCacheKey {
68+
fn from_type_id(engines: &Engines, type_id: TypeId) -> Self {
69+
let type_engine = engines.te();
70+
let type_info = &*type_engine.get(type_id);
71+
Self::from_type_info(type_info, engines)
72+
}
73+
74+
fn from_type_info(type_info: &TypeInfo, engines: &Engines) -> Self {
75+
let mut hasher = DefaultHasher::new();
76+
type_info.hash(&mut hasher, engines);
77+
TypeCacheKey(hasher.finish())
78+
}
79+
}
80+
5781
pub fn extract_abi_name_inner(span: &Span) -> Option<Span> {
5882
let text = &span.src().text;
5983
let full_attr = span.as_str();
@@ -601,6 +625,13 @@ fn generate_concrete_type_declaration(
601625
type_id: TypeId,
602626
resolved_type_id: TypeId,
603627
) -> Result<ConcreteTypeId, ErrorEmitted> {
628+
let cache_key = TypeCacheKey::from_type_id(engines, resolved_type_id);
629+
if ctx.type_cache_enabled {
630+
if let Some(cached_decl) = ctx.concrete_declaration_cache.get(&cache_key) {
631+
return Ok(cached_decl.concrete_type_id.clone());
632+
}
633+
}
634+
604635
let mut metadata_types_to_add = Vec::<program_abi::TypeMetadataDeclaration>::new();
605636

606637
let type_metadata_decl = generate_type_metadata_declaration(
@@ -651,6 +682,8 @@ fn generate_concrete_type_declaration(
651682
alias_of: None,
652683
};
653684

685+
ctx.concrete_declaration_cache
686+
.insert(cache_key, concrete_type_decl.clone());
654687
concrete_types.push(concrete_type_decl);
655688

656689
Ok(concrete_type_id)
@@ -667,6 +700,13 @@ fn generate_type_metadata_declaration(
667700
resolved_type_id: TypeId,
668701
metadata_types_to_add: &mut Vec<program_abi::TypeMetadataDeclaration>,
669702
) -> Result<program_abi::TypeMetadataDeclaration, ErrorEmitted> {
703+
let cache_key = TypeCacheKey::from_type_id(engines, resolved_type_id);
704+
if ctx.type_cache_enabled {
705+
if let Some(cached_decl) = ctx.metadata_declaration_cache.get(&cache_key) {
706+
return Ok(cached_decl.clone());
707+
}
708+
}
709+
670710
let mut new_metadata_types_to_add = Vec::<program_abi::TypeMetadataDeclaration>::new();
671711

672712
let components = type_id.get_abi_type_components(
@@ -699,6 +739,8 @@ fn generate_type_metadata_declaration(
699739
alias_of: None,
700740
};
701741

742+
ctx.metadata_declaration_cache
743+
.insert(cache_key, type_metadata_decl.clone());
702744
metadata_types_to_add.push(type_metadata_decl.clone());
703745
metadata_types_to_add.extend(new_metadata_types_to_add);
704746

@@ -1626,6 +1668,13 @@ impl GenericTypeParameter {
16261668
concrete_types: &mut Vec<program_abi::TypeConcreteDeclaration>,
16271669
metadata_types_to_add: &mut Vec<program_abi::TypeMetadataDeclaration>,
16281670
) -> Result<MetadataTypeId, ErrorEmitted> {
1671+
let cache_key = TypeCacheKey::from_type_id(engines, self.initial_type_id);
1672+
if ctx.type_cache_enabled {
1673+
if let Some(cached) = ctx.metadata_declaration_cache.get(&cache_key) {
1674+
return Ok(cached.metadata_type_id.clone());
1675+
}
1676+
}
1677+
16291678
let type_id = MetadataTypeId(self.initial_type_id.index());
16301679

16311680
let type_field = self.initial_type_id.get_abi_type_str(
@@ -1651,6 +1700,9 @@ impl GenericTypeParameter {
16511700
type_parameters: None,
16521701
alias_of: None,
16531702
};
1703+
1704+
ctx.metadata_declaration_cache
1705+
.insert(cache_key, type_parameter.clone());
16541706
metadata_types_to_add.push(type_parameter);
16551707
Ok(type_id)
16561708
}

0 commit comments

Comments
 (0)