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; } } } }
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); }
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); }