public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory context) { // TODO: https://github.com/dotnet/corert/issues/3224 // 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 (context.MetadataManager.IsReflectionInvokable(_method) && _method.IsAbstract) { DependencyList dependencies = new DependencyList(); if (context.MetadataManager.HasReflectionInvokeStubForInvokableMethod(_method) && !_method.IsCanonicalMethod(CanonicalFormKind.Any)) { MethodDesc invokeStub = context.MetadataManager.GetReflectionInvokeStub(_method); MethodDesc canonInvokeStub = invokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific); if (invokeStub != canonInvokeStub) { dependencies.Add(new DependencyListEntry(context.MetadataManager.DynamicInvokeTemplateData, "Reflection invoke template data")); context.MetadataManager.DynamicInvokeTemplateData.AddDependenciesDueToInvokeTemplatePresence(ref dependencies, context, canonInvokeStub); } else { dependencies.Add(new DependencyListEntry(context.MethodEntrypoint(invokeStub), "Reflection invoke")); } } dependencies.AddRange(ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(context, _method)); return(dependencies); } return(Array.Empty <DependencyListEntry>()); }
public static void AddDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { if (factory.MetadataManager.IsReflectionInvokable(method)) { if (dependencies == null) { dependencies = new DependencyList(); } dependencies.Add(factory.MaximallyConstructableType(method.OwningType), "Reflection invoke"); if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method) && ((factory.Target.Abi != TargetAbi.ProjectN) || ProjectNDependencyBehavior.EnableFullAnalysis || !method.IsCanonicalMethod(CanonicalFormKind.Any))) { MethodDesc canonInvokeStub = factory.MetadataManager.GetCanonicalReflectionInvokeStub(method); if (canonInvokeStub.IsSharedByGenericInstantiations) { dependencies.Add(new DependencyListEntry(factory.MetadataManager.DynamicInvokeTemplateData, "Reflection invoke template data")); factory.MetadataManager.DynamicInvokeTemplateData.AddDependenciesDueToInvokeTemplatePresence(ref dependencies, factory, canonInvokeStub); } else { dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(canonInvokeStub), "Reflection invoke")); } } bool skipUnboxingStubDependency = false; if ((factory.Target.Abi == TargetAbi.ProjectN) && !ProjectNDependencyBehavior.EnableFullAnalysis) { // 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.ExactCallableAddress(method, isUnboxingStub: true), "Reflection unboxing stub")); } // If the method is defined in a different module than this one, a metadata token isn't known for performing the reference // Use a name/sig reference instead. if (!factory.MetadataManager.WillUseMetadataTokenToReferenceMethod(method)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition())), "Non metadata-local method reference")); } if (method.HasInstantiation && method.IsCanonicalMethod(CanonicalFormKind.Universal)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method)), "UniversalCanon signature of method")); } ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(ref dependencies, factory, method); } }
public static void AddDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { Debug.Assert(factory.MetadataManager.IsReflectionInvokable(method)); if (dependencies == null) { dependencies = new DependencyList(); } dependencies.Add(factory.MaximallyConstructableType(method.OwningType), "Reflection invoke"); if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method)) { MethodDesc canonInvokeStub = factory.MetadataManager.GetCanonicalReflectionInvokeStub(method); if (canonInvokeStub.IsSharedByGenericInstantiations) { dependencies.Add(new DependencyListEntry(factory.DynamicInvokeTemplate(canonInvokeStub), "Reflection invoke")); } else { dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(canonInvokeStub), "Reflection invoke")); } } if (method.OwningType.IsValueType && !method.Signature.IsStatic) { dependencies.Add(new DependencyListEntry(factory.ExactCallableAddress(method, isUnboxingStub: true), "Reflection unboxing stub")); } // If the method is defined in a different module than this one, a metadata token isn't known for performing the reference // Use a name/sig reference instead. if (!factory.MetadataManager.WillUseMetadataTokenToReferenceMethod(method)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition())), "Non metadata-local method reference")); } if (method.HasInstantiation) { bool useUnboxingStub = method.OwningType.IsValueType && !method.Signature.IsStatic; if (method.IsCanonicalMethod(CanonicalFormKind.Universal)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method)), "UniversalCanon signature of method")); } else if (!method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg() || method.IsAbstract) { foreach (var instArg in method.Instantiation) { dependencies.Add(factory.NecessaryTypeSymbol(instArg), "Reflectable generic method inst arg"); } } } ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(ref dependencies, factory, method); }
public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory) { List <DependencyListEntry> dependencies = new List <DependencyListEntry>(); // 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(_decl) && _decl.IsAbstract) { if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(_decl) && !_decl.IsCanonicalMethod(CanonicalFormKind.Any)) { MethodDesc invokeStub = factory.MetadataManager.GetReflectionInvokeStub(_decl); 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")); } } dependencies.AddRange(ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(factory, _decl)); } MethodDesc canonDecl = _decl.GetCanonMethodTarget(CanonicalFormKind.Specific); if (canonDecl != _decl) { dependencies.Add(new DependencyListEntry(factory.VirtualMethodUse(canonDecl), "Canonical method")); } dependencies.Add(new DependencyListEntry(factory.VTable(_decl.OwningType), "VTable of a VirtualMethodUse")); return(dependencies); }
public static void AddDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { // TODO: https://github.com/dotnet/corert/issues/3224 // 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) && ((factory.Target.Abi != TargetAbi.ProjectN) || !method.IsCanonicalMethod(CanonicalFormKind.Any))) { MethodDesc canonInvokeStub = factory.MetadataManager.GetCanonicalReflectionInvokeStub(method); if (canonInvokeStub.IsSharedByGenericInstantiations) { dependencies.Add(new DependencyListEntry(factory.MetadataManager.DynamicInvokeTemplateData, "Reflection invoke template data")); factory.MetadataManager.DynamicInvokeTemplateData.AddDependenciesDueToInvokeTemplatePresence(ref dependencies, factory, canonInvokeStub); } else { dependencies.Add(new DependencyListEntry(factory.MethodEntrypoint(canonInvokeStub), "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")); } // If the method is defined in a different module than this one, a metadata token isn't known for performing the reference // Use a name/sig reference instead. if (!factory.MetadataManager.WillUseMetadataTokenToReferenceMethod(method)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition())), "Non metadata-local method reference")); } if (method.HasInstantiation && method.IsCanonicalMethod(CanonicalFormKind.Universal)) { dependencies.Add(new DependencyListEntry(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method)), "UniversalCanon signature of method")); } ReflectionVirtualInvokeMapNode.GetVirtualInvokeMapDependencies(ref dependencies, factory, method); } }
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); } } }