Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 public IEETypeNode MaximallyConstructableType(TypeDesc type)
 {
     if (ConstructedEETypeNode.CreationAllowed(type))
     {
         return(ConstructedTypeSymbol(type));
     }
     else
     {
         return(NecessaryTypeSymbol(type));
     }
 }
Exemplo n.º 5
0
        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"));
        }
Exemplo n.º 6
0
        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 }));
        }