diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs index 8d596f87e43f31..dae5bc317ae47e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs @@ -132,7 +132,7 @@ public CompilationBuilder UseDwarf5(bool value) protected PreinitializationManager GetPreinitializationManager() { if (_preinitializationManager == null) - return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy(), new StaticReadOnlyFieldPolicy()); + return new PreinitializationManager(_context, _compilationGroup, GetILProvider(), new TypePreinit.DisabledPreinitializationPolicy(), new StaticReadOnlyFieldPolicy(), null); return _preinitializationManager; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/PreinitializationManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/PreinitializationManager.cs index 59aa509360464e..58b3f1f0dd6501 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/PreinitializationManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/PreinitializationManager.cs @@ -2,9 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; + using Internal.IL; using Internal.TypeSystem; +using FlowAnnotations = ILLink.Shared.TrimAnalysis.FlowAnnotations; + namespace ILCompiler { /// @@ -14,10 +17,10 @@ public class PreinitializationManager { private readonly bool _supportsLazyCctors; - public PreinitializationManager(TypeSystemContext context, CompilationModuleGroup compilationGroup, ILProvider ilprovider, TypePreinit.TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy) + public PreinitializationManager(TypeSystemContext context, CompilationModuleGroup compilationGroup, ILProvider ilprovider, TypePreinit.TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, FlowAnnotations flowAnnotations) { _supportsLazyCctors = context.SystemModule.GetType("System.Runtime.CompilerServices", "ClassConstructorRunner", throwIfNotFound: false) != null; - _preinitHashTable = new PreinitializationInfoHashtable(compilationGroup, ilprovider, policy, readOnlyPolicy); + _preinitHashTable = new PreinitializationInfoHashtable(compilationGroup, ilprovider, policy, readOnlyPolicy, flowAnnotations); } /// @@ -137,13 +140,15 @@ private sealed class PreinitializationInfoHashtable : LockFreeReaderHashtable key == value.Type; @@ -153,7 +158,7 @@ public PreinitializationInfoHashtable(CompilationModuleGroup compilationGroup, I protected override TypePreinit.PreinitializationInfo CreateValueFromKey(MetadataType key) { - var info = TypePreinit.ScanType(_compilationGroup, _ilProvider, _policy, _readOnlyPolicy, key); + var info = TypePreinit.ScanType(_compilationGroup, _ilProvider, _policy, _readOnlyPolicy, _flowAnnotations, key); // We either successfully preinitialized or // the type doesn't have a canonical form or diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs index 95b47562addfd3..e2e7a8b756e5ae 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs @@ -12,6 +12,7 @@ using Internal.TypeSystem; using CombinedDependencyList = System.Collections.Generic.List.CombinedDependencyListEntry>; +using FlowAnnotations = ILLink.Shared.TrimAnalysis.FlowAnnotations; namespace ILCompiler { @@ -36,17 +37,19 @@ public class TypePreinit private readonly ILProvider _ilProvider; private readonly TypePreinitializationPolicy _policy; private readonly ReadOnlyFieldPolicy _readOnlyPolicy; + private readonly FlowAnnotations _flowAnnotations; private readonly Dictionary _fieldValues = new Dictionary(); private readonly Dictionary _internedStrings = new Dictionary(); private readonly Dictionary _internedTypes = new Dictionary(); - private TypePreinit(MetadataType owningType, CompilationModuleGroup compilationGroup, ILProvider ilProvider, TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy) + private TypePreinit(MetadataType owningType, CompilationModuleGroup compilationGroup, ILProvider ilProvider, TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, FlowAnnotations flowAnnotations) { _type = owningType; _compilationGroup = compilationGroup; _ilProvider = ilProvider; _policy = policy; _readOnlyPolicy = readOnlyPolicy; + _flowAnnotations = flowAnnotations; // Zero initialize all fields we model. foreach (var field in owningType.GetFields()) @@ -58,7 +61,7 @@ private TypePreinit(MetadataType owningType, CompilationModuleGroup compilationG } } - public static PreinitializationInfo ScanType(CompilationModuleGroup compilationGroup, ILProvider ilProvider, TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, MetadataType type) + public static PreinitializationInfo ScanType(CompilationModuleGroup compilationGroup, ILProvider ilProvider, TypePreinitializationPolicy policy, ReadOnlyFieldPolicy readOnlyPolicy, FlowAnnotations flowAnnotations, MetadataType type) { Debug.Assert(type.HasStaticConstructor); Debug.Assert(!type.IsGenericDefinition); @@ -85,7 +88,7 @@ public static PreinitializationInfo ScanType(CompilationModuleGroup compilationG Status status; try { - preinit = new TypePreinit(type, compilationGroup, ilProvider, policy, readOnlyPolicy); + preinit = new TypePreinit(type, compilationGroup, ilProvider, policy, readOnlyPolicy, flowAnnotations); int instructions = 0; status = preinit.TryScanMethod(type.GetStaticConstructor(), null, null, ref instructions, out _); } @@ -313,6 +316,11 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack(); recursionProtect.Push(methodIL.OwningMethod); @@ -410,6 +418,11 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack= 0; i--) { @@ -514,6 +532,11 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack= 0; i--) { @@ -712,6 +735,11 @@ private Status TryScanMethod(MethodIL methodIL, Value[] parameters, Stack(T val) where T : unmanaged where U : unmanaged - => *(U*)&val; + static unsafe sbyte Read(byte val) => *(sbyte*)&val; + static unsafe short Read(ushort val) => *(short*)&val; + static unsafe int Read(uint val) => *(int*)&val; + static unsafe long Read(ulong val) => *(long*)&val; class LdindTester { - public static sbyte SByte = Read(byte.MaxValue); - public static short Short = Read(ushort.MaxValue); - public static int Int = Read(uint.MaxValue); - public static long Long = Read(ulong.MaxValue); + public static sbyte SByte = Read(byte.MaxValue); + public static short Short = Read(ushort.MaxValue); + public static int Int = Read(uint.MaxValue); + public static long Long = Read(ulong.MaxValue); } public static void Run() @@ -1367,6 +1370,22 @@ public static void Run() } } +class TestDataflow +{ + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type TheType = typeof(MyType); + + class MyType + { + public static void TheMethod() => Console.WriteLine("Hello"); + } + + public static void Run() + { + TheType.GetMethod("TheMethod").Invoke(null, []); + } +} + static class Assert { [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern",