Imported Upstream version 5.14.0.78

Former-commit-id: 3494343bcc9ddb42b36b82dd9ae7b69e85e0229f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-05-10 08:37:03 +00:00
parent 74b74abd9f
commit 19234507ba
1776 changed files with 67755 additions and 31107 deletions

View File

@@ -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";

View File

@@ -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;

View File

@@ -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;
}
};
}

View File

@@ -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("-", "");
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;
}
}
}

View File

@@ -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)

View File

@@ -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>

View File

@@ -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);

View File

@@ -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