@@ -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+
64101pub 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