Beispiel #1
0
        public static void AddDependenciesDueToMethodCodePresence(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
        {
            factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencies, factory, method);

            if (method.HasInstantiation)
            {
                ExactMethodInstantiationsNode.GetExactMethodInstantiationDependenciesForMethod(ref dependencies, factory, method);

                if (method.IsVirtual)
                {
                    // Generic virtual methods dependency tracking
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.Add(new DependencyListEntry(factory.GVMDependencies(method), "GVM Dependencies Support"));
                }

                GenericMethodsTemplateMap.GetTemplateMethodDependencies(ref dependencies, factory, method);
            }
            else
            {
                TypeDesc owningTemplateType = method.OwningType;

                // Unboxing and Instantiating stubs use a different type as their template
                if (factory.TypeSystemContext.IsSpecialUnboxingThunk(method))
                {
                    owningTemplateType = factory.TypeSystemContext.GetTargetOfSpecialUnboxingThunk(method).OwningType;
                }

                GenericTypesTemplateMap.GetTemplateTypeDependencies(ref dependencies, factory, owningTemplateType);
            }

            // On Project N, the compiler doesn't generate the interop code on the fly
            if (method.Context.Target.Abi != TargetAbi.ProjectN)
            {
                factory.InteropStubManager.AddDependeciesDueToPInvoke(ref dependencies, factory, method);
            }
        }
Beispiel #2
0
        public static void AddDependenciesDueToMethodCodePresence(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
        {
            factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencies, factory, method);

            if (method.HasInstantiation)
            {
                ExactMethodInstantiationsNode.GetExactMethodInstantiationDependenciesForMethod(ref dependencies, factory, method);
                GenericMethodsTemplateMap.GetTemplateMethodDependencies(ref dependencies, factory, method);
            }
            else
            {
                TypeDesc owningTemplateType = method.OwningType;

                // Unboxing and Instantiating stubs use a different type as their template
                if (factory.TypeSystemContext.IsSpecialUnboxingThunk(method))
                {
                    owningTemplateType = factory.TypeSystemContext.GetTargetOfSpecialUnboxingThunk(method).OwningType;
                }

                GenericTypesTemplateMap.GetTemplateTypeDependencies(ref dependencies, factory, owningTemplateType);
            }

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

            if (method.IsIntrinsic && factory.MetadataManager.SupportsReflection)
            {
                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;
                    }
                }
            }
        }
Beispiel #3
0
        protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
        {
            DependencyList dependencies = null;

            TypeDesc owningType = _method.OwningType;

            if (factory.TypeSystemContext.HasEagerStaticConstructor(owningType))
            {
                if (dependencies == null)
                {
                    dependencies = new DependencyList();
                }
                dependencies.Add(factory.EagerCctorIndirection(owningType.GetStaticConstructor()), "Eager .cctor");
            }

            if (_ehInfo != null && _ehInfo.Relocs != null)
            {
                if (dependencies == null)
                {
                    dependencies = new DependencyList();
                }

                foreach (Relocation reloc in _ehInfo.Relocs)
                {
                    dependencies.Add(reloc.Target, "reloc");
                }
            }

            // Reflection invoke stub handling is here because in the current reflection model we reflection-enable
            // all methods that are compiled. Ideally the list of reflection enabled methods should be known before
            // we even start the compilation process (with the invocation stubs being compilation roots like any other).
            // The existing model has it's problems: e.g. the invocability of the method depends on inliner decisions.
            if (factory.MetadataManager.HasReflectionInvokeStub(_method))
            {
                if (dependencies == null)
                {
                    dependencies = new DependencyList();
                }

                if (!_method.IsCanonicalMethod(CanonicalFormKind.Any) /* Shared generics handled in the shadow concrete method node */)
                {
                    MethodDesc invokeStub      = factory.MetadataManager.GetReflectionInvokeStub(Method);
                    MethodDesc canonInvokeStub = invokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    if (invokeStub != canonInvokeStub)
                    {
                        dependencies.Add(new DependencyListEntry(factory.FatFunctionPointer(invokeStub), "Reflection invoke"));
                    }
                    else
                    {
                        dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(invokeStub), "Reflection invoke"));
                    }
                }

                if (_method.OwningType.IsValueType && !_method.Signature.IsStatic)
                {
                    dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(_method, unboxingStub: true), "Reflection unboxing stub"));
                }
            }

            if (_method.HasInstantiation)
            {
                var exactMethodInstantiationDependencies = ExactMethodInstantiationsNode.GetExactMethodInstantiationDependenciesForMethod(factory, _method);
                if (exactMethodInstantiationDependencies != null)
                {
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.AddRange(exactMethodInstantiationDependencies);
                }

                if (_method.IsVirtual)
                {
                    // Generic virtual methods dependency tracking
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.Add(new DependencyListEntry(factory.GVMDependencies(_method), "GVM Dependencies Support"));
                }

                var templateMethodDependencies = GenericMethodsTemplateMap.GetTemplateMethodDependencies(factory, _method);
                if (templateMethodDependencies != null)
                {
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.AddRange(templateMethodDependencies);
                }
            }

            return(dependencies);
        }
