private void RootMethod(IRootingServiceProvider rootProvider, MethodDesc method) { try { LibraryRootProvider.CheckCanGenerateMethod(method); // Virtual methods should be rooted as if they were called virtually if (method.IsVirtual) { MethodDesc slotMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method); rootProvider.RootVirtualMethodForReflection(slotMethod, "RD.XML root"); } if (!method.IsAbstract) { rootProvider.AddCompilationRoot(method, "RD.XML root"); } } catch (TypeSystemException) { // TODO: fail compilation if a switch was passed // Individual methods can fail to load types referenced in their signatures. // Skip them in library mode since they're not going to be callable. return; // TODO: Log as a warning } }
void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider) { MetadataLoadedInfo loadedMetadata = _loadedMetadata.Value; // Add all non-generic reflectable methods as roots. // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract. foreach (var method in loadedMetadata.MethodMappings.Keys) { if (method.HasInstantiation || method.OwningType.HasInstantiation) { continue; } if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, "Reflection root"); } else { rootProvider.AddCompilationRoot(method, "Reflection root"); } } // Root all the generic type instantiations from the pre-computed metadata foreach (var type in loadedMetadata.RequiredGenericTypes) { rootProvider.AddCompilationRoot(type, "Required instantiation"); } // Root all the generic methods (either non-generic methods on generic types, or generic methods) from // the pre-computed metadata. // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract. foreach (var method in loadedMetadata.RequiredGenericMethods) { if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, "Required instantiation"); } else { rootProvider.AddCompilationRoot(method, "Required instantiation"); } } // TODO: required generic fields. Root containing type, and add field to list in ComputeMetadata() }
private void RootType(IRootingServiceProvider rootProvider, TypeDesc type) { rootProvider.AddCompilationRoot(type, "RD.XML root"); if (type.IsGenericDefinition) { return; } if (type.IsDefType) { foreach (var method in type.GetMethods()) { // We don't know what to instantiate generic methods over if (method.HasInstantiation) { continue; } try { LibraryRootProvider.CheckCanGenerateMethod(method); // Virtual methods should be rooted as if they were called virtually if (method.IsVirtual) { MethodDesc slotMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method); rootProvider.RootVirtualMethodForReflection(slotMethod, "RD.XML root"); } if (!method.IsAbstract) { rootProvider.AddCompilationRoot(method, "RD.XML root"); } } catch (TypeSystemException) { // TODO: fail compilation if a switch was passed // Individual methods can fail to load types referenced in their signatures. // Skip them in library mode since they're not going to be callable. continue; // TODO: Log as a warning } } } }
public static void RootMethod(IRootingServiceProvider rootProvider, MethodDesc method, string reason) { // Make sure we're not putting something into the graph that will crash later. LibraryRootProvider.CheckCanGenerateMethod(method); // Virtual methods should be rooted as if they were called virtually if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, reason); } if (!method.IsAbstract) { rootProvider.AddCompilationRoot(method, reason); } }
void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider) { // We go over all the types and members that need a runtime artifact present in the // compiled executable and root it. const string reason = "Reflection"; foreach (var pair in _reflectableTypes) { if ((pair.Value & MetadataCategory.RuntimeMapping) != 0) { rootProvider.AddCompilationRoot(pair.Key, reason); } } foreach (var pair in _reflectableMethods) { if ((pair.Value & MetadataCategory.RuntimeMapping) != 0) { MethodDesc method = pair.Key; // We need to root virtual methods as if they were called virtually. // This will possibly trigger the generation of other overrides too. if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, reason); } if (!method.IsAbstract) { rootProvider.AddCompilationRoot(pair.Key, reason); } } } foreach (var pair in _reflectableFields) { if ((pair.Value & MetadataCategory.RuntimeMapping) != 0) { FieldDesc field = pair.Key; // We only care about static fields at this point. Instance fields don't need // runtime artifacts generated in the image. if (field.IsStatic && !field.IsLiteral) { if (field.IsThreadStatic) { rootProvider.RootThreadStaticBaseForType(field.OwningType, reason); } else if (field.HasGCStaticBase) { rootProvider.RootGCStaticBaseForType(field.OwningType, reason); } else { rootProvider.RootNonGCStaticBaseForType(field.OwningType, reason); } } } } }
void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider) { MetadataLoadedInfo loadedMetadata = _loadedMetadata.Value; // Add all non-generic reflectable types as roots. foreach (var type in loadedMetadata.TypesWithStrongMetadataMappings) { rootProvider.AddCompilationRoot(type, "Required non-generic type"); } // Add all non-generic reflectable methods as roots. // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract. foreach (var method in loadedMetadata.MethodMappings.Keys) { if (method.HasInstantiation || method.OwningType.HasInstantiation) { continue; } if (!IsMethodSupportedInPrecomputedReflection(method)) { continue; } if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, "Reflection root"); } else { if (method.IsConstructor) { rootProvider.AddCompilationRoot(method.OwningType, "Type for method reflection root"); } rootProvider.AddCompilationRoot(method, "Reflection root"); } } // Root all the generic type instantiations from the pre-computed metadata foreach (var type in loadedMetadata.RequiredGenericTypes) { rootProvider.AddCompilationRoot(type, "Required generic type"); } // Root all the generic methods (either non-generic methods on generic types, or generic methods) from // the pre-computed metadata. // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract. foreach (var method in loadedMetadata.RequiredGenericMethods) { if (!IsMethodSupportedInPrecomputedReflection(method)) { continue; } if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, "Required generic method"); } if (!method.IsAbstract) { if (method.IsConstructor) { rootProvider.AddCompilationRoot(method.OwningType, "Type for method required generic method"); } rootProvider.AddCompilationRoot(method, "Required generic method"); } } foreach (var field in loadedMetadata.RequiredGenericFields) { rootProvider.AddCompilationRoot(field.OwningType, "Required generic field's owning type"); if (field.IsThreadStatic) { rootProvider.RootThreadStaticBaseForType(field.OwningType, "Required generic field"); } else if (field.IsStatic) { if (field.HasGCStaticBase) { rootProvider.RootGCStaticBaseForType(field.OwningType, "Required generic field"); } else { rootProvider.RootNonGCStaticBaseForType(field.OwningType, "Required generic field"); } } } foreach (var type in loadedMetadata.RequiredTemplateTypes) { Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); rootProvider.AddCompilationRoot(type, "Compiler determined template"); } foreach (var method in loadedMetadata.RequiredTemplateMethods) { Debug.Assert(method.IsCanonicalMethod(CanonicalFormKind.Any)); if (method.IsVirtual) { rootProvider.RootVirtualMethodForReflection(method, "Compiler determined template"); } if (!method.IsAbstract) { if (method.IsConstructor) { rootProvider.AddCompilationRoot(method.OwningType, "Type for method compiler determined template method"); } rootProvider.AddCompilationRoot(method, "Compiler determined template"); } } }