66using Java . Interop . Tools . TypeNameMappings ;
77using Microsoft . Build . Framework ;
88using Microsoft . Build . Utilities ;
9-
109using Xamarin . Android . Tasks . LLVMIR ;
1110
1211namespace Xamarin . Android . Tasks
@@ -27,17 +26,13 @@ sealed class DSOCacheEntryContextDataProvider : NativeAssemblerStructContextData
2726 {
2827 public override string GetComment ( object data , string fieldName )
2928 {
30- var dso_entry = data as DSOCacheEntry ;
31- if ( dso_entry == null ) {
32- throw new InvalidOperationException ( "Invalid data type, expected an instance of DSOCacheEntry" ) ;
33- }
34-
29+ var dso_entry = EnsureType < DSOCacheEntry > ( data ) ;
3530 if ( String . Compare ( "hash" , fieldName , StringComparison . Ordinal ) == 0 ) {
36- return $ "hash 0x{ dso_entry . hash : x} , from name: { dso_entry . HashedName } ";
31+ return $ " hash 0x{ dso_entry . hash : x} , from name: { dso_entry . HashedName } ";
3732 }
3833
3934 if ( String . Compare ( "name" , fieldName , StringComparison . Ordinal ) == 0 ) {
40- return $ "name: { dso_entry . name } ";
35+ return $ " name: { dso_entry . name } ";
4136 }
4237
4338 return String . Empty ;
@@ -57,6 +52,7 @@ sealed class DSOCacheEntry
5752 public ulong hash ;
5853 public bool ignore ;
5954
55+ [ NativeAssembler ( UsesDataProvider = true ) ]
6056 public string name ;
6157 public IntPtr handle = IntPtr . Zero ;
6258 }
@@ -131,24 +127,24 @@ sealed class XamarinAndroidBundledAssembly
131127 public uint name_length ;
132128
133129 [ NativeAssembler ( UsesDataProvider = true ) , NativePointer ( PointsToPreAllocatedBuffer = true ) ]
134- public char name ;
130+ public string name ;
135131 }
136132
137133 // Keep in sync with FORMAT_TAG in src/monodroid/jni/xamarin-app.hh
138134 const ulong FORMAT_TAG = 0x015E6972616D58 ;
139135
140- SortedDictionary < string , string > environmentVariables ;
141- SortedDictionary < string , string > systemProperties ;
136+ SortedDictionary < string , string > ? environmentVariables ;
137+ SortedDictionary < string , string > ? systemProperties ;
142138 TaskLoggingHelper log ;
143- StructureInstance < ApplicationConfig > ? application_config ;
139+ StructureInstance ? application_config ;
144140 List < StructureInstance < DSOCacheEntry > > ? dsoCache ;
145141 List < StructureInstance < XamarinAndroidBundledAssembly > > ? xamarinAndroidBundledAssemblies ;
146142
147- StructureInfo < ApplicationConfig > ? applicationConfigStructureInfo ;
148- StructureInfo < DSOCacheEntry > ? dsoCacheEntryStructureInfo ;
149- StructureInfo < XamarinAndroidBundledAssembly > ? xamarinAndroidBundledAssemblyStructureInfo ;
150- StructureInfo < AssemblyStoreSingleAssemblyRuntimeData > assemblyStoreSingleAssemblyRuntimeDataStructureinfo ;
151- StructureInfo < AssemblyStoreRuntimeData > assemblyStoreRuntimeDataStructureInfo ;
143+ StructureInfo ? applicationConfigStructureInfo ;
144+ StructureInfo ? dsoCacheEntryStructureInfo ;
145+ StructureInfo ? xamarinAndroidBundledAssemblyStructureInfo ;
146+ StructureInfo ? assemblyStoreSingleAssemblyRuntimeDataStructureinfo ;
147+ StructureInfo ? assemblyStoreRuntimeDataStructureInfo ;
152148
153149 public bool UsesMonoAOT { get ; set ; }
154150 public bool UsesMonoLLVM { get ; set ; }
@@ -188,8 +184,23 @@ public ApplicationConfigNativeAssemblyGenerator (IDictionary<string, string> env
188184 this . log = log ;
189185 }
190186
191- public override void Init ( )
187+ protected override void Construct ( LlvmIrModule module )
192188 {
189+ MapStructures ( module ) ;
190+
191+ module . AddGlobalVariable ( "format_tag" , FORMAT_TAG , comment : $ " 0x{ FORMAT_TAG : x} ") ;
192+ module . AddGlobalVariable ( "mono_aot_mode_name" , MonoAOTMode ) ;
193+
194+ var envVars = new LlvmIrGlobalVariable ( environmentVariables , "app_environment_variables" ) {
195+ Comment = " Application environment variables array, name:value" ,
196+ } ;
197+ module . Add ( envVars , stringGroupName : "env" , stringGroupComment : " Application environment variables name:value pairs" ) ;
198+
199+ var sysProps = new LlvmIrGlobalVariable ( systemProperties , "app_system_properties" ) {
200+ Comment = " System properties defined by the application" ,
201+ } ;
202+ module . Add ( sysProps , stringGroupName : "sysprop" , stringGroupComment : " System properties name:value pairs" ) ;
203+
193204 dsoCache = InitDSOCache ( ) ;
194205 var app_cfg = new ApplicationConfig {
195206 uses_mono_llvm = UsesMonoLLVM ,
@@ -218,7 +229,14 @@ public override void Init ()
218229 mono_components_mask = ( uint ) MonoComponents ,
219230 android_package_name = AndroidPackageName ,
220231 } ;
221- application_config = new StructureInstance < ApplicationConfig > ( app_cfg ) ;
232+ application_config = new StructureInstance < ApplicationConfig > ( applicationConfigStructureInfo , app_cfg ) ;
233+ module . AddGlobalVariable ( "application_config" , application_config ) ;
234+
235+ var dso_cache = new LlvmIrGlobalVariable ( dsoCache , "dso_cache" , LlvmIrVariableOptions . GlobalWritable ) {
236+ Comment = " DSO cache entries" ,
237+ BeforeWriteCallback = HashAndSortDSOCache ,
238+ } ;
239+ module . Add ( dso_cache ) ;
222240
223241 if ( ! HaveAssemblyStore ) {
224242 xamarinAndroidBundledAssemblies = new List < StructureInstance < XamarinAndroidBundledAssembly > > ( NumberOfAssembliesInApk ) ;
@@ -229,13 +247,63 @@ public override void Init ()
229247 data_size = 0 ,
230248 data = 0 ,
231249 name_length = ( uint ) BundledAssemblyNameWidth ,
232- name = ' \0 ' ,
250+ name = null ,
233251 } ;
234252
235253 for ( int i = 0 ; i < NumberOfAssembliesInApk ; i ++ ) {
236- xamarinAndroidBundledAssemblies . Add ( new StructureInstance < XamarinAndroidBundledAssembly > ( emptyBundledAssemblyData ) ) ;
254+ xamarinAndroidBundledAssemblies . Add ( new StructureInstance < XamarinAndroidBundledAssembly > ( xamarinAndroidBundledAssemblyStructureInfo , emptyBundledAssemblyData ) ) ;
255+ }
256+ }
257+
258+ string bundledBuffersSize = xamarinAndroidBundledAssemblies == null ? "empty (unused when assembly stores are enabled)" : $ "{ BundledAssemblyNameWidth } bytes long";
259+ var bundled_assemblies = new LlvmIrGlobalVariable ( typeof ( List < StructureInstance < XamarinAndroidBundledAssembly > > ) , "bundled_assemblies" , LlvmIrVariableOptions . GlobalWritable ) {
260+ Value = xamarinAndroidBundledAssemblies ,
261+ Comment = $ " Bundled assembly name buffers, all { bundledBuffersSize } ",
262+ } ;
263+ module . Add ( bundled_assemblies ) ;
264+
265+ AddAssemblyStores ( module ) ;
266+ }
267+
268+ void AddAssemblyStores ( LlvmIrModule module )
269+ {
270+ ulong itemCount = ( ulong ) ( HaveAssemblyStore ? NumberOfAssembliesInApk : 0 ) ;
271+ var assembly_store_bundled_assemblies = new LlvmIrGlobalVariable ( typeof ( List < StructureInstance < AssemblyStoreSingleAssemblyRuntimeData > > ) , "assembly_store_bundled_assemblies" , LlvmIrVariableOptions . GlobalWritable ) {
272+ ZeroInitializeArray = true ,
273+ ArrayItemCount = itemCount ,
274+ } ;
275+ module . Add ( assembly_store_bundled_assemblies ) ;
276+
277+ itemCount = ( ulong ) ( HaveAssemblyStore ? NumberOfAssemblyStoresInApks : 0 ) ;
278+ var assembly_stores = new LlvmIrGlobalVariable ( typeof ( List < StructureInstance < AssemblyStoreRuntimeData > > ) , "assembly_stores" , LlvmIrVariableOptions . GlobalWritable ) {
279+ ZeroInitializeArray = true ,
280+ ArrayItemCount = itemCount ,
281+ } ;
282+ module . Add ( assembly_stores ) ;
283+ }
284+
285+ void HashAndSortDSOCache ( LlvmIrVariable variable , LlvmIrModuleTarget target , object ? state )
286+ {
287+ var cache = variable . Value as List < StructureInstance < DSOCacheEntry > > ;
288+ if ( cache == null ) {
289+ throw new InvalidOperationException ( $ "Internal error: DSO cache must no be empty") ;
290+ }
291+
292+ bool is64Bit = target . Is64Bit ;
293+ foreach ( StructureInstance instance in cache ) {
294+ if ( instance . Obj == null ) {
295+ throw new InvalidOperationException ( "Internal error: DSO cache must not contain null entries" ) ;
237296 }
297+
298+ var entry = instance . Obj as DSOCacheEntry ;
299+ if ( entry == null ) {
300+ throw new InvalidOperationException ( $ "Internal error: DSO cache entry has unexpected type { instance . Obj . GetType ( ) } ") ;
301+ }
302+
303+ entry . hash = GetXxHash ( entry . HashedName , is64Bit ) ;
238304 }
305+
306+ cache . Sort ( ( StructureInstance < DSOCacheEntry > a , StructureInstance < DSOCacheEntry > b ) => a . Instance . hash . CompareTo ( b . Instance . hash ) ) ;
239307 }
240308
241309 List < StructureInstance < DSOCacheEntry > > InitDSOCache ( )
@@ -273,7 +341,7 @@ List<StructureInstance<DSOCacheEntry>> InitDSOCache ()
273341 name = name ,
274342 } ;
275343
276- dsoCache . Add ( new StructureInstance < DSOCacheEntry > ( entry ) ) ;
344+ dsoCache . Add ( new StructureInstance < DSOCacheEntry > ( dsoCacheEntryStructureInfo , entry ) ) ;
277345 }
278346 }
279347
@@ -300,56 +368,14 @@ void AddNameMutations (string name)
300368 }
301369 }
302370
303- protected override void MapStructures ( LlvmIrGenerator generator )
304- {
305- applicationConfigStructureInfo = generator . MapStructure < ApplicationConfig > ( ) ;
306- generator . MapStructure < AssemblyStoreAssemblyDescriptor > ( ) ;
307- assemblyStoreSingleAssemblyRuntimeDataStructureinfo = generator . MapStructure < AssemblyStoreSingleAssemblyRuntimeData > ( ) ;
308- assemblyStoreRuntimeDataStructureInfo = generator . MapStructure < AssemblyStoreRuntimeData > ( ) ;
309- xamarinAndroidBundledAssemblyStructureInfo = generator . MapStructure < XamarinAndroidBundledAssembly > ( ) ;
310- dsoCacheEntryStructureInfo = generator . MapStructure < DSOCacheEntry > ( ) ;
311- }
312-
313- protected override void Write ( LlvmIrGenerator generator )
314- {
315- generator . WriteVariable ( "format_tag" , FORMAT_TAG ) ;
316- generator . WriteString ( "mono_aot_mode_name" , MonoAOTMode ) ;
317-
318- generator . WriteNameValueArray ( "app_environment_variables" , environmentVariables ) ;
319- generator . WriteNameValueArray ( "app_system_properties" , systemProperties ) ;
320-
321- generator . WriteStructure ( applicationConfigStructureInfo , application_config , LlvmIrVariableOptions . GlobalConstant , "application_config" ) ;
322-
323- WriteDSOCache ( generator ) ;
324- WriteBundledAssemblies ( generator ) ;
325- WriteAssemblyStoreAssemblies ( generator ) ;
326- }
327-
328- void WriteAssemblyStoreAssemblies ( LlvmIrGenerator generator )
329- {
330- ulong count = ( ulong ) ( HaveAssemblyStore ? NumberOfAssembliesInApk : 0 ) ;
331- generator . WriteStructureArray < AssemblyStoreSingleAssemblyRuntimeData > ( assemblyStoreSingleAssemblyRuntimeDataStructureinfo , count , "assembly_store_bundled_assemblies" , initialComment : "Assembly store individual assembly data" ) ;
332-
333- count = ( ulong ) ( HaveAssemblyStore ? NumberOfAssemblyStoresInApks : 0 ) ;
334- generator . WriteStructureArray < AssemblyStoreRuntimeData > ( assemblyStoreRuntimeDataStructureInfo , count , "assembly_stores" , initialComment : "Assembly store data" ) ;
335- }
336-
337- void WriteBundledAssemblies ( LlvmIrGenerator generator )
371+ void MapStructures ( LlvmIrModule module )
338372 {
339- generator . WriteStructureArray ( xamarinAndroidBundledAssemblyStructureInfo , xamarinAndroidBundledAssemblies , "bundled_assemblies" , initialComment : $ "Bundled assembly name buffers, all { BundledAssemblyNameWidth } bytes long") ;
340- }
341-
342- void WriteDSOCache ( LlvmIrGenerator generator )
343- {
344- bool is64Bit = generator . Is64Bit ;
345-
346- // We need to hash here, because the hash is architecture-specific
347- foreach ( StructureInstance < DSOCacheEntry > entry in dsoCache ) {
348- entry . Obj . hash = HashName ( entry . Obj . HashedName , is64Bit ) ;
349- }
350- dsoCache . Sort ( ( StructureInstance < DSOCacheEntry > a , StructureInstance < DSOCacheEntry > b ) => a . Obj . hash . CompareTo ( b . Obj . hash ) ) ;
351-
352- generator . WriteStructureArray ( dsoCacheEntryStructureInfo , dsoCache , "dso_cache" ) ;
373+ applicationConfigStructureInfo = module . MapStructure < ApplicationConfig > ( ) ;
374+ module . MapStructure < AssemblyStoreAssemblyDescriptor > ( ) ;
375+ assemblyStoreSingleAssemblyRuntimeDataStructureinfo = module . MapStructure < AssemblyStoreSingleAssemblyRuntimeData > ( ) ;
376+ assemblyStoreRuntimeDataStructureInfo = module . MapStructure < AssemblyStoreRuntimeData > ( ) ;
377+ xamarinAndroidBundledAssemblyStructureInfo = module . MapStructure < XamarinAndroidBundledAssembly > ( ) ;
378+ dsoCacheEntryStructureInfo = module . MapStructure < DSOCacheEntry > ( ) ;
353379 }
354380 }
355381}
0 commit comments