You've already forked linux-packaging-mono
Imported Upstream version 5.14.0.78
Former-commit-id: 3494343bcc9ddb42b36b82dd9ae7b69e85e0229f
This commit is contained in:
parent
74b74abd9f
commit
19234507ba
@@ -155,7 +155,7 @@ namespace ILCompiler
|
||||
|
||||
void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider)
|
||||
{
|
||||
// We go over all the types and members that need a runtime artiface present in the
|
||||
// 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";
|
||||
|
||||
@@ -94,6 +94,10 @@ namespace ILCompiler
|
||||
|
||||
private bool ComputeIsBlocked(EcmaType type, ModuleBlockingMode blockingMode)
|
||||
{
|
||||
// If the type is explicitly blocked, it's always blocked.
|
||||
if (type.HasCustomAttribute("System.Runtime.CompilerServices", "ReflectionBlockedAttribute"))
|
||||
return true;
|
||||
|
||||
// If no blocking is applied to the module, the type is not blocked
|
||||
if (blockingMode == ModuleBlockingMode.None)
|
||||
return false;
|
||||
|
||||
@@ -97,13 +97,20 @@ namespace ILCompiler
|
||||
private SimpleNameHashtable _simpleNameHashtable = new SimpleNameHashtable();
|
||||
|
||||
private SharedGenericsMode _genericsMode;
|
||||
|
||||
|
||||
public CompilerTypeSystemContext(TargetDetails details, SharedGenericsMode genericsMode)
|
||||
: base(details)
|
||||
{
|
||||
_genericsMode = genericsMode;
|
||||
|
||||
_vectorOfTFieldLayoutAlgorithm = new VectorOfTFieldLayoutAlgorithm(_metadataFieldLayoutAlgorithm);
|
||||
|
||||
GenericsConfig = new SharedGenericsConfiguration();
|
||||
}
|
||||
|
||||
public SharedGenericsConfiguration GenericsConfig
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, string> InputFilePaths
|
||||
@@ -345,6 +352,10 @@ namespace ILCompiler
|
||||
{
|
||||
return GetAllMethodsForEnum(type);
|
||||
}
|
||||
else if (type.IsValueType)
|
||||
{
|
||||
return GetAllMethodsForValueType(type);
|
||||
}
|
||||
|
||||
return type.GetMethods();
|
||||
}
|
||||
@@ -473,4 +484,32 @@ namespace ILCompiler
|
||||
Disabled,
|
||||
CanonicalReferenceTypes,
|
||||
}
|
||||
|
||||
public class SharedGenericsConfiguration
|
||||
{
|
||||
//
|
||||
// Universal Shared Generics heuristics magic values determined empirically
|
||||
//
|
||||
public long UniversalCanonGVMReflectionRootHeuristic_InstantiationCount { get; }
|
||||
public long UniversalCanonGVMDepthHeuristic_NonCanonDepth { get; }
|
||||
public long UniversalCanonGVMDepthHeuristic_CanonDepth { get; }
|
||||
|
||||
// Controls how many different instantiations of a generic method, or method on generic type
|
||||
// should be allowed before trying to fall back to only supplying USG in the reflection
|
||||
// method table.
|
||||
public long UniversalCanonReflectionMethodRootHeuristic_InstantiationCount { get; }
|
||||
|
||||
public SharedGenericsConfiguration()
|
||||
{
|
||||
UniversalCanonGVMReflectionRootHeuristic_InstantiationCount = 4;
|
||||
UniversalCanonGVMDepthHeuristic_NonCanonDepth = 2;
|
||||
UniversalCanonGVMDepthHeuristic_CanonDepth = 1;
|
||||
|
||||
// Unlike the GVM heuristics which are intended to kick in aggresively
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -115,16 +115,21 @@ namespace ILCompiler
|
||||
|
||||
if (mangledName != literal)
|
||||
{
|
||||
if (_sha256 == null)
|
||||
byte[] hash;
|
||||
lock (this)
|
||||
{
|
||||
// Use SHA256 hash here to provide a high degree of uniqueness to symbol names without requiring them to be long
|
||||
// This hash function provides an exceedingly high likelihood that no two strings will be given equal symbol names
|
||||
// This is not considered used for security purpose; however collisions would be highly unfortunate as they will cause compilation
|
||||
// failure.
|
||||
_sha256 = SHA256.Create();
|
||||
}
|
||||
if (_sha256 == null)
|
||||
{
|
||||
// Use SHA256 hash here to provide a high degree of uniqueness to symbol names without requiring them to be long
|
||||
// This hash function provides an exceedingly high likelihood that no two strings will be given equal symbol names
|
||||
// This is not considered used for security purpose; however collisions would be highly unfortunate as they will cause compilation
|
||||
// failure.
|
||||
_sha256 = SHA256.Create();
|
||||
}
|
||||
|
||||
var hash = _sha256.ComputeHash(GetBytesFromString(literal));
|
||||
hash = _sha256.ComputeHash(GetBytesFromString(literal));
|
||||
}
|
||||
|
||||
mangledName += "_" + BitConverter.ToString(hash).Replace("-", "");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
protected override ISymbolNode GetBaseTypeNode(NodeFactory factory)
|
||||
{
|
||||
return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.NormalizedBaseType()) : null;
|
||||
return _type.BaseType != null ? factory.NecessaryTypeSymbol(GetFullCanonicalTypeForCanonicalType(_type.BaseType)) : null;
|
||||
}
|
||||
|
||||
protected override int GCDescSize
|
||||
|
||||
@@ -36,8 +36,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
|
||||
@@ -23,7 +23,9 @@ namespace ILCompiler.DependencyAnalysis
|
||||
if (dependencies == null)
|
||||
dependencies = new DependencyList();
|
||||
|
||||
dependencies.Add(factory.MaximallyConstructableType(method.OwningType), "Reflection invoke");
|
||||
// The fact we need to exclude Project N is likely a bug in Project N metadata manager
|
||||
if (factory.Target.Abi != TargetAbi.ProjectN)
|
||||
dependencies.Add(factory.MaximallyConstructableType(method.OwningType), "Reflection invoke");
|
||||
|
||||
if (factory.MetadataManager.HasReflectionInvokeStubForInvokableMethod(method)
|
||||
&& ((factory.Target.Abi != TargetAbi.ProjectN) || ProjectNDependencyBehavior.EnableFullAnalysis || !method.IsCanonicalMethod(CanonicalFormKind.Any)))
|
||||
@@ -98,7 +100,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
factory.InteropStubManager.AddDependeciesDueToPInvoke(ref dependencies, factory, method);
|
||||
|
||||
if (method.IsIntrinsic && factory.Target.Abi != TargetAbi.ProjectN)
|
||||
if (method.IsIntrinsic && factory.Target.Abi != TargetAbi.ProjectN && factory.MetadataManager.SupportsReflection)
|
||||
{
|
||||
if (method.OwningType is MetadataType owningType)
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
dependencyList.Add(factory.VTable(closestDefType), "VTable");
|
||||
|
||||
if (closestDefType.HasInstantiation)
|
||||
if (closestDefType.HasInstantiation && factory.MetadataManager.SupportsReflection)
|
||||
{
|
||||
TypeDesc canonType = _type.ConvertToCanonForm(CanonicalFormKind.Specific);
|
||||
TypeDesc canonClosestDefType = closestDefType.ConvertToCanonForm(CanonicalFormKind.Specific);
|
||||
|
||||
@@ -145,14 +145,17 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
|
||||
{
|
||||
// Root the template for the type. In the future, we may want to control this via type reflectability instead.
|
||||
if (_owningMethodOrType is MethodDesc)
|
||||
if (factory.MetadataManager.SupportsReflection)
|
||||
{
|
||||
yield return new DependencyListEntry(factory.NativeLayout.TemplateMethodLayout((MethodDesc)_owningMethodOrType), "Type loader template");
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout((TypeDesc) _owningMethodOrType), "Type loader template");
|
||||
// Root the template for the type. In the future, we may want to control this via type reflectability instead.
|
||||
if (_owningMethodOrType is MethodDesc)
|
||||
{
|
||||
yield return new DependencyListEntry(factory.NativeLayout.TemplateMethodLayout((MethodDesc)_owningMethodOrType), "Type loader template");
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new DependencyListEntry(factory.NativeLayout.TemplateTypeLayout((TypeDesc)_owningMethodOrType), "Type loader template");
|
||||
}
|
||||
}
|
||||
|
||||
if (HasFixedSlots)
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
if (impl.OwningType == defType && !impl.IsAbstract)
|
||||
{
|
||||
MethodDesc canonImpl = impl.GetCanonMethodTarget(CanonicalFormKind.Specific);
|
||||
yield return new CombinedDependencyListEntry(factory.MethodEntrypoint(canonImpl, _type.IsValueType), factory.VirtualMethodUse(decl.Normalize()), "Virtual method");
|
||||
yield return new CombinedDependencyListEntry(factory.MethodEntrypoint(canonImpl, _type.IsValueType), factory.VirtualMethodUse(decl), "Virtual method");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
// Add conditional dependencies for interface methods the type implements. For example, if the type T implements
|
||||
// interface IFoo which has a method M1, add a dependency on T.M1 dependent on IFoo.M1 being called, since it's
|
||||
// possible for any IFoo object to actually be an instance of T.
|
||||
foreach (DefType interfaceType in defType.NormalizedRuntimeInterfaces())
|
||||
foreach (DefType interfaceType in defType.RuntimeInterfaces)
|
||||
{
|
||||
Debug.Assert(interfaceType.IsInterface);
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
|
||||
if (_type.RuntimeInterfaces.Length > 0 && !factory.VTable(closestDefType).HasFixedSlots)
|
||||
{
|
||||
foreach (var implementedInterface in _type.NormalizedRuntimeInterfaces())
|
||||
foreach (var implementedInterface in _type.RuntimeInterfaces)
|
||||
{
|
||||
// If the type implements ICastable, the methods are implicitly necessary
|
||||
if (implementedInterface == factory.ICastableInterface)
|
||||
@@ -634,6 +634,22 @@ namespace ILCompiler.DependencyAnalysis
|
||||
}
|
||||
}
|
||||
|
||||
protected static TypeDesc GetFullCanonicalTypeForCanonicalType(TypeDesc type)
|
||||
{
|
||||
if (type.IsCanonicalSubtype(CanonicalFormKind.Specific))
|
||||
{
|
||||
return type.ConvertToCanonForm(CanonicalFormKind.Specific);
|
||||
}
|
||||
else if (type.IsCanonicalSubtype(CanonicalFormKind.Universal))
|
||||
{
|
||||
return type.ConvertToCanonForm(CanonicalFormKind.Universal);
|
||||
}
|
||||
else
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ISymbolNode GetBaseTypeNode(NodeFactory factory)
|
||||
{
|
||||
return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType) : null;
|
||||
@@ -681,7 +697,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
declType = declType.GetClosestDefType();
|
||||
templateType = templateType.ConvertToCanonForm(CanonicalFormKind.Specific);
|
||||
|
||||
var baseType = declType.NormalizedBaseType();
|
||||
var baseType = declType.BaseType;
|
||||
if (baseType != null)
|
||||
{
|
||||
Debug.Assert(templateType.BaseType != null);
|
||||
@@ -1017,18 +1033,18 @@ namespace ILCompiler.DependencyAnalysis
|
||||
}
|
||||
|
||||
// It must be possible to create an EEType for the base type of this type
|
||||
TypeDesc baseType = type.NormalizedBaseType();
|
||||
TypeDesc baseType = type.BaseType;
|
||||
if (baseType != null)
|
||||
{
|
||||
// Make sure EEType can be created for this.
|
||||
factory.NecessaryTypeSymbol(baseType);
|
||||
factory.NecessaryTypeSymbol(GetFullCanonicalTypeForCanonicalType(baseType));
|
||||
}
|
||||
|
||||
// We need EETypes for interfaces
|
||||
foreach (var intf in type.NormalizedRuntimeInterfaces())
|
||||
foreach (var intf in type.RuntimeInterfaces)
|
||||
{
|
||||
// Make sure EEType can be created for this.
|
||||
factory.NecessaryTypeSymbol(intf);
|
||||
factory.NecessaryTypeSymbol(GetFullCanonicalTypeForCanonicalType(intf));
|
||||
}
|
||||
|
||||
// Validate classes, structs, enums, interfaces, and delegates
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
@@ -71,4 +70,4 @@ namespace ILCompiler.DependencyAnalysis
|
||||
protected internal override int Phase => (int)ObjectNodePhase.Ordered;
|
||||
protected internal override int ClassCode => (int)ObjectNodeOrder.GenericTypesHashtableNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
|
||||
|
||||
@@ -38,7 +38,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace ILCompiler.DependencyAnalysis
|
||||
result.Add(factory.InterfaceDispatchMapIndirection(_type), "Interface dispatch map indirection node");
|
||||
|
||||
// VTable slots of implemented interfaces are consulted during emission
|
||||
foreach (TypeDesc runtimeInterface in _type.NormalizedRuntimeInterfaces())
|
||||
foreach (TypeDesc runtimeInterface in _type.RuntimeInterfaces)
|
||||
{
|
||||
result.Add(factory.VTable(runtimeInterface), "Interface for a dispatch map");
|
||||
}
|
||||
@@ -61,10 +61,10 @@ namespace ILCompiler.DependencyAnalysis
|
||||
{
|
||||
var entryCountReservation = builder.ReserveInt();
|
||||
int entryCount = 0;
|
||||
int interfaceIndex = 0;
|
||||
|
||||
foreach (var interfaceType in _type.NormalizedRuntimeInterfaces())
|
||||
for (int interfaceIndex = 0; interfaceIndex < _type.RuntimeInterfaces.Length; interfaceIndex++)
|
||||
{
|
||||
var interfaceType = _type.RuntimeInterfaces[interfaceIndex];
|
||||
Debug.Assert(interfaceType.IsInterface);
|
||||
|
||||
IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(interfaceType).Slots;
|
||||
@@ -80,12 +80,10 @@ namespace ILCompiler.DependencyAnalysis
|
||||
{
|
||||
builder.EmitShort(checked((short)interfaceIndex));
|
||||
builder.EmitShort(checked((short)(interfaceMethodSlot + (interfaceType.HasGenericDictionarySlot() ? 1 : 0))));
|
||||
builder.EmitShort(checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod.Normalize())));
|
||||
builder.EmitShort(checked((short)VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, implMethod)));
|
||||
entryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
interfaceIndex++;
|
||||
}
|
||||
|
||||
builder.EmitInt(entryCountReservation, entryCount);
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace ILCompiler.DependencyAnalysis
|
||||
public override bool IsShareable => false;
|
||||
public override ObjectNodeSection Section => _externalReferences.Section;
|
||||
public override bool StaticDependenciesAreComputed => true;
|
||||
public override bool ShouldSkipEmittingObjectNode(NodeFactory factory) => !factory.MetadataManager.SupportsReflection;
|
||||
protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler);
|
||||
|
||||
/// <summary>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user