Example #1
0
        public static void AddDependenciesDueToMethodCodePresence(ref DependencyList dependencies, NodeFactory factory, MethodDesc method, MethodIL methodIL)
        {
            factory.MetadataManager.GetDependenciesDueToMethodCodePresence(ref dependencies, factory, method, methodIL);

            factory.InteropStubManager.AddDependenciesDueToPInvoke(ref dependencies, factory, method);

            if (method.OwningType is MetadataType mdType)
            {
                ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencies, factory, mdType.Module);
            }

            if (method.IsIntrinsic)
            {
                if (method.OwningType is MetadataType owningType)
                {
                    string name = method.Name;

                    switch (name)
                    {
                    // The general purpose code in Comparer/EqualityComparer Create method depends on the template
                    // type loader being able to load the necessary types at runtime.
                    case "Create":
                        if (method.IsSharedByGenericInstantiations &&
                            owningType.Module == factory.TypeSystemContext.SystemModule &&
                            owningType.Namespace == "System.Collections.Generic")
                        {
                            TypeDesc[] templateDependencies = null;

                            if (owningType.Name == "Comparer`1")
                            {
                                templateDependencies = Internal.IL.Stubs.ComparerIntrinsics.GetPotentialComparersForType(
                                    owningType.Instantiation[0]);
                            }
                            else if (owningType.Name == "EqualityComparer`1")
                            {
                                templateDependencies = Internal.IL.Stubs.ComparerIntrinsics.GetPotentialEqualityComparersForType(
                                    owningType.Instantiation[0]);
                            }

                            if (templateDependencies != null)
                            {
                                dependencies = dependencies ?? new DependencyList();
                                foreach (TypeDesc templateType in templateDependencies)
                                {
                                    dependencies.Add(factory.NativeLayout.TemplateTypeLayout(templateType), "Generic comparer");
                                }
                            }
                        }
                        break;
                    }
                }
            }
        }
Example #2
0
        protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
        {
            DependencyList dependencyList = new DependencyList();

            if (factory.PreinitializationManager.HasEagerStaticConstructor(_type))
            {
                dependencyList.Add(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor");
            }

            ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencyList, factory, _type.Module);

            EETypeNode.AddDependenciesForStaticsNode(factory, _type, ref dependencyList);

            return(dependencyList);
        }
Example #3
0
        public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory)
        {
            DependencyList result = new DependencyList();

            result.Add(new DependencyListEntry(GetGCStaticEETypeNode(factory), "ThreadStatic MethodTable"));

            if (factory.PreinitializationManager.HasEagerStaticConstructor(_type))
            {
                result.Add(new DependencyListEntry(factory.EagerCctorIndirection(_type.GetStaticConstructor()), "Eager .cctor"));
            }

            ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref result, factory, _type.Module);

            EETypeNode.AddDependenciesForStaticsNode(factory, _type, ref result);
            return(result);
        }
        protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
        {
            DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory);

            // Ensure that we track the necessary type symbol if we are working with a constructed type symbol.
            // The emitter will ensure we don't emit both, but this allows us assert that we only generate
            // relocs to nodes we emit.
            dependencyList.Add(factory.NecessaryTypeSymbol(_type), "NecessaryType for constructed type");

            if (_type is MetadataType mdType)
            {
                ModuleUseBasedDependencyAlgorithm.AddDependenciesDueToModuleUse(ref dependencyList, factory, mdType.Module);
            }

            DefType closestDefType = _type.GetClosestDefType();

            if (MightHaveInterfaceDispatchMap(factory))
            {
                dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map");
            }

            if (_type.IsArray)
            {
                // Array MethodTable depends on System.Array's virtuals. Array EETypes don't point to
                // their base type (i.e. there's no reloc based dependency making this "just work").
                dependencyList.Add(factory.ConstructedTypeSymbol(_type.BaseType), "Array base type");

                ArrayType arrayType = (ArrayType)_type;
                if (arrayType.IsMdArray && arrayType.Rank == 1)
                {
                    // Allocating an MDArray of Rank 1 with zero lower bounds results in allocating
                    // an SzArray instead. Make sure the type loader can find the SzArray type.
                    dependencyList.Add(factory.ConstructedTypeSymbol(arrayType.ElementType.MakeArrayType()), "Rank 1 array");
                }
            }

            dependencyList.Add(factory.VTable(closestDefType), "VTable");

            if (factory.TypeSystemContext.SupportsUniversalCanon)
            {
                foreach (var instantiationType in _type.Instantiation)
                {
                    if (instantiationType.IsValueType)
                    {
                        // All valuetype generic parameters of a constructed type may be effectively constructed. This is generally not that
                        // critical, but in the presence of universal generics the compiler may generate a Box followed by calls to ToString,
                        // GetHashcode or Equals in ways that cannot otherwise be detected by dependency analysis. Thus force all struct type
                        // generic parameters to be considered constructed when walking dependencies of a constructed generic
                        dependencyList.Add(factory.ConstructedTypeSymbol(instantiationType.ConvertToCanonForm(CanonicalFormKind.Specific)),
                                           "Struct generic parameters in constructed types may be assumed to be used as constructed in constructed generic types");
                    }
                }
            }

            // Ask the metadata manager if we have any dependencies due to reflectability.
            factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencyList, factory, _type);

            factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type);

            // Keep track of the default constructor map dependency for this type if it has a default constructor
            // We only do this for reflection blocked types because dataflow analysis is responsible for
            // generating default constructors for Activator.CreateInstance in other cases.
            MethodDesc defaultCtor = closestDefType.GetDefaultConstructor();

            if (defaultCtor != null && factory.MetadataManager.IsReflectionBlocked(defaultCtor))
            {
                dependencyList.Add(new DependencyListEntry(
                                       factory.CanonicalEntrypoint(defaultCtor),
                                       "DefaultConstructorNode"));
            }

            return(dependencyList);
        }