Imported Upstream version 5.20.0.180

Former-commit-id: ff953ca879339fe1e1211f7220f563e1342e66cb
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-02-04 20:11:37 +00:00
parent 0e2d47d1c8
commit 0510252385
3360 changed files with 83827 additions and 39243 deletions

View File

@@ -25,16 +25,17 @@ namespace ILCompiler
private readonly Dictionary<FieldDesc, MetadataCategory> _reflectableFields = new Dictionary<FieldDesc, MetadataCategory>();
public AnalysisBasedMetadataManager(
ModuleDesc generatedAssembly,
CompilerTypeSystemContext typeSystemContext,
MetadataBlockingPolicy blockingPolicy,
ManifestResourceBlockingPolicy resourceBlockingPolicy,
string logFile,
StackTraceEmissionPolicy stackTracePolicy,
DynamicInvokeThunkGenerationPolicy invokeThunkGenerationPolicy,
IEnumerable<ModuleDesc> modulesWithMetadata,
IEnumerable<ReflectableEntity<TypeDesc>> reflectableTypes,
IEnumerable<ReflectableEntity<MethodDesc>> reflectableMethods,
IEnumerable<ReflectableEntity<FieldDesc>> reflectableFields)
: base(generatedAssembly, typeSystemContext, blockingPolicy, logFile, stackTracePolicy)
: base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy)
{
_modulesWithMetadata = new List<ModuleDesc>(modulesWithMetadata);

View File

@@ -58,7 +58,7 @@ namespace ILCompiler
foreach (var rootProvider in compilationRoots)
rootProvider.AddCompilationRoots(rootingService);
MetadataType globalModuleGeneratedType = nodeFactory.CompilationModuleGroup.GeneratedAssembly.GetGlobalModuleType();
MetadataType globalModuleGeneratedType = nodeFactory.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType();
_typeGetTypeMethodThunks = new TypeGetTypeMethodThunkCache(globalModuleGeneratedType);
_assemblyGetExecutingAssemblyMethodThunks = new AssemblyGetExecutingAssemblyMethodThunkCache(globalModuleGeneratedType);
_methodBaseGetCurrentMethodThunks = new MethodBaseGetCurrentMethodThunkCache();
@@ -90,6 +90,12 @@ namespace ILCompiler
public DelegateCreationInfo GetDelegateCtor(TypeDesc delegateType, MethodDesc target, bool followVirtualDispatch)
{
// If we're creating a delegate to a virtual method that cannot be overriden, devirtualize.
// This is not just an optimization - it's required for correctness in the presence of sealed
// vtable slots.
if (followVirtualDispatch && (target.IsFinal || target.OwningType.IsSealed()))
followVirtualDispatch = false;
return DelegateCreationInfo.Create(delegateType, target, NodeFactory, followVirtualDispatch);
}
@@ -102,7 +108,7 @@ namespace ILCompiler
{
var pInvokeFixup = (PInvokeLazyFixupField)field;
PInvokeMetadata metadata = pInvokeFixup.PInvokeMetadata;
return NodeFactory.PInvokeMethodFixup(metadata.Module, metadata.Name);
return NodeFactory.PInvokeMethodFixup(metadata.Module, metadata.Name, metadata.Flags);
}
else
{
@@ -360,7 +366,7 @@ namespace ILCompiler
Debug.Assert(!type.IsGenericDefinition);
MetadataType metadataType = type as MetadataType;
if (metadataType != null && metadataType.ThreadStaticFieldSize.AsInt > 0)
if (metadataType != null && metadataType.ThreadGcStaticFieldSize.AsInt > 0)
{
_graph.AddRoot(_factory.TypeThreadStaticIndex(metadataType), reason);
@@ -413,7 +419,16 @@ namespace ILCompiler
public void RootModuleMetadata(ModuleDesc module, string reason)
{
_graph.AddRoot(_factory.ModuleMetadata(module), reason);
// RootModuleMetadata is kind of a hack - this is pretty much only used to force include
// type forwarders from assemblies metadata generator would normally not look at.
// This will go away when the temporary RD.XML parser goes away.
if (_factory.MetadataManager is UsageBasedMetadataManager)
_graph.AddRoot(_factory.ModuleMetadata(module), reason);
}
public void RootReadOnlyDataBlob(byte[] data, int alignment, string reason, string exportName)
{
_graph.AddRoot(_factory.ReadOnlyDataBlob(exportName, data, alignment), reason);
}
}
}

View File

@@ -21,17 +21,6 @@ namespace ILCompiler
public abstract class CompilationModuleGroup
{
/// <summary>
/// Gets the synthetic assembly that holds types generated by the compiler as part of the compilation process.
/// Types and members that declare this module as their owning module are always generated.
/// </summary>
public ModuleDesc GeneratedAssembly { get; }
public CompilationModuleGroup(TypeSystemContext context)
{
GeneratedAssembly = new CompilerGeneratedAssembly(context);
}
/// <summary>
/// If true, "type" is in the set of input assemblies being compiled
/// </summary>
@@ -49,6 +38,10 @@ namespace ILCompiler
/// </summary>
public abstract bool ContainsMethodDictionary(MethodDesc method);
/// <summary>
/// If true, "method" is imported from the set of reference assemblies
/// </summary>
public abstract bool ImportsMethod(MethodDesc method, bool unboxingStub);
/// <summary>
/// If true, "type" is exported by the set of input assemblies being compiled
/// </summary>
public abstract ExportForm GetExportTypeForm(TypeDesc type);
@@ -94,41 +87,5 @@ namespace ILCompiler
/// accessed through the target platform's import mechanism (ie, Import Address Table on Windows)
/// </summary>
public abstract bool CanHaveReferenceThroughImportTable { get; }
private class CompilerGeneratedAssembly : ModuleDesc, IAssemblyDesc
{
private MetadataType _globalModuleType;
public CompilerGeneratedAssembly(TypeSystemContext context)
: base(context)
{
_globalModuleType = new CompilerGeneratedType(this, "<Module>");
}
public override IEnumerable<MetadataType> GetAllTypes()
{
return Array.Empty<MetadataType>();
}
public override MetadataType GetGlobalModuleType()
{
return _globalModuleType;
}
public AssemblyName GetName()
{
return new AssemblyName("System.Private.CompilerGenerated");
}
public override MetadataType GetType(string nameSpace, string name, bool throwIfNotFound = true)
{
Debug.Fail("Resolving a TypeRef in the compiler generated assembly?");
if (throwIfNotFound)
ThrowHelper.ThrowTypeLoadException(nameSpace, name, this);
return null;
}
}
}
}

