diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2017-12-29 12:50:40 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-29 12:50:40 +0300 |
commit | 8a83d68707a12b39bc15bb5c2350f234dbb0ca55 (patch) | |
tree | cdca783fdcbd32f35fa946dab650da4f34f961ad | |
parent | 6738ef2f1ba5a4ed881b4c325f1f0519ee7e9302 (diff) |
Route LDTOKEN dependencies through MetadataManager (#5158)
The presence of `RuntimeMethodHandle`/`RuntimeFieldHandle` data structure should only imply the need of metadata if we're generating/collecting metadata from usage.
Closes #3224. This was the last place that needed fixes.
4 files changed, 44 insertions, 20 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs index c1285477f..57a4018fd 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeFieldHandleNode.cs @@ -37,18 +37,9 @@ namespace ILCompiler.DependencyAnalysis protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { - // TODO: https://github.com/dotnet/corert/issues/3224 - // We should figure out reflectable fields when scanning for reflection - FieldDesc fieldDefinition = _targetField.GetTypicalFieldDefinition(); - if (factory.MetadataManager.CanGenerateMetadata(fieldDefinition)) - { - return new DependencyList - { - new DependencyListEntry(factory.FieldMetadata(fieldDefinition), "LDTOKEN") - }; - } - - return null; + DependencyList result = null; + factory.MetadataManager.GetDependenciesDueToLdToken(ref result, factory, _targetField); + return result; } public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs index 79bf416c3..c40987f3c 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/RuntimeMethodHandleNode.cs @@ -50,14 +50,7 @@ namespace ILCompiler.DependencyAnalysis dependencies.Add(factory.GVMDependencies(_targetMethod), "GVM dependencies for runtime method handle"); } - // TODO: https://github.com/dotnet/corert/issues/3224 - // We should figure out reflectable methods when scanning for reflection - MethodDesc methodDefinition = _targetMethod.GetTypicalMethodDefinition(); - if (factory.MetadataManager.CanGenerateMetadata(methodDefinition)) - { - dependencies = dependencies ?? new DependencyList(); - dependencies.Add(factory.MethodMetadata(methodDefinition), "LDTOKEN"); - } + factory.MetadataManager.GetDependenciesDueToLdToken(ref dependencies, factory, _targetMethod); return dependencies; } diff --git a/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs index 1cbc5e6b4..ab86d40e2 100644 --- a/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs +++ b/src/ILCompiler.Compiler/src/Compiler/MetadataManager.cs @@ -408,6 +408,24 @@ namespace ILCompiler } /// <summary> + /// This method is an extension point that can provide additional metadata-based dependencies to generated RuntimeMethodHandles. + /// </summary> + public virtual void GetDependenciesDueToLdToken(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) + { + // MetadataManagers can override this to provide additional dependencies caused by the presence of a + // RuntimeMethodHandle data structure. + } + + /// <summary> + /// This method is an extension point that can provide additional metadata-based dependencies to generated RuntimeFieldHandles. + /// </summary> + public virtual void GetDependenciesDueToLdToken(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) + { + // MetadataManagers can override this to provide additional dependencies caused by the presence of a + // RuntimeFieldHandle data structure. + } + + /// <summary> /// Given that a method is invokable, does there exist a reflection invoke stub? /// </summary> public abstract bool HasReflectionInvokeStubForInvokableMethod(MethodDesc method); diff --git a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs index 6100d991f..f13cc6735 100644 --- a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs +++ b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs @@ -194,6 +194,28 @@ namespace ILCompiler } } + public override void GetDependenciesDueToLdToken(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) + { + // In order for the RuntimeFieldHandle data structure to be usable at runtime, ensure the field + // is generating metadata. + if ((GetMetadataCategory(field) & MetadataCategory.Description) == MetadataCategory.Description) + { + dependencies = dependencies ?? new DependencyList(); + dependencies.Add(factory.FieldMetadata(field.GetTypicalFieldDefinition()), "LDTOKEN field"); + } + } + + public override void GetDependenciesDueToLdToken(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) + { + // In order for the RuntimeMethodHandle data structure to be usable at runtime, ensure the method + // is generating metadata. + if ((GetMetadataCategory(method) & MetadataCategory.Description) == MetadataCategory.Description) + { + dependencies = dependencies ?? new DependencyList(); + dependencies.Add(factory.MethodMetadata(method.GetTypicalMethodDefinition()), "LDTOKEN method"); + } + } + protected override IEnumerable<FieldDesc> GetFieldsWithRuntimeMapping() { if (_hasPreciseFieldUsageInformation) |