diff options
author | Michal Strehovský <michals@microsoft.com> | 2017-12-08 17:17:48 +0300 |
---|---|---|
committer | Michal Strehovský <michals@microsoft.com> | 2017-12-18 14:28:54 +0300 |
commit | b5d9787448020192b7986de45d1bcd54696ef123 (patch) | |
tree | 0ccf8c5ad7ae8d3de709ceee9af6f52ff9fa030d | |
parent | f3006294bf15992688207dd751f9f96386437315 (diff) |
Split CompilerGeneratedMetadataManager
Two classes now:
* Things that are shared by all MD managers that generate metadata
* Things that are only relevent for MD managers that generate statical-usage-based metadata
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs (renamed from src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedMetadataManager.cs) | 142 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs | 2 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs | 143 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj | 3 | ||||
-rw-r--r-- | src/ILCompiler/src/Program.cs | 3 |
5 files changed, 169 insertions, 124 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs index 893f39163..9e9fdc742 100644 --- a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedMetadataManager.cs +++ b/src/ILCompiler.Compiler/src/Compiler/GeneratingMetadataManager.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -16,22 +16,20 @@ using ILCompiler.Metadata; using ILCompiler.DependencyAnalysis; using Debug = System.Diagnostics.Debug; -using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore<ILCompiler.DependencyAnalysis.NodeFactory>.DependencyList; namespace ILCompiler { /// <summary> - /// This class is responsible for managing native metadata to be emitted into the compiled - /// module. It applies a policy that every type/method emitted shall be reflectable. + /// Base class for metadata managers that generate metadata blobs. /// </summary> - public sealed class CompilerGeneratedMetadataManager : MetadataManager + public abstract class GeneratingMetadataManager : MetadataManager { private readonly string _metadataLogFile; private readonly StackTraceEmissionPolicy _stackTraceEmissionPolicy; - private Dictionary<DynamicInvokeMethodSignature, MethodDesc> _dynamicInvokeThunks; + private readonly Dictionary<DynamicInvokeMethodSignature, MethodDesc> _dynamicInvokeThunks; - public CompilerGeneratedMetadataManager(CompilationModuleGroup group, CompilerTypeSystemContext typeSystemContext, string logFile, StackTraceEmissionPolicy stackTracePolicy) - : base(group, typeSystemContext, new BlockedInternalsBlockingPolicy()) + public GeneratingMetadataManager(CompilationModuleGroup group, CompilerTypeSystemContext typeSystemContext, MetadataBlockingPolicy blockingPolicy, string logFile, StackTraceEmissionPolicy stackTracePolicy) + : base(group, typeSystemContext, blockingPolicy) { _metadataLogFile = logFile; _stackTraceEmissionPolicy = stackTracePolicy; @@ -42,69 +40,26 @@ namespace ILCompiler } } - public override bool WillUseMetadataTokenToReferenceMethod(MethodDesc method) + public sealed override bool WillUseMetadataTokenToReferenceMethod(MethodDesc method) { return (GetMetadataCategory(method) & MetadataCategory.Description) != 0; } - public override bool WillUseMetadataTokenToReferenceField(FieldDesc field) + public sealed override bool WillUseMetadataTokenToReferenceField(FieldDesc field) { return (GetMetadataCategory(field) & MetadataCategory.Description) != 0; } - protected override MetadataCategory GetMetadataCategory(FieldDesc field) + protected void ComputeMetadata<TPolicy>( + TPolicy policy, + NodeFactory factory, + out byte[] metadataBlob, + out List<MetadataMapping<MetadataType>> typeMappings, + out List<MetadataMapping<MethodDesc>> methodMappings, + out List<MetadataMapping<FieldDesc>> fieldMappings, + out List<MetadataMapping<MethodDesc>> stackTraceMapping) where TPolicy : struct, IMetadataPolicy { - MetadataCategory category = 0; - - if (!IsReflectionBlocked(field)) - { - category = MetadataCategory.RuntimeMapping; - - if (_compilationModuleGroup.ContainsType(field.GetTypicalFieldDefinition().OwningType)) - category |= MetadataCategory.Description; - } - - return category; - } - - protected override MetadataCategory GetMetadataCategory(MethodDesc method) - { - MetadataCategory category = 0; - - if (!IsReflectionBlocked(method)) - { - category = MetadataCategory.RuntimeMapping; - - if (_compilationModuleGroup.ContainsType(method.GetTypicalMethodDefinition().OwningType)) - category |= MetadataCategory.Description; - } - - return category; - } - - protected override MetadataCategory GetMetadataCategory(TypeDesc type) - { - MetadataCategory category = 0; - - if (!IsReflectionBlocked(type)) - { - category = MetadataCategory.RuntimeMapping; - - if (_compilationModuleGroup.ContainsType(type.GetTypeDefinition())) - category |= MetadataCategory.Description; - } - - return category; - } - - protected override void ComputeMetadata(NodeFactory factory, - out byte[] metadataBlob, - out List<MetadataMapping<MetadataType>> typeMappings, - out List<MetadataMapping<MethodDesc>> methodMappings, - out List<MetadataMapping<FieldDesc>> fieldMappings, - out List<MetadataMapping<MethodDesc>> stackTraceMapping) - { - var transformed = MetadataTransform.Run(new GeneratedTypesAndCodeMetadataPolicy(_blockingPolicy, factory), GetCompilationModulesWithMetadata()); + var transformed = MetadataTransform.Run(policy, GetCompilationModulesWithMetadata()); MetadataTransform transform = transformed.Transform; // TODO: DeveloperExperienceMode: Use transformed.Transform.HandleType() to generate @@ -133,7 +88,7 @@ namespace ILCompiler continue; MetadataRecord record = transform.HandleQualifiedMethod(typicalMethod); - + // As a twist, instantiated generic methods appear as if instantiated over their formals. if (typicalMethod.HasInstantiation) { @@ -159,7 +114,7 @@ namespace ILCompiler writer.AdditionalRootRecords.Add(record); } - + var ms = new MemoryStream(); // .NET metadata is UTF-16 and UTF-16 contains code points that don't translate to UTF-8. @@ -248,7 +203,7 @@ namespace ILCompiler /// <summary> /// Is there a reflection invoke stub for a method that is invokable? /// </summary> - public override bool HasReflectionInvokeStubForInvokableMethod(MethodDesc method) + public sealed override bool HasReflectionInvokeStubForInvokableMethod(MethodDesc method) { Debug.Assert(IsReflectionInvokable(method)); @@ -267,7 +222,7 @@ namespace ILCompiler /// <summary> /// Gets a stub that can be used to reflection-invoke a method with a given signature. /// </summary> - public override MethodDesc GetCanonicalReflectionInvokeStub(MethodDesc method) + public sealed override MethodDesc GetCanonicalReflectionInvokeStub(MethodDesc method) { TypeSystemContext context = method.Context; var sig = method.Signature; @@ -283,60 +238,5 @@ namespace ILCompiler return InstantiateCanonicalDynamicInvokeMethodForMethod(thunk, method); } - - protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) - { - dependencies = dependencies ?? new DependencyList(); - dependencies.Add(factory.MethodMetadata(method.GetTypicalMethodDefinition()), "Reflectable method"); - } - - protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) - { - TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); - } - - private struct GeneratedTypesAndCodeMetadataPolicy : IMetadataPolicy - { - private readonly MetadataBlockingPolicy _blockingPolicy; - private readonly NodeFactory _factory; - private readonly ExplicitScopeAssemblyPolicyMixin _explicitScopeMixin; - - public GeneratedTypesAndCodeMetadataPolicy(MetadataBlockingPolicy blockingPolicy, NodeFactory factory) - { - _blockingPolicy = blockingPolicy; - _factory = factory; - _explicitScopeMixin = new ExplicitScopeAssemblyPolicyMixin(); - } - - public bool GeneratesMetadata(FieldDesc fieldDef) - { - return _factory.FieldMetadata(fieldDef).Marked; - } - - public bool GeneratesMetadata(MethodDesc methodDef) - { - return _factory.MethodMetadata(methodDef).Marked; - } - - public bool GeneratesMetadata(MetadataType typeDef) - { - return _factory.TypeMetadata(typeDef).Marked; - } - - public bool IsBlocked(MetadataType typeDef) - { - return _blockingPolicy.IsBlocked(typeDef); - } - - public bool IsBlocked(MethodDesc methodDef) - { - return _blockingPolicy.IsBlocked(methodDef); - } - - public ModuleDesc GetModuleOfType(MetadataType typeDef) - { - return _explicitScopeMixin.GetModuleOfType(typeDef); - } - } } } diff --git a/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs b/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs index 81b8458c9..86ee40cd0 100644 --- a/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs +++ b/src/ILCompiler.Compiler/src/Compiler/ILScannerBuilder.cs @@ -46,7 +46,7 @@ namespace ILCompiler public IILScanner ToILScanner() { // TODO: we will want different metadata managers depending on whether we're doing reflection analysis - var metadataManager = new CompilerGeneratedMetadataManager(_compilationGroup, _context, null, new NoStackTraceEmissionPolicy()); + var metadataManager = new UsageBasedMetadataManager(_compilationGroup, _context, new BlockedInternalsBlockingPolicy(), null, new NoStackTraceEmissionPolicy()); var interopStubManager = new CompilerGeneratedInteropStubManager(_compilationGroup, _context, new InteropStateManager(_compilationGroup.GeneratedAssembly)); var nodeFactory = new ILScanNodeFactory(_context, _compilationGroup, metadataManager, interopStubManager, _nameMangler); DependencyAnalyzerBase<NodeFactory> graph = _dependencyTrackingLevel.CreateDependencyGraph(nodeFactory); diff --git a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs new file mode 100644 index 000000000..568afc5b6 --- /dev/null +++ b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs @@ -0,0 +1,143 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +using Internal.TypeSystem; + +using ILCompiler.Metadata; +using ILCompiler.DependencyAnalysis; + +using DependencyList = ILCompiler.DependencyAnalysisFramework.DependencyNodeCore<ILCompiler.DependencyAnalysis.NodeFactory>.DependencyList; + +namespace ILCompiler +{ + /// <summary> + /// This class is responsible for managing native metadata to be emitted into the compiled + /// module. It applies a policy that every type/method that is statically used shall be reflectable. + /// </summary> + public sealed class UsageBasedMetadataManager : GeneratingMetadataManager + { + public UsageBasedMetadataManager( + CompilationModuleGroup group, + CompilerTypeSystemContext typeSystemContext, + MetadataBlockingPolicy blockingPolicy, + string logFile, + StackTraceEmissionPolicy stackTracePolicy) + : base(group, typeSystemContext, blockingPolicy, logFile, stackTracePolicy) + { + } + + protected override MetadataCategory GetMetadataCategory(FieldDesc field) + { + MetadataCategory category = 0; + + if (!IsReflectionBlocked(field)) + { + category = MetadataCategory.RuntimeMapping; + + if (_compilationModuleGroup.ContainsType(field.GetTypicalFieldDefinition().OwningType)) + category |= MetadataCategory.Description; + } + + return category; + } + + protected override MetadataCategory GetMetadataCategory(MethodDesc method) + { + MetadataCategory category = 0; + + if (!IsReflectionBlocked(method)) + { + category = MetadataCategory.RuntimeMapping; + + if (_compilationModuleGroup.ContainsType(method.GetTypicalMethodDefinition().OwningType)) + category |= MetadataCategory.Description; + } + + return category; + } + + protected override MetadataCategory GetMetadataCategory(TypeDesc type) + { + MetadataCategory category = 0; + + if (!IsReflectionBlocked(type)) + { + category = MetadataCategory.RuntimeMapping; + + if (_compilationModuleGroup.ContainsType(type.GetTypeDefinition())) + category |= MetadataCategory.Description; + } + + return category; + } + + protected override void ComputeMetadata(NodeFactory factory, + out byte[] metadataBlob, + out List<MetadataMapping<MetadataType>> typeMappings, + out List<MetadataMapping<MethodDesc>> methodMappings, + out List<MetadataMapping<FieldDesc>> fieldMappings, + out List<MetadataMapping<MethodDesc>> stackTraceMapping) + { + ComputeMetadata(new GeneratedTypesAndCodeMetadataPolicy(_blockingPolicy, factory), + factory, out metadataBlob, out typeMappings, out methodMappings, out fieldMappings, out stackTraceMapping); + } + + protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) + { + dependencies = dependencies ?? new DependencyList(); + dependencies.Add(factory.MethodMetadata(method.GetTypicalMethodDefinition()), "Reflectable method"); + } + + protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + { + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); + } + + private struct GeneratedTypesAndCodeMetadataPolicy : IMetadataPolicy + { + private readonly MetadataBlockingPolicy _blockingPolicy; + private readonly NodeFactory _factory; + private readonly ExplicitScopeAssemblyPolicyMixin _explicitScopeMixin; + + public GeneratedTypesAndCodeMetadataPolicy(MetadataBlockingPolicy blockingPolicy, NodeFactory factory) + { + _blockingPolicy = blockingPolicy; + _factory = factory; + _explicitScopeMixin = new ExplicitScopeAssemblyPolicyMixin(); + } + + public bool GeneratesMetadata(FieldDesc fieldDef) + { + return _factory.FieldMetadata(fieldDef).Marked; + } + + public bool GeneratesMetadata(MethodDesc methodDef) + { + return _factory.MethodMetadata(methodDef).Marked; + } + + public bool GeneratesMetadata(MetadataType typeDef) + { + return _factory.TypeMetadata(typeDef).Marked; + } + + public bool IsBlocked(MetadataType typeDef) + { + return _blockingPolicy.IsBlocked(typeDef); + } + + public bool IsBlocked(MethodDesc methodDef) + { + return _blockingPolicy.IsBlocked(methodDef); + } + + public ModuleDesc GetModuleOfType(MetadataType typeDef) + { + return _explicitScopeMixin.GetModuleOfType(typeDef); + } + } + } +} diff --git a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj index 43cc9b802..febe21611 100644 --- a/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj +++ b/src/ILCompiler.Compiler/src/ILCompiler.Compiler.csproj @@ -137,6 +137,7 @@ <Compile Include="Compiler\EmptyInteropStubManager.cs" /> <Compile Include="Compiler\DependencyAnalysis\SortableDependencyNode.cs" /> <Compile Include="Compiler\DependencyAnalysis\ImportedNodeProvider.cs" /> + <Compile Include="Compiler\GeneratingMetadataManager.cs" /> <Compile Include="Compiler\InternalCompilerErrorException.cs" /> <Compile Include="Compiler\PreInitFieldInfo.cs" /> <Compile Include="Compiler\DependencyAnalysis\FrozenArrayNode.cs" /> @@ -321,7 +322,6 @@ <Compile Include="Compiler\MainMethodRootProvider.cs" /> <Compile Include="Compiler\ManagedBinaryEmitter.cs" /> <Compile Include="Compiler\MemoryHelper.cs" /> - <Compile Include="Compiler\CompilerGeneratedMetadataManager.cs" /> <Compile Include="Compiler\MergedAssemblyRecords.cs" /> <Compile Include="Compiler\MetadataManager.cs" /> <Compile Include="Compiler\InteropStubManager.cs" /> @@ -343,6 +343,7 @@ <Compile Include="Compiler\TypeExtensions.cs" /> <Compile Include="Compiler\CompilerTypeSystemContext.TypeInit.cs" /> <Compile Include="Compiler\CoreRTNameMangler.cs" /> + <Compile Include="Compiler\UsageBasedMetadataManager.cs" /> <Compile Include="Compiler\UserDefinedTypeDescriptor.cs" /> <Compile Include="Compiler\UniversalGenericsRootProvider.cs" /> <Compile Include="Compiler\UnixNodeMangler.cs" /> diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs index e3efa2321..a57948b90 100644 --- a/src/ILCompiler/src/Program.cs +++ b/src/ILCompiler/src/Program.cs @@ -418,9 +418,10 @@ namespace ILCompiler var stackTracePolicy = _emitStackTraceData ? (StackTraceEmissionPolicy)new EcmaMethodStackTraceEmissionPolicy() : new NoStackTraceEmissionPolicy(); - CompilerGeneratedMetadataManager metadataManager = new CompilerGeneratedMetadataManager( + UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager( compilationGroup, typeSystemContext, + new BlockedInternalsBlockingPolicy(), _metadataLogFileName, stackTracePolicy); |