diff options
Diffstat (limited to 'src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs | 97 |
1 files changed, 60 insertions, 37 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs index 0e333d323..a005fa379 100644 --- a/src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs +++ b/src/ILCompiler.Compiler/src/Compiler/PrecomputedMetadataManager.cs @@ -33,6 +33,7 @@ namespace ILCompiler public ImmutableArray<ModuleDesc> LocalMetadataModules = ImmutableArray<ModuleDesc>.Empty; public ImmutableArray<ModuleDesc> ExternalMetadataModules = ImmutableArray<ModuleDesc>.Empty; public List<MetadataType> TypesWithStrongMetadataMappings = new List<MetadataType>(); + public Dictionary<MetadataType, int> WeakReflectedTypeMappings = new Dictionary<MetadataType, int>(); public Dictionary<MetadataType, int> AllTypeMappings = new Dictionary<MetadataType, int>(); public Dictionary<MethodDesc, int> MethodMappings = new Dictionary<MethodDesc, int>(); public Dictionary<FieldDesc, int> FieldMappings = new Dictionary<FieldDesc, int>(); @@ -62,9 +63,15 @@ namespace ILCompiler IEnumerable<ModuleDesc> compilationModules, IEnumerable<ModuleDesc> inputMetadataOnlyAssemblies, byte[] metadataBlob, - StackTraceEmissionPolicy stackTraceEmissionPolicy) - : base(typeSystemContext, new AttributeSpecifiedBlockingPolicy()) + StackTraceEmissionPolicy stackTraceEmissionPolicy, + ManifestResourceBlockingPolicy resourceBlockingPolicy, + bool disableInvokeThunks) + : base(typeSystemContext, new AttributeSpecifiedBlockingPolicy(), resourceBlockingPolicy, + disableInvokeThunks ? (DynamicInvokeThunkGenerationPolicy)new NoDynamicInvokeThunkGenerationPolicy() : new PrecomputedDynamicInvokeThunkGenerationPolicy()) { + // Need to do this dance because C# won't let us access `this` in the `base()` expression above. Sigh. + (_dynamicInvokeThunkGenerationPolicy as PrecomputedDynamicInvokeThunkGenerationPolicy)?.SetParentWorkaround(this); + _compilationModuleGroup = group; _metadataDescribingModule = metadataDescribingModule; _compilationModules = new HashSet<ModuleDesc>(compilationModules); @@ -400,7 +407,7 @@ namespace ILCompiler MethodIL weakMethodIL = ilProvider.GetMethodIL(weakMetadataMethod); Dictionary<MethodDesc, int> weakMethodMappings = new Dictionary<MethodDesc, int>(); Dictionary<FieldDesc, int> weakFieldMappings = new Dictionary<FieldDesc, int>(); - ReadMetadataMethod(weakMethodIL, result.AllTypeMappings, weakMethodMappings, weakFieldMappings, metadataModules); + ReadMetadataMethod(weakMethodIL, result.WeakReflectedTypeMappings, weakMethodMappings, weakFieldMappings, metadataModules); if ((weakMethodMappings.Count > 0) || (weakFieldMappings.Count > 0)) { // the format does not permit weak field/method mappings @@ -538,7 +545,7 @@ namespace ILCompiler } } - if (metadataType.ThreadStaticFieldSize.AsInt > 0) + if (metadataType.ThreadGcStaticFieldSize.AsInt > 0) { dependencies.Add(((UtcNodeFactory)factory).TypeThreadStaticsOffsetSymbol(metadataType), "Thread statics for ReflectionFieldMap entry"); } @@ -706,7 +713,7 @@ namespace ILCompiler continue; int token; - if (loadedMetadata.AllTypeMappings.TryGetValue(definition, out token)) + if (loadedMetadata.AllTypeMappings.TryGetValue(definition, out token) || loadedMetadata.WeakReflectedTypeMappings.TryGetValue(definition, out token)) { typeMappings.Add(new MetadataMapping<MetadataType>(definition, token)); } @@ -739,6 +746,14 @@ namespace ILCompiler AddFieldMapping(field, canonicalFieldsAddedToMap, fieldMappings); } + foreach (var typeMapping in loadedMetadata.WeakReflectedTypeMappings) + { + // Imported types that are also declared as weak reflected types need to be added to the TypeMap table, but only if they are also + // reachable from static compilation (node marked in the dependency analysis graph) + if (factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(typeMapping.Key) && factory.NecessaryTypeSymbol(typeMapping.Key).Marked) + typeMappings.Add(new MetadataMapping<MetadataType>(typeMapping.Key, typeMapping.Value)); + } + stackTraceMapping = GenerateStackTraceMetadata(factory); } @@ -894,38 +909,6 @@ namespace ILCompiler } /// <summary> - /// Is there a reflection invoke stub for a method that is invokable? - /// </summary> - public override bool HasReflectionInvokeStubForInvokableMethod(MethodDesc method) - { - Debug.Assert(IsReflectionInvokable(method)); - - if (!ProjectNDependencyBehavior.EnableFullAnalysis) - { - if (method.IsCanonicalMethod(CanonicalFormKind.Any)) - return false; - } - else - { - if (method.IsCanonicalMethod(CanonicalFormKind.Universal)) - return false; - } - - MethodDesc reflectionInvokeStub = GetCanonicalReflectionInvokeStub(method); - - if (reflectionInvokeStub == null) - return false; - - // TODO: Generate DynamicInvokeTemplateMap dependencies correctly. For now, force all canonical stubs to go through the - // calling convention converter interpreter path. - if (reflectionInvokeStub.IsSharedByGenericInstantiations) - return false; - - return true; - } - - - /// <summary> /// Gets a stub that can be used to reflection-invoke a method with a given signature. /// </summary> public override MethodDesc GetCanonicalReflectionInvokeStub(MethodDesc method) @@ -1040,5 +1023,45 @@ namespace ILCompiler public bool IsBlocked(MethodDesc methodDef) => false; public ModuleDesc GetModuleOfType(MetadataType typeDef) => typeDef.Module; } + + private sealed class PrecomputedDynamicInvokeThunkGenerationPolicy : DynamicInvokeThunkGenerationPolicy + { + private PrecomputedMetadataManager _parent; + + public PrecomputedDynamicInvokeThunkGenerationPolicy() + { + } + + public void SetParentWorkaround(PrecomputedMetadataManager parent) + { + _parent = parent; + } + + public override bool HasStaticInvokeThunk(MethodDesc method) + { + if (!ProjectNDependencyBehavior.EnableFullAnalysis) + { + if (method.IsCanonicalMethod(CanonicalFormKind.Any)) + return false; + } + else + { + if (method.IsCanonicalMethod(CanonicalFormKind.Universal)) + return false; + } + + MethodDesc reflectionInvokeStub = _parent.GetCanonicalReflectionInvokeStub(method); + + if (reflectionInvokeStub == null) + return false; + + // TODO: Generate DynamicInvokeTemplateMap dependencies correctly. For now, force all canonical stubs to go through the + // calling convention converter interpreter path. + if (reflectionInvokeStub.IsSharedByGenericInstantiations) + return false; + + return true; + } + } } } |