View File

@@ -1,22 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Internal.TypeSystem;
namespace ILCompiler
{
// Functionality related to determinstic ordering of types and members
internal sealed partial class CompilerGeneratedType : MetadataType
{
protected override int ClassCode => -1036681447;
protected override int CompareToImpl(TypeDesc other, TypeSystemComparer comparer)
{
// Should be a singleton
throw new NotSupportedException();
}
}
}

View File

@@ -1,198 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
using TypeHashingAlgorithms = Internal.NativeFormat.TypeHashingAlgorithms;
namespace ILCompiler
{
/// <summary>
/// A pseudo-type that owns helper methods generated by the compiler.
/// This type should never be allocated (we should never see an EEType for it).
/// </summary>
internal sealed partial class CompilerGeneratedType : MetadataType
{
private int _hashcode;
public CompilerGeneratedType(ModuleDesc module, string name)
{
Module = module;
Name = name;
}
public override TypeSystemContext Context
{
get
{
return Module.Context;
}
}
public override string Name
{
get;
}
public override string Namespace
{
get
{
return "Internal.CompilerGenerated";
}
}
public override int GetHashCode()
{
if (_hashcode != 0)
return _hashcode;
return InitializeHashCode();
}
private int InitializeHashCode()
{
string ns = Namespace;
var hashCodeBuilder = new TypeHashingAlgorithms.HashCodeBuilder(ns);
if (ns.Length > 0)
hashCodeBuilder.Append(".");
hashCodeBuilder.Append(Name);
_hashcode = hashCodeBuilder.ToHashCode();
return _hashcode;
}
public override bool IsCanonicalSubtype(CanonicalFormKind policy)
{
Debug.Assert(!HasInstantiation, "Why is this generic?");
return false;
}
protected override TypeFlags ComputeTypeFlags(TypeFlags mask)
{
return TypeFlags.Class |
TypeFlags.HasGenericVarianceComputed |
TypeFlags.HasStaticConstructorComputed |
TypeFlags.HasFinalizerComputed |
TypeFlags.IsByRefLikeComputed;
}
public override ClassLayoutMetadata GetClassLayout()
{
return new ClassLayoutMetadata
{
Offsets = null,
PackingSize = 0,
Size = 0,
};
}
public override bool HasCustomAttribute(string attributeNamespace, string attributeName)
{
return false;
}
public override IEnumerable<MetadataType> GetNestedTypes()
{
return Array.Empty<MetadataType>();
}
public override MetadataType GetNestedType(string name)
{
return null;
}
protected override MethodImplRecord[] ComputeVirtualMethodImplsForType()
{
return Array.Empty<MethodImplRecord>();
}
public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(string name)
{
return Array.Empty<MethodImplRecord>();
}
public override ModuleDesc Module
{
get;
}
public override PInvokeStringFormat PInvokeStringFormat
{
get
{
return PInvokeStringFormat.AutoClass;
}
}
public override bool IsExplicitLayout
{
get
{
return false;
}
}
public override bool IsSequentialLayout
{
get
{
return false;
}
}
public override bool IsBeforeFieldInit
{
get
{
return false;
}
}
public override MetadataType MetadataBaseType
{
get
{
// Since this type should never be allocated and only serves the purpose of grouping things,
// it can act like a <Module> type and have no base type.
return null;
}
}
public override bool IsSealed
{
get
{
return true;
}
}
public override bool IsAbstract
{
get
{
return false;
}
}
public override DefType ContainingType
{
get
{
return null;
}
}
public override DefType[] ExplicitlyImplementedInterfaces
{
get
{
return Array.Empty<DefType>();
}
}
}
}

