Esempio n. 1
0
        /// <summary>
        /// Gets the node representing the target method of the delegate if no runtime lookup is needed.
        /// </summary>
        public ISymbolNode GetTargetNode(NodeFactory factory)
        {
            Debug.Assert(!NeedsRuntimeLookup);
            switch (_targetKind)
            {
            case TargetKind.CanonicalEntrypoint:
                return(factory.CanonicalEntrypoint(TargetMethod, TargetMethodIsUnboxingThunk));

            case TargetKind.ExactCallableAddress:
                return(factory.ExactCallableAddress(TargetMethod, TargetMethodIsUnboxingThunk));

            case TargetKind.InterfaceDispatch:
                return(factory.InterfaceDispatchCell(TargetMethod));

            case TargetKind.MethodHandle:
                return(factory.RuntimeMethodHandle(TargetMethod));

            case TargetKind.VTableLookup:
                Debug.Fail("Need to do runtime lookup");
                return(null);

            default:
                Debug.Assert(false);
                return(null);
            }
        }
Esempio n. 2
0
        public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            switch (lookupKind)
            {
            case ReadyToRunHelperId.TypeHandle:
                return(NodeFactory.ConstructedTypeSymbol((TypeDesc)targetOfLookup));

            case ReadyToRunHelperId.NecessaryTypeHandle:
                return(NodeFactory.NecessaryTypeSymbol((TypeDesc)targetOfLookup));

            case ReadyToRunHelperId.TypeHandleForCasting:
            {
                var type = (TypeDesc)targetOfLookup;
                if (type.IsNullable)
                {
                    targetOfLookup = type.Instantiation[0];
                }
                return(NodeFactory.NecessaryTypeSymbol((TypeDesc)targetOfLookup));
            }

            case ReadyToRunHelperId.MethodDictionary:
                return(NodeFactory.MethodGenericDictionary((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.MethodEntry:
                return(NodeFactory.FatFunctionPointer((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.MethodHandle:
                return(NodeFactory.RuntimeMethodHandle((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.FieldHandle:
                return(NodeFactory.RuntimeFieldHandle((FieldDesc)targetOfLookup));

            case ReadyToRunHelperId.DefaultConstructor:
            {
                var        type = (TypeDesc)targetOfLookup;
                MethodDesc ctor = type.GetDefaultConstructor();
                if (ctor == null)
                {
                    MetadataType activatorType        = TypeSystemContext.SystemModule.GetKnownType("System", "Activator");
                    MetadataType classWithMissingCtor = activatorType.GetKnownNestedType("ClassWithMissingConstructor");
                    ctor = classWithMissingCtor.GetParameterlessConstructor();
                }
                return(NodeFactory.CanonicalEntrypoint(ctor));
            }

            case ReadyToRunHelperId.ObjectAllocator:
            {
                var type = (TypeDesc)targetOfLookup;
                return(NodeFactory.ExternSymbol(JitHelper.GetNewObjectHelperForType(type)));
            }

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 3
0
            public void AddCompilationRoot(MethodDesc method, string reason, string exportName = null)
            {
                IMethodNode methodEntryPoint = _factory.CanonicalEntrypoint(method);

                _graph.AddRoot(methodEntryPoint, reason);

                if (exportName != null)
                {
                    _factory.NodeAliases.Add(methodEntryPoint, exportName);
                }
            }
Esempio n. 4
0
        public ISymbolNode ComputeConstantLookup(ReadyToRunHelperId lookupKind, object targetOfLookup)
        {
            switch (lookupKind)
            {
            case ReadyToRunHelperId.TypeHandle:
                return(NodeFactory.ConstructedTypeSymbol(WithoutFunctionPointerType((TypeDesc)targetOfLookup)));

            case ReadyToRunHelperId.NecessaryTypeHandle:
                return(NecessaryTypeSymbolIfPossible(WithoutFunctionPointerType((TypeDesc)targetOfLookup)));

            case ReadyToRunHelperId.TypeHandleForCasting:
            {
                var type = (TypeDesc)targetOfLookup;
                if (type.IsNullable)
                {
                    targetOfLookup = type.Instantiation[0];
                }
                return(NecessaryTypeSymbolIfPossible((TypeDesc)targetOfLookup));
            }

            case ReadyToRunHelperId.MethodDictionary:
                return(NodeFactory.MethodGenericDictionary((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.MethodEntry:
                return(NodeFactory.FatFunctionPointer((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.MethodHandle:
                return(NodeFactory.RuntimeMethodHandle((MethodDesc)targetOfLookup));

            case ReadyToRunHelperId.FieldHandle:
                return(NodeFactory.RuntimeFieldHandle((FieldDesc)targetOfLookup));

            case ReadyToRunHelperId.DefaultConstructor:
            {
                var        type = (TypeDesc)targetOfLookup;
                MethodDesc ctor = GetConstructorForCreateInstanceIntrinsic(type);
                return(NodeFactory.CanonicalEntrypoint(ctor));
            }

            case ReadyToRunHelperId.ObjectAllocator:
            {
                var type = (TypeDesc)targetOfLookup;
                return(NodeFactory.ExternSymbol(JitHelper.GetNewObjectHelperForType(type)));
            }

            default:
                throw new NotImplementedException();
            }
        }
Esempio n. 5
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");
                        }
                    }
                }
            }
        }
Esempio n. 6
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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 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 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");
                    }
                }
            }
        }