Example #1
0
        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());
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
                            }
                        }
                    }
                }
            }
        }