View File

@@ -7,6 +7,8 @@ using System.Collections.Generic;
using Internal.TypeSystem;
using Debug = System.Diagnostics.Debug;
namespace ILCompiler
{
internal class CompilerMetadataFieldLayoutAlgorithm : MetadataFieldLayoutAlgorithm
@@ -15,7 +17,7 @@ namespace ILCompiler
{
// GC statics start with a pointer to the "EEType" that signals the size and GCDesc to the GC
layout.GcStatics.Size = context.Target.LayoutPointerSize;
layout.ThreadStatics.Size = context.Target.LayoutPointerSize;
layout.ThreadGcStatics.Size = context.Target.LayoutPointerSize;
}
protected override void FinalizeRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
@@ -26,10 +28,14 @@ namespace ILCompiler
{
layout.GcStatics.Size = LayoutInt.Zero;
}
if (layout.ThreadStatics.Size == context.Target.LayoutPointerSize)
if (layout.ThreadGcStatics.Size == context.Target.LayoutPointerSize)
{
layout.ThreadStatics.Size = LayoutInt.Zero;
layout.ThreadGcStatics.Size = LayoutInt.Zero;
}
// CoreRT makes no distinction between Gc / non-Gc thread statics. All are placed into ThreadGcStatics since thread statics
// are typically rare.
Debug.Assert(layout.ThreadNonGcStatics.Size == LayoutInt.Zero);
}
}
}

View File

