protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList result = new DependencyList(); // Include the layout as a dependency if the canonical type isn't imported TypeDesc canonicalOwningType = _owningType.ConvertToCanonForm(CanonicalFormKind.Specific); if (factory.CompilationModuleGroup.ContainsType(canonicalOwningType) || !factory.CompilationModuleGroup.ShouldReferenceThroughImportTable(canonicalOwningType)) { result.Add(GetDictionaryLayout(factory), "Layout"); } // Lazy generic use of the Activator.CreateInstance<T> heuristic requires tracking type parameters that are used in lazy generics. if (factory.LazyGenericsPolicy.UsesLazyGenerics(_owningType)) { foreach (var arg in _owningType.Instantiation) { // Skip types that do not have a default constructor (not interesting). if (arg.IsValueType || arg.GetDefaultConstructor() == null || !ConstructedEETypeNode.CreationAllowed(arg)) { continue; } result.Add(new DependencyListEntry( factory.ConstructedTypeSymbol(arg.ConvertToCanonForm(CanonicalFormKind.Specific)), "Default constructor for lazy generics")); } } return(result); }
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) { // If there is a constructed version of this node in the graph, emit that instead if (ConstructedEETypeNode.CreationAllowed(_type)) { return(((DependencyNode)factory.ConstructedTypeSymbol(_type)).Marked); } return(false); }
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory) { DependencyList dependencies = new DependencyList(); MethodDesc canonicalTarget = _owningMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); if (factory.CompilationModuleGroup.ContainsMethodBody(canonicalTarget, false)) { dependencies.Add(GetDictionaryLayout(factory), "Layout"); } GenericMethodsHashtableNode.GetGenericMethodsHashtableDependenciesForMethod(ref dependencies, factory, _owningMethod); factory.InteropStubManager.AddMarshalAPIsGenericDependencies(ref dependencies, factory, _owningMethod); // Lazy generic use of the Activator.CreateInstance<T> heuristic requires tracking type parameters that are used in lazy generics. if (factory.LazyGenericsPolicy.UsesLazyGenerics(_owningMethod)) { foreach (var arg in _owningMethod.OwningType.Instantiation) { // Skip types that do not have a default constructor (not interesting). if (arg.IsValueType || arg.GetDefaultConstructor() == null || !ConstructedEETypeNode.CreationAllowed(arg)) { continue; } dependencies.Add(new DependencyListEntry( factory.ConstructedTypeSymbol(arg.ConvertToCanonForm(CanonicalFormKind.Specific)), "Default constructor for lazy generics")); } foreach (var arg in _owningMethod.Instantiation) { // Skip types that do not have a default constructor (not interesting). if (arg.IsValueType || arg.GetDefaultConstructor() == null || !ConstructedEETypeNode.CreationAllowed(arg)) { continue; } dependencies.Add(new DependencyListEntry( factory.ConstructedTypeSymbol(arg.ConvertToCanonForm(CanonicalFormKind.Specific)), "Default constructor for lazy generics")); } } // Make sure the dictionary can also be populated dependencies.Add(factory.ShadowConcreteMethod(_owningMethod), "Dictionary contents"); // Generic virtual method dictionaries need extra tracking if (_owningMethod.IsVirtual) { dependencies.Add(new DependencyListEntry(factory.GVMDependencies(_owningMethod), "GVM Dependencies Support for method dictionary")); } return(dependencies); }
public IEETypeNode MaximallyConstructableType(TypeDesc type) { if (ConstructedEETypeNode.CreationAllowed(type)) { return(ConstructedTypeSymbol(type)); } else { return(NecessaryTypeSymbol(type)); } }
public static void GetTemplateTypeDependencies(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { if (!factory.MetadataManager.SupportsReflection) { return; } TypeDesc templateType = ConvertArrayOfTToRegularArray(factory, type); if (!IsEligibleToHaveATemplate(templateType)) { return; } if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. IDependencyNode node; if (ConstructedEETypeNode.CreationAllowed(templateType)) { node = factory.ConstructedTypeSymbol(templateType); } else { node = factory.NecessaryTypeSymbol(templateType); } if (!node.Marked) { return; } } dependencies = dependencies ?? new DependencyList(); dependencies.Add(new DependencyListEntry(factory.NecessaryTypeSymbol(templateType), "Template type")); dependencies.Add(new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout(templateType), "Template Type Layout")); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // Dependencies for this node are tracked by the method code nodes if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } // Ensure the native layout data has been saved, in order to get valid Vertex offsets for the signature Vertices factory.MetadataManager.NativeLayoutInfo.SaveNativeLayoutInfoWriter(factory); NativeWriter nativeWriter = new NativeWriter(); VertexHashtable hashtable = new VertexHashtable(); Section nativeSection = nativeWriter.NewSection(); nativeSection.Place(hashtable); foreach (TypeDesc type in factory.MetadataManager.GetTypesWithConstructedEETypes()) { if (!IsEligibleToHaveATemplate(type)) { continue; } if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { // If the type does not have fully constructed type, don't track its dependencies. // TODO: Remove the workaround once we stop using the STS dependency analysis. IDependencyNode node; if (ConstructedEETypeNode.CreationAllowed(type)) { node = factory.ConstructedTypeSymbol(type); } else { node = factory.NecessaryTypeSymbol(type); } if (!node.Marked) { continue; } } // Type's native layout info NativeLayoutTemplateTypeLayoutVertexNode templateNode = factory.NativeLayout.TemplateTypeLayout(type); // If this template isn't considered necessary, don't emit it. if (!templateNode.Marked) { continue; } Vertex nativeLayout = templateNode.SavedVertex; // Hashtable Entry Vertex entry = nativeWriter.GetTuple( nativeWriter.GetUnsignedConstant(_externalReferences.GetIndex(factory.NecessaryTypeSymbol(type))), nativeWriter.GetUnsignedConstant((uint)nativeLayout.VertexOffset)); // Add to the hash table, hashed by the containing type's hashcode uint hashCode = (uint)type.GetHashCode(); hashtable.Append(hashCode, nativeSection.Place(entry)); } byte[] streamBytes = nativeWriter.Save(); _endSymbol.SetSymbolOffset(streamBytes.Length); return(new ObjectData(streamBytes, Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this, _endSymbol })); }