diff options
Diffstat (limited to 'src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index a835bc1f7..d145a8d26 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -80,7 +80,7 @@ namespace ILCompiler.DependencyAnalysis DefType closestDefType = _type.GetClosestDefType(); - if (_type.RuntimeInterfaces.Length > 0) + if (InterfaceDispatchMapNode.MightHaveInterfaceDispatchMap(_type, factory)) { dependencyList.Add(factory.InterfaceDispatchMap(_type), "Interface dispatch map"); } @@ -115,6 +115,22 @@ namespace ILCompiler.DependencyAnalysis dependencyList.Add(factory.NativeLayout.TemplateTypeLayout(canonType), "Template Type Layout"); } + if (factory.TypeSystemContext.SupportsUniversalCanon) + { + foreach (var instantiationType in _type.Instantiation) + { + if (instantiationType.IsValueType) + { + // All valuetype generic parameters of a constructed type may be effectively constructed. This is generally not that + // critical, but in the presence of universal generics the compiler may generate a Box followed by calls to ToString, + // GetHashcode or Equals in ways that cannot otherwise be detected by dependency analysis. Thus force all struct type + // generic parameters to be considered constructed when walking dependencies of a constructed generic + dependencyList.Add(factory.ConstructedTypeSymbol(instantiationType.ConvertToCanonForm(CanonicalFormKind.Specific)), + "Struct generic parameters in constructed types may be assumed to be used as constructed in constructed generic types"); + } + } + } + // Generated type contains generic virtual methods that will get added to the GVM tables if (TypeGVMEntriesNode.TypeNeedsGVMTableEntries(_type)) { @@ -135,6 +151,15 @@ namespace ILCompiler.DependencyAnalysis factory.InteropStubManager.AddInterestingInteropConstructedTypeDependencies(ref dependencyList, factory, _type); + // Keep track of the default constructor map dependency for this type if it has a default constructor + MethodDesc defaultCtor = closestDefType.GetDefaultConstructor(); + if (defaultCtor != null) + { + dependencyList.Add(new DependencyListEntry( + factory.MethodEntrypoint(defaultCtor.GetCanonMethodTarget(CanonicalFormKind.Specific), closestDefType.IsValueType), + "DefaultConstructorNode")); + } + return dependencyList; } @@ -179,10 +204,6 @@ namespace ILCompiler.DependencyAnalysis if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) return false; - // Byref-like types have interior pointers and cannot be heap allocated. - if (type.IsByRefLike) - return false; - // The global "<Module>" type can never be allocated. if (((MetadataType)type).IsModuleType) return false; @@ -199,6 +220,6 @@ namespace ILCompiler.DependencyAnalysis ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadGeneral, type); } - protected internal override int ClassCode => 590142654; + public override int ClassCode => 590142654; } } |