@@ -290,7 +290,17 @@ namespace ILCompiler
Module = owningModule;
ValueTypeRepresented = valuetype;
BoxedValue = new BoxedValueField(this);
// Unboxing thunks for byref-like types don't make sense. Byref-like types cannot be boxed.
// We still allow these to exist in the system, because it's easier than trying to prevent
// their creation. We create them as if they existed (in lieu of e.g. pointing all of them
// to the same __unreachable method body) so that the various places that store pointers to
// them because they want to be able to extract the target instance method can use the same
// mechanism they use for everything else at runtime.
// The main difference is that the "Boxed_ValueType" version has no fields. Reference types
// cannot have byref-like fields.
if (!valuetype.IsByRefLike)
BoxedValue = new BoxedValueField(this);
}
public override ClassLayoutMetadata GetClassLayout() => default(ClassLayoutMetadata);
@@ -325,14 +335,14 @@ namespace ILCompiler
}
flags |= TypeFlags.HasFinalizerComputed;
flags |= TypeFlags.IsByRefLikeComputed;
flags |= TypeFlags.AttributeCacheComputed;
return flags;
}
public override FieldDesc GetField(string name)
{
if (name == BoxedValueFieldName)
if (name == BoxedValueFieldName && BoxedValue != null)
return BoxedValue;
return null;
@@ -340,7 +350,10 @@ namespace ILCompiler
public override IEnumerable<FieldDesc> GetFields()
{
yield return BoxedValue;
if (BoxedValue != null)
return new FieldDesc[] { BoxedValue };
return Array.Empty<FieldDesc>();
}
/// <summary>
@@ -439,6 +452,15 @@ namespace ILCompiler
public override MethodIL EmitIL()
{
if (_owningType.BoxedValue == null)
{
// If this is the fake unboxing thunk for ByRef-like types, just make a method that throws.
return new ILStubMethodIL(this,
new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ },
Array.Empty<LocalVariableDefinition>(),
Array.Empty<object>());
}
// Generate the unboxing stub. This loosely corresponds to following C#:
// return BoxedValue.InstanceMethod(this.m_pEEType, [rest of parameters])
@@ -507,6 +529,15 @@ namespace ILCompiler
public override MethodIL EmitIL()
{
if (_owningType.BoxedValue == null)
{
// If this is the fake unboxing thunk for ByRef-like types, just make a method that throws.
return new ILStubMethodIL(this,
new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ },
Array.Empty<LocalVariableDefinition>(),
Array.Empty<object>());
}
// Generate the unboxing stub. This loosely corresponds to following C#:
// return BoxedValue.InstanceMethod([rest of parameters])

View File

@@ -47,5 +47,24 @@ namespace ILCompiler
}
}
}
partial class UnboxingThunk : IPrefixMangledMethod
{
MethodDesc IPrefixMangledMethod.BaseMethod
{
get
{
return _targetMethod;
}
}
string IPrefixMangledMethod.Prefix
{
get
{
return "unbox";
}
}
}
}
}

View File

@@ -424,6 +424,9 @@ namespace ILCompiler
{
Debug.Assert(field.IsStatic);
if (field.IsThreadStatic)
return true;
TypeDesc fieldType = field.FieldType;
if (fieldType.IsValueType)
return ((DefType)fieldType).ContainsGCPointers;
@@ -499,17 +502,23 @@ namespace ILCompiler
// method table.
public long UniversalCanonReflectionMethodRootHeuristic_InstantiationCount { get; }
// To avoid infinite generic recursion issues during debug type record generation, attempt to
// use canonical form for types with high generic complexity.
public long MaxGenericDepthOfDebugRecord { get; }
public SharedGenericsConfiguration()
{
UniversalCanonGVMReflectionRootHeuristic_InstantiationCount = 4;
UniversalCanonGVMDepthHeuristic_NonCanonDepth = 2;
UniversalCanonGVMDepthHeuristic_CanonDepth = 1;
// Unlike the GVM heuristics which are intended to kick in aggresively
// Unlike the GVM heuristics which are intended to kick in aggressively
// this heuristic exists to make it so that a fair amount of generic
// expansion is allowed. Numbers are chosen to allow a fairly large
// amount of generic expansion before trimming.
UniversalCanonReflectionMethodRootHeuristic_InstantiationCount = 1024;
MaxGenericDepthOfDebugRecord = 15;
}
};
}

View File

