protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } // TODO: use a better owning type for multi-file friendliness _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(TypeSystemContext.SystemModule.GetGlobalModuleType()); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, ILProvider ilProvider, DevirtualizationManager devirtualizationManager, IEnumerable <ModuleDesc> modulesBeingInstrumented, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _devirtualizationManager = devirtualizationManager; _modulesBeingInstrumented = new HashSet <ModuleDesc>(modulesBeingInstrumented); _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(nodeFactory, _dependencyGraph.AddRoot); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } _methodILCache = new ILCache(ilProvider, NodeFactory.CompilationModuleGroup); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType()); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType()); bool?forceLazyPInvokeResolution = null; // TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet // https://github.com/dotnet/corert/issues/2454 // https://github.com/dotnet/corert/issues/2149 if (this is CppCodegenCompilation) { forceLazyPInvokeResolution = false; } PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution), nodeFactory.InteropStubManager.InteropStateManager); _methodILCache = new ILProvider(PInvokeILProvider); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, NameMangler nameMangler, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _nameMangler = nameMangler; _logger = logger; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); // TODO: hacky static field NodeFactory.NameMangler = nameMangler; var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, DevirtualizationManager devirtualizationManager, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _debugInformationProvider = debugInformationProvider; _devirtualizationManager = devirtualizationManager; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(dependencyGraph, nodeFactory); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } MetadataType globalModuleGeneratedType = nodeFactory.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType(); _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType); _assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType); _methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache(); if (!(nodeFactory.InteropStubManager is EmptyInteropStubManager)) { bool?forceLazyPInvokeResolution = null; // TODO: Workaround lazy PInvoke resolution not working with CppCodeGen yet // https://github.com/dotnet/corert/issues/2454 // https://github.com/dotnet/corert/issues/2149 if (nodeFactory.IsCppCodegenTemporaryWorkaround) { forceLazyPInvokeResolution = false; } PInvokeILProvider = new PInvokeILProvider(new PInvokeILEmitterConfiguration(forceLazyPInvokeResolution), nodeFactory.InteropStubManager.InteropStateManager); ilProvider = new CombinedILProvider(ilProvider, PInvokeILProvider); } _methodILCache = new ILCache(ilProvider); }
protected Compilation( DependencyAnalyzerBase <NodeFactory> dependencyGraph, NodeFactory nodeFactory, IEnumerable <ICompilationRootProvider> compilationRoots, ILProvider ilProvider, DebugInformationProvider debugInformationProvider, DevirtualizationManager devirtualizationManager, IInliningPolicy inliningPolicy, Logger logger) { _dependencyGraph = dependencyGraph; _nodeFactory = nodeFactory; _logger = logger; _debugInformationProvider = debugInformationProvider; _devirtualizationManager = devirtualizationManager; _inliningPolicy = inliningPolicy; _dependencyGraph.ComputeDependencyRoutine += ComputeDependencyNodeDependencies; NodeFactory.AttachToDependencyGraph(_dependencyGraph); var rootingService = new RootingServiceProvider(nodeFactory, _dependencyGraph.AddRoot); foreach (var rootProvider in compilationRoots) { rootProvider.AddCompilationRoots(rootingService); } MetadataType globalModuleGeneratedType = nodeFactory.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType(); _typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType); _assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType); _methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache(); PInvokeILProvider = _nodeFactory.InteropStubManager.CreatePInvokeILProvider(); if (PInvokeILProvider != null) { ilProvider = new CombinedILProvider(ilProvider, PInvokeILProvider); } _methodILCache = new ILCache(ilProvider); }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (type is MetadataType metadataType && metadataType.HasInstantiation && !metadataType.IsGenericDefinition && metadataType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && metadataType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } // If the option was specified to root types and methods in all user assemblies, do that. if ((_generationOptions & UsageBasedMetadataGenerationOptions.FullUserAssemblyRooting) != 0) { if (type is MetadataType metadataType && !_rootAllAssembliesExaminedModules.Contains(metadataType.Module)) { _rootAllAssembliesExaminedModules.Add(metadataType.Module); if (metadataType.Module is Internal.TypeSystem.Ecma.EcmaModule ecmaModule && !FrameworkStringResourceBlockingPolicy.IsFrameworkAssembly(ecmaModule)) { dependencies = dependencies ?? new DependencyList(); var rootProvider = new RootingServiceProvider(factory, dependencies.Add); foreach (TypeDesc t in ecmaModule.GetAllTypes()) { RootingHelpers.TryRootType(rootProvider, t, "RD.XML root"); } } } } // If a type is marked [Serializable], make sure a couple things are also included. if (type.IsSerializable && !type.IsGenericDefinition) { foreach (MethodDesc method in type.GetAllMethods()) { MethodSignature signature = method.Signature; if (method.IsConstructor && signature.Length == 2 && signature[0] == _serializationInfoType /* && signature[1] is StreamingContext */) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } // Methods with these attributes can be called during serialization if (signature.Length == 1 && !signature.IsStatic && signature.ReturnType.IsVoid && (method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnSerializedAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializingAttribute") || method.HasCustomAttribute("System.Runtime.Serialization", "OnDeserializedAttribute"))) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Binary serialization"); } } } // Event sources need their special nested types if (type is MetadataType mdType && mdType.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute")) { AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Keywords")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Tasks")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Opcodes")); void AddEventSourceSpecialTypeDependencies(ref DependencyList dependencies, NodeFactory factory, MetadataType type) { if (type != null) { const string reason = "Event source"; dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.TypeMetadata(type), reason); foreach (FieldDesc field in type.GetFields()) { if (field.IsLiteral) { dependencies.Add(factory.FieldMetadata(field), reason); } } } } } }
protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); // If we don't have precise field usage information, apply policy that all fields that // are eligible to have metadata get metadata. if (!_hasPreciseFieldUsageInformation) { TypeDesc typeDefinition = type.GetTypeDefinition(); foreach (FieldDesc field in typeDefinition.GetFields()) { if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); } } } MetadataType mdType = type as MetadataType; // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have // method bodies for all properties. It's common to have anonymous types used with reflection // and it's hard to specify them in RD.XML. if ((_generationOptions & UsageBasedMetadataGenerationOptions.AnonymousTypeHeuristic) != 0) { if (mdType != null && mdType.HasInstantiation && !mdType.IsGenericDefinition && mdType.HasCustomAttribute("System.Runtime.CompilerServices", "CompilerGeneratedAttribute") && mdType.Name.Contains("AnonymousType")) { foreach (MethodDesc method in type.GetMethods()) { if (!method.Signature.IsStatic && method.IsSpecialName) { dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.CanonicalEntrypoint(method), "Anonymous type accessor"); } } } } ModuleDesc module = mdType?.Module; if (module != null && !_rootEntireAssembliesExaminedModules.Contains(module)) { // If the owning assembly needs to be fully compiled, do that. _rootEntireAssembliesExaminedModules.Add(module); string assemblyName = module.Assembly.GetName().Name; bool fullyRoot; string reason; if (_rootEntireAssembliesModules.Contains(assemblyName)) { // If the assembly was specified as a root on the command line, root it fullyRoot = true; reason = "Rooted from command line"; } else if (_trimmedAssemblies.Contains(assemblyName) || IsTrimmableAssembly(module)) { // If the assembly was specified as trimmed on the command line, do not root // If the assembly is marked trimmable via an attribute, do not root fullyRoot = false; reason = null; } else { // If rooting default assemblies was requested, root fullyRoot = (_generationOptions & UsageBasedMetadataGenerationOptions.RootDefaultAssemblies) != 0; reason = "Assemblies rooted from command line"; } if (fullyRoot) { dependencies = dependencies ?? new DependencyList(); var rootProvider = new RootingServiceProvider(factory, dependencies.Add); foreach (TypeDesc t in mdType.Module.GetAllTypes()) { RootingHelpers.TryRootType(rootProvider, t, reason); } } } // Event sources need their special nested types if (mdType != null && mdType.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute")) { AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Keywords")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Tasks")); AddEventSourceSpecialTypeDependencies(ref dependencies, factory, mdType.GetNestedType("Opcodes")); void AddEventSourceSpecialTypeDependencies(ref DependencyList dependencies, NodeFactory factory, MetadataType type) { if (type != null) { const string reason = "Event source"; dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.TypeMetadata(type), reason); foreach (FieldDesc field in type.GetFields()) { if (field.IsLiteral) { dependencies.Add(factory.FieldMetadata(field), reason); } } } } } }