@@ -3,7 +3,10 @@ use fuel_abi_types::abi::program::{
33 PanickingCall , TypeConcreteDeclaration ,
44} ;
55use 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+ } ;
710use sway_error:: {
811 error:: CompileError ,
912 handler:: { ErrorEmitted , Handler } ,
@@ -13,6 +16,7 @@ use sway_types::{BaseIdent, Named, Span, Spanned};
1316
1417use 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
4653impl 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+
5781pub 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