@@ -331,7 +331,13 @@ namespace ILCompiler
}
else
{
// This is a type definition. Since we didn't fall in the `is EcmaType` case above,
// it's likely a compiler-generated type.
mangledName = SanitizeName(((DefType)type).GetFullName(), true);
// Always generate a fully qualified name
if (_mangleForCplusPlus)
mangledName = "::" + mangledName;
}
break;
}
@@ -404,6 +410,35 @@ namespace ILCompiler
return sb.ToUtf8String();
}
private Utf8String GetPrefixMangledSignatureName(IPrefixMangledSignature prefixMangledSignature)
{
Utf8StringBuilder sb = new Utf8StringBuilder();
sb.Append(EnterNameScopeSequence).Append(prefixMangledSignature.Prefix).Append(ExitNameScopeSequence);
var signature = prefixMangledSignature.BaseSignature;
sb.Append(signature.Flags.ToStringInvariant());
sb.Append(EnterNameScopeSequence);
string sigRetTypeName = GetMangledTypeName(signature.ReturnType);
if (_mangleForCplusPlus)
sigRetTypeName = sigRetTypeName.Replace("::", "_");
sb.Append(sigRetTypeName);
for (int i = 0; i < signature.Length; i++)
{
sb.Append("__");
string sigArgName = GetMangledTypeName(signature[i]);
if (_mangleForCplusPlus)
sigArgName = sigArgName.Replace("::", "_");
sb.Append(sigArgName);
}
sb.Append(ExitNameScopeSequence);
return sb.ToUtf8String();
}
private Utf8String GetPrefixMangledMethodName(IPrefixMangledMethod prefixMangledMetod)
{
Utf8StringBuilder sb = new Utf8StringBuilder();
@@ -491,6 +526,10 @@ namespace ILCompiler
{
utf8MangledName = GetPrefixMangledTypeName((IPrefixMangledType)method);
}
else if (method is IPrefixMangledSignature)
{
utf8MangledName = GetPrefixMangledSignatureName((IPrefixMangledSignature)method);
}
else
{
// Assume that Name is unique for all other methods

View File

@@ -78,6 +78,6 @@ namespace ILCompiler.DependencyAnalysis
}
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayMapNode;
public override int ClassCode => (int)ObjectNodeOrder.ArrayMapNode;
}
}

View File

@@ -108,6 +108,6 @@ namespace ILCompiler.DependencyAnalysis
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedDataNode;
public override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedDataNode;
}
}

View File

@@ -51,7 +51,7 @@ namespace ILCompiler.DependencyAnalysis
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
protected internal override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedPointersNode;
public override int ClassCode => (int)ObjectNodeOrder.ArrayOfEmbeddedPointersNode;
private class PointerIndirectionNodeComparer : IComparer<EmbeddedPointerIndirectionNode<TTarget>>
{
@@ -96,7 +96,7 @@ namespace ILCompiler.DependencyAnalysis
};
}
protected internal override int ClassCode => -66002498;
public override int ClassCode => -66002498;
}
private class EmbeddedPointerIndirectionWithSymbolNode : SimpleEmbeddedPointerIndirectionNode, ISymbolDefinitionNode

View File

@@ -42,6 +42,6 @@ namespace ILCompiler.DependencyAnalysis
builder.EmitZeroPointer();
}
protected internal override int ClassCode => -1771336339;
public override int ClassCode => -1771336339;
}
}

View File