Beispiel #4
0
        public static void AddDependenciesDueToMethodCodePresence(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
        {
            // Reflection invoke stub handling is here because in the current reflection model we reflection-enable
            // all methods that are compiled. Ideally the list of reflection enabled methods should be known before
            // we even start the compilation process (with the invocation stubs being compilation roots like any other).
            // The existing model has it's problems: e.g. the invocability of the method depends on inliner decisions.
            if (factory.MetadataManager.IsReflectionInvokable(method))
            {
                if (dependencies == null)
                {
                    dependencies = new DependencyList();
                }

                if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method) && !method.IsCanonicalMethod(CanonicalFormKind.Any) /* Shared generics handled in the shadow concrete method node */)
                {
                    MethodDesc invokeStub      = factory.MetadataManager.GetReflectionInvokeStub(method);
                    MethodDesc canonInvokeStub = invokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    if (invokeStub != canonInvokeStub)
                    {
                        dependencies.Add(new DependencyListEntry(factory.FatFunctionPointer(invokeStub), "Reflection invoke"));
                    }
                    else
                    {
                        dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(invokeStub), "Reflection invoke"));
                    }
                }

                bool skipUnboxingStubDependency = false;
                if (factory.Target.Abi == TargetAbi.ProjectN)
                {
                    // ProjectN compilation currently computes the presence of these stubs independent from dependency analysis here
                    // TODO: fix that issue and remove this odd treatment of unboxing stubs
                    if (!method.HasInstantiation && method.OwningType.IsValueType && method.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any) && !method.Signature.IsStatic)
                    {
                        skipUnboxingStubDependency = true;
                    }
                }

                if (method.OwningType.IsValueType && !method.Signature.IsStatic && !skipUnboxingStubDependency)
                {
                    dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(method, unboxingStub: true), "Reflection unboxing stub"));
                }

                dependencies.AddRange(ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(factory, method));
            }

            if (method.HasInstantiation)
            {
                var exactMethodInstantiationDependencies = ExactMethodInstantiationsNode.GetExactMethodInstantiationDependenciesForMethod(factory, method);
                if (exactMethodInstantiationDependencies != null)
                {
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.AddRange(exactMethodInstantiationDependencies);
                }

                if (method.IsVirtual)
                {
                    // Generic virtual methods dependency tracking
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.Add(new DependencyListEntry(factory.GVMDependencies(method), "GVM Dependencies Support"));
                }

                var templateMethodDependencies = GenericMethodsTemplateMap.GetTemplateMethodDependencies(factory, method);
                if (templateMethodDependencies != null)
                {
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.AddRange(templateMethodDependencies);
                }
            }
            else
            {
                TypeDesc owningTemplateType = method.OwningType;

                // Unboxing and Instantiating stubs use a different type as their template
                if (factory.TypeSystemContext.IsSpecialUnboxingThunk(method))
                {
                    owningTemplateType = factory.TypeSystemContext.GetTargetOfSpecialUnboxingThunk(method).OwningType;
                }

                var templateTypeDepedencies = GenericTypesTemplateMap.GetTemplateTypeDependencies(factory, owningTemplateType);
                if (templateTypeDepedencies != null)
                {
                    dependencies = dependencies ?? new DependencyList();
                    dependencies.AddRange(templateTypeDepedencies);
                }
            }
        }