@@ -16,6 +16,12 @@ namespace ILCompiler.DependencyAnalysis
{
}
/// <summary>
/// Gets a value indicating whether the stub's address is visible from managed code
/// and could be a target of a managed calli.
/// </summary>
protected virtual bool IsVisibleFromManagedCode => true;
public override ObjectNodeSection Section => ObjectNodeSection.TextSection;
public override bool StaticDependenciesAreComputed => true;
@@ -26,19 +32,26 @@ namespace ILCompiler.DependencyAnalysis
public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
{
// If the address is expected to be visible from managed code, we need to align
// at the managed code boundaries to prevent the stub from being confused with
// a fat fuction pointer. Otherwise we can align tighter.
int alignment = IsVisibleFromManagedCode ?
factory.Target.MinimumFunctionAlignment :
factory.Target.MinimumCodeAlignment;
switch (factory.Target.Architecture)
{
case TargetArchitecture.X64:
X64.X64Emitter x64Emitter = new X64.X64Emitter(factory, relocsOnly);
EmitCode(factory, ref x64Emitter, relocsOnly);
x64Emitter.Builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
x64Emitter.Builder.RequireInitialAlignment(alignment);
x64Emitter.Builder.AddSymbol(this);
return x64Emitter.Builder.ToObjectData();
case TargetArchitecture.X86:
X86.X86Emitter x86Emitter = new X86.X86Emitter(factory, relocsOnly);
EmitCode(factory, ref x86Emitter, relocsOnly);
x86Emitter.Builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
x86Emitter.Builder.RequireInitialAlignment(alignment);
x86Emitter.Builder.AddSymbol(this);
return x86Emitter.Builder.ToObjectData();
@@ -46,14 +59,14 @@ namespace ILCompiler.DependencyAnalysis
case TargetArchitecture.ARMEL:
ARM.ARMEmitter armEmitter = new ARM.ARMEmitter(factory, relocsOnly);
EmitCode(factory, ref armEmitter, relocsOnly);
armEmitter.Builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
armEmitter.Builder.RequireInitialAlignment(alignment);
armEmitter.Builder.AddSymbol(this);
return armEmitter.Builder.ToObjectData();
case TargetArchitecture.ARM64:
ARM64.ARM64Emitter arm64Emitter = new ARM64.ARM64Emitter(factory, relocsOnly);
EmitCode(factory, ref arm64Emitter, relocsOnly);
arm64Emitter.Builder.RequireInitialAlignment(factory.Target.MinimumFunctionAlignment);
arm64Emitter.Builder.RequireInitialAlignment(alignment);
arm64Emitter.Builder.AddSymbol(this);
return arm64Emitter.Builder.ToObjectData();

View File

@@ -42,9 +42,9 @@ namespace ILCompiler.DependencyAnalysis
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
#if !SUPPORT_JIT
protected internal override int ClassCode => -470351029;
public override int ClassCode => -470351029;
protected internal override int CompareToImpl(SortableDependencyNode other, CompilerComparer comparer)
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
{
return _name.CompareTo(((BlobNode)other)._name);
}

View File

@@ -83,6 +83,6 @@ namespace ILCompiler.DependencyAnalysis
}
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
protected internal override int ClassCode => (int)ObjectNodeOrder.BlockReflectionTypeMapNode;
public override int ClassCode => (int)ObjectNodeOrder.BlockReflectionTypeMapNode;
}
}

View File

@@ -43,6 +43,6 @@ namespace ILCompiler.DependencyAnalysis
// Canonical definition types will have their base size set to the minimum
protected override int BaseSize => MinimumObjectSize;
protected internal override int ClassCode => -1851030036;
public override int ClassCode => -1851030036;
}
}

View File

@@ -27,7 +27,6 @@ namespace ILCompiler.DependencyAnalysis
Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any));
Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific));
Debug.Assert(!type.IsMdArray);
Debug.Assert(!type.IsByRefLike);
}
public override bool StaticDependenciesAreComputed => true;
@@ -46,7 +45,7 @@ namespace ILCompiler.DependencyAnalysis
DefType closestDefType = _type.GetClosestDefType();
if (_type.RuntimeInterfaces.Length > 0)
if (InterfaceDispatchMapNode.MightHaveInterfaceDispatchMap(_type, factory))
dependencyList.Add(factory.InterfaceDispatchMap(_type), "Canonical interface dispatch map");
dependencyList.Add(factory.VTable(closestDefType), "VTable");
@@ -62,6 +61,15 @@ namespace ILCompiler.DependencyAnalysis
AddDependenciesForUniversalGVMSupport(factory, _type, ref dependencyList);
}
// 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, closestDefType.IsValueType),
"DefaultConstructorNode"));
}
return dependencyList;
}
@@ -136,6 +144,6 @@ namespace ILCompiler.DependencyAnalysis
base.ComputeValueTypeFieldPadding();
}
protected internal override int ClassCode => -1798018602;
public override int ClassCode => -1798018602;
}
}

View File

@@ -81,6 +81,6 @@ namespace ILCompiler.DependencyAnalysis
}
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
protected internal override int ClassCode => (int)ObjectNodeOrder.ClassConstructorContextMap;
public override int ClassCode => (int)ObjectNodeOrder.ClassConstructorContextMap;
}
}

Some files were not shown because too many files have changed in this diff Show More