The file format that mapped reflection metadata to runtime artifacts had a limitation that required generic methods to be always instantiated over concrete types - we could not place canonical method bodies there. The limitation stemmed from the fact that the mapping table was placing a generic dictionary in it.
This switches the table to use NameAndSignature + an array of instantiation arguments.
The rest of this change is just deleting code that was working around the problem. The fixes in NativeLayoutVertexNode and NodeFactory.NativeLayout are fixing analysis holes that were exposed by our ability to be more lazy.
Also saves 0.4% on BasicWebApi, which is always nice.
return RuntimeAugments.CreateRuntimeTypeHandle(GetIntPtrFromIndex(index));
}
- public IntPtr GetGenericDictionaryFromIndex(uint index)
- {
- return GetIntPtrFromIndex(index);
- }
-
public unsafe IntPtr GetAddressFromIndex(uint index)
{
if (index >= _elementsCount)
public RuntimeTypeHandle _entryType;
public IntPtr _methodEntrypoint;
public uint _dynamicInvokeCookie;
- public IntPtr _entryDictionary;
public RuntimeTypeHandle[] _methodInstantiation;
// Computed data
private bool _hasEntryPoint;
private bool _isMatchingMethodHandleAndDeclaringType;
private MethodNameAndSignature _nameAndSignature;
- private RuntimeTypeHandle[] _entryMethodInstantiation;
public InvokeMapEntryDataEnumerator(
TLookupMethodInfo lookupMethodInfo,
_dynamicInvokeCookie = 0xffffffff;
_hasEntryPoint = false;
_isMatchingMethodHandleAndDeclaringType = false;
- _entryDictionary = IntPtr.Zero;
_methodInstantiation = null;
_nameAndSignature = null;
- _entryMethodInstantiation = null;
}
public void GetNext(
_entryType = default(RuntimeTypeHandle);
_methodEntrypoint = IntPtr.Zero;
_dynamicInvokeCookie = 0xffffffff;
- _entryDictionary = IntPtr.Zero;
_methodInstantiation = null;
_nameAndSignature = null;
- _entryMethodInstantiation = null;
// If the current entry is not a canonical entry of the same canonical form kind we are looking for, then this cannot be a match
if (((_flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0) != (_canonFormKind == CanonicalFormKind.Universal))
if ((_flags & InvokeTableFlags.IsGenericMethod) == 0)
return;
- if ((_flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0)
+ if ((_flags & InvokeTableFlags.RequiresInstArg) != 0)
{
- Debug.Assert((_hasEntryPoint || ((_flags & InvokeTableFlags.HasVirtualInvoke) != 0)) && ((_flags & InvokeTableFlags.RequiresInstArg) != 0));
+ Debug.Assert(_hasEntryPoint || ((_flags & InvokeTableFlags.HasVirtualInvoke) != 0));
uint nameAndSigPointerToken = entryParser.GetUnsigned();
_nameAndSignature = TypeLoaderEnvironment.Instance.GetMethodNameAndSignatureFromNativeLayoutOffset(_moduleHandle, nameAndSigPointerToken);
}
- else if (((_flags & InvokeTableFlags.RequiresInstArg) != 0) && _hasEntryPoint)
- _entryDictionary = extRefTable.GetGenericDictionaryFromIndex(entryParser.GetUnsigned());
- else
+
+ if ((_flags & InvokeTableFlags.IsUniversalCanonicalEntry) == 0)
+ {
_methodInstantiation = GetTypeSequence(ref extRefTable, ref entryParser);
+ }
}
public bool IsMatchingOrCompatibleEntry()
return true;
}
- // Generic non-shareable method or abstract methods: check for the canonical equivalency of the method
- // instantiation arguments that we read from the entry
- if (((_flags & InvokeTableFlags.RequiresInstArg) == 0) || !_hasEntryPoint)
- return _lookupMethodInfo.CanInstantiationsShareCode(_methodInstantiation, _canonFormKind);
-
- // Generic shareable method: check for canonical equivalency of the method instantiation arguments.
- // The method instantiation arguments are extracted from the generic dictionary pointer that we read from the entry.
- Debug.Assert(_entryDictionary != IntPtr.Zero);
- return GetNameAndSignatureAndMethodInstantiation() && _lookupMethodInfo.CanInstantiationsShareCode(_entryMethodInstantiation, _canonFormKind);
+ return _lookupMethodInfo.CanInstantiationsShareCode(_methodInstantiation, _canonFormKind);
}
public bool GetMethodEntryPoint(out IntPtr methodEntrypoint, out TDictionaryComponentType dictionaryComponent, out IntPtr rawMethodEntrypoint)
}
// Dictionary for generic method (either found statically or constructed dynamically)
- return GetNameAndSignatureAndMethodInstantiation() && _lookupMethodInfo.GetMethodDictionary(_nameAndSignature, out dictionaryComponent);
+ return _lookupMethodInfo.GetMethodDictionary(_nameAndSignature, out dictionaryComponent);
}
private bool GetMethodEntryPointComponent(TDictionaryComponentType dictionaryComponent, out IntPtr methodEntrypoint)
return true;
}
-
- private bool GetNameAndSignatureAndMethodInstantiation()
- {
- if (_nameAndSignature != null)
- {
- Debug.Assert(((_flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0) || (_entryMethodInstantiation != null && _entryMethodInstantiation.Length > 0));
- return true;
- }
-
- if ((_flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0)
- {
- // _nameAndSignature should have been read from the InvokeMap entry directly!
- Debug.Fail("Universal canonical entries do NOT have dictionary entries!");
- return false;
- }
-
- RuntimeTypeHandle dummy1;
- bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(_entryDictionary, out dummy1, out _nameAndSignature, out _entryMethodInstantiation);
- Debug.Assert(success && dummy1.Equals(_entryType) && _nameAndSignature != null && _entryMethodInstantiation != null && _entryMethodInstantiation.Length > 0);
- return success;
- }
}
public bool TryGetMetadataForTypeMethodNameAndSignature(RuntimeTypeHandle declaringTypeHandle, MethodNameAndSignature nameAndSignature, out QMethodDefinition methodHandle)
using Internal.Text;
using Internal.TypeSystem;
-using CombinedDependencyList = System.Collections.Generic.List<ILCompiler.DependencyAnalysisFramework.DependencyNodeCore<ILCompiler.DependencyAnalysis.NodeFactory>.CombinedDependencyListEntry>;
-
namespace ILCompiler.DependencyAnalysis
{
/// <summary>
protected override TypeSystemContext Context => _owningMethod.Context;
public override TypeSystemEntity OwningEntity => _owningMethod;
public MethodDesc OwningMethod => _owningMethod;
- public override bool HasConditionalStaticDependencies => true;
- public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory)
- {
- CombinedDependencyList list = null;
- factory.MetadataManager.GetConditionalDependenciesDueToMethodGenericDictionary(ref list, factory, _owningMethod);
- return list ?? (IEnumerable<CombinedDependencyListEntry>)System.Array.Empty<CombinedDependencyListEntry>();
- }
+ public override bool HasConditionalStaticDependencies => false;
protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFactory factory)
{
// Make sure the dictionary can also be populated
dependencies.Add(factory.ShadowConcreteMethod(_owningMethod), "Dictionary contents");
- factory.MetadataManager.GetDependenciesForGenericDictionary(ref dependencies, factory, _owningMethod);
-
return dependencies;
}
public NativeLayoutFieldLdTokenGenericDictionarySlotNode(FieldDesc field)
{
+ Debug.Assert(field.OwningType.IsRuntimeDeterminedSubtype);
_field = field;
}
public sealed override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
{
- yield return new DependencyListEntry(factory.NativeLayout.FieldLdTokenVertex(_field), "Field Signature");
+ var result = new DependencyList
+ {
+ { factory.NativeLayout.FieldLdTokenVertex(_field), "Field Signature" }
+ };
foreach (var dependency in factory.NativeLayout.TemplateConstructableTypes(_field.OwningType))
{
- yield return new DependencyListEntry(dependency, "template construction dependency");
+ result.Add(dependency, "template construction dependency");
}
+
+ var canonOwningType = (InstantiatedType)_field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
+ FieldDesc canonField = factory.TypeSystemContext.GetFieldForInstantiatedType(_field.GetTypicalFieldDefinition(), canonOwningType);
+ factory.MetadataManager.GetDependenciesDueToLdToken(ref result, factory, canonField);
+
+ return result;
}
protected sealed override Vertex WriteSignatureVertex(NativeWriter writer, NodeFactory factory)
public sealed override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory)
{
- yield return new DependencyListEntry(factory.NativeLayout.MethodLdTokenVertex(_method), "Method Signature");
+ var result = new DependencyList
+ {
+ { factory.NativeLayout.MethodLdTokenVertex(_method), "Method Signature" }
+ };
foreach (var dependency in factory.NativeLayout.TemplateConstructableTypes(_method.OwningType))
{
- yield return new DependencyListEntry(dependency, "template construction dependency for method OwningType");
+ result.Add(dependency, "template construction dependency for method OwningType");
}
foreach (var type in _method.Instantiation)
{
foreach (var dependency in factory.NativeLayout.TemplateConstructableTypes(type))
- yield return new DependencyListEntry(dependency, "template construction dependency for method Instantiation types");
+ result.Add(dependency, "template construction dependency for method Instantiation types");
}
+
+ factory.MetadataManager.GetDependenciesDueToLdToken(ref result, factory, _method.GetCanonMethodTarget(CanonicalFormKind.Specific));
+
+ return result;
}
protected sealed override Vertex WriteSignatureVertex(NativeWriter writer, NodeFactory factory)
{
yield return _factory.NativeLayout.TemplateTypeLayout(arrayCanonicalType);
}
+
+ yield return _factory.MaximallyConstructableType(arrayCanonicalType);
}
while (type.IsParameterizedType)
private NodeCache<MethodDesc, ReflectedMethodNode> _reflectedMethods;
public ReflectedMethodNode ReflectedMethod(MethodDesc method)
{
+ // We track reflectability at canonical method body level
+ method = method.GetCanonMethodTarget(CanonicalFormKind.Specific);
+
return _reflectedMethods.GetOrAdd(method);
}
public ReflectedMethodNode(MethodDesc method)
{
- Debug.Assert(!method.IsCanonicalMethod(CanonicalFormKind.Any) ||
- method.GetCanonMethodTarget(CanonicalFormKind.Specific) == method);
+ Debug.Assert(method.GetCanonMethodTarget(CanonicalFormKind.Specific) == method);
_method = method;
}
dependencies.Add(factory.ReflectedMethod(typicalMethod), "Definition of the reflectable method");
}
- MethodDesc canonMethod = _method.GetCanonMethodTarget(CanonicalFormKind.Specific);
- if (canonMethod != _method)
- {
- dependencies.Add(factory.ReflectedMethod(canonMethod), "Canonical version of the reflectable method");
- }
-
// Make sure we generate the method body and other artifacts.
if (MetadataManager.IsMethodSupportedInReflectionInvoke(_method))
{
if (!_method.IsAbstract)
{
- dependencies.Add(factory.MethodEntrypoint(canonMethod), "Body of a reflectable method");
-
- if (_method.HasInstantiation
- && _method != canonMethod)
- dependencies.Add(factory.MethodGenericDictionary(_method), "Dictionary of a reflectable method");
+ dependencies.Add(factory.MethodEntrypoint(_method), "Body of a reflectable method");
}
}
public static void AddDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
{
Debug.Assert(factory.MetadataManager.IsReflectionInvokable(method));
+ Debug.Assert(method.GetCanonMethodTarget(CanonicalFormKind.Specific) == method);
dependencies ??= new DependencyList();
}
if (method.OwningType.IsValueType && !method.Signature.IsStatic)
- dependencies.Add(factory.ExactCallableAddress(method, isUnboxingStub: true), "Reflection unboxing stub");
+ dependencies.Add(factory.MethodEntrypoint(method, unboxingStub: true), "Reflection unboxing stub");
// If the method is defined in a different module than this one, a metadata token isn't known for performing the reference
// Use a name/sig reference instead.
if (method.HasInstantiation)
{
- if (method.IsCanonicalMethod(CanonicalFormKind.Universal))
+ if (method.IsCanonicalMethod(CanonicalFormKind.Any))
{
- dependencies.Add(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method)),
- "UniversalCanon signature of method");
+ dependencies.Add(factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition())),
+ "Signature of canonical method");
}
- else if (!method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg() || method.IsAbstract)
+
+ if (!method.IsCanonicalMethod(CanonicalFormKind.Universal))
{
foreach (var instArg in method.Instantiation)
{
{
MethodDesc method = mappingEntry.Entity;
+ Debug.Assert(method == method.GetCanonMethodTarget(CanonicalFormKind.Specific));
+
if (!factory.MetadataManager.ShouldMethodBeInInvokeMap(method))
continue;
if (method.HasInstantiation)
flags |= InvokeTableFlags.IsGenericMethod;
- if (method.GetCanonMethodTarget(CanonicalFormKind.Specific).RequiresInstArg())
+ if (method.RequiresInstArg())
{
bool goesThroughInstantiatingUnboxingThunk = method.OwningType.IsValueType && !method.Signature.IsStatic && !method.HasInstantiation;
if (!goesThroughInstantiatingUnboxingThunk)
{
vertex = writer.GetTuple(vertex,
writer.GetUnsignedConstant(_externalReferences.GetIndex(
- factory.MethodEntrypoint(method.GetCanonMethodTarget(CanonicalFormKind.Specific),
+ factory.MethodEntrypoint(method,
unboxingStub: method.OwningType.IsValueType && !method.Signature.IsStatic))));
}
if ((flags & InvokeTableFlags.IsGenericMethod) != 0)
{
- if ((flags & InvokeTableFlags.IsUniversalCanonicalEntry) != 0)
+ if ((flags & InvokeTableFlags.RequiresInstArg) != 0)
{
- var nameAndSigGenericMethod = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method));
+ var nameAndSigGenericMethod = factory.NativeLayout.PlacedSignatureVertex(factory.NativeLayout.MethodNameAndSignatureVertex(method.GetTypicalMethodDefinition()));
vertex = writer.GetTuple(vertex, writer.GetUnsignedConstant((uint)nameAndSigGenericMethod.SavedVertex.VertexOffset));
}
- else if ((flags & InvokeTableFlags.RequiresInstArg) == 0 || (flags & InvokeTableFlags.HasEntrypoint) == 0)
+
+ if ((flags & InvokeTableFlags.IsUniversalCanonicalEntry) == 0)
{
VertexSequence args = new VertexSequence();
for (int i = 0; i < method.Instantiation.Length; i++)
}
vertex = writer.GetTuple(vertex, args);
}
- else
- {
- uint dictionaryId = _externalReferences.GetIndex(factory.MethodGenericDictionary(method));
- vertex = writer.GetTuple(vertex, writer.GetUnsignedConstant(dictionaryId));
- }
}
- int hashCode = method.GetCanonMethodTarget(CanonicalFormKind.Specific).OwningType.GetHashCode();
+ int hashCode = method.OwningType.GetHashCode();
typeMapHashTable.Append((uint)hashCode, hashTableSection.Place(vertex));
}
&& _targetMethod.HasInstantiation && _targetMethod.IsVirtual)
{
dependencies ??= new DependencyList();
- dependencies.Add(factory.GVMDependencies(_targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific)), "GVM dependencies for runtime method handle");
+ MethodDesc canonMethod = _targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
+ dependencies.Add(factory.GVMDependencies(canonMethod), "GVM dependencies for runtime method handle");
// GVM analysis happens on canonical forms, but this is potentially injecting new genericness
// into the system. Ensure reflection analysis can still see this.
if (_targetMethod.IsAbstract)
- factory.MetadataManager.GetDependenciesDueToMethodCodePresence(ref dependencies, factory, _targetMethod, methodIL: null);
+ factory.MetadataManager.GetDependenciesDueToMethodCodePresence(ref dependencies, factory, canonMethod, methodIL: null);
}
factory.MetadataManager.GetDependenciesDueToLdToken(ref dependencies, factory, _targetMethod);
typeMappings.Add(new MetadataMapping<MetadataType>(definition, writer.GetRecordHandle(record)));
}
- HashSet<MethodDesc> canonicalGenericMethods = new HashSet<MethodDesc>();
foreach (var method in GetReflectableMethods())
{
if (method.IsGenericMethodDefinition || method.OwningType.IsGenericDefinition)
continue;
}
- if ((method.HasInstantiation && method.IsCanonicalMethod(CanonicalFormKind.Specific))
- || (!method.HasInstantiation && method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method))
+ if (method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method)
{
- // Methods that are not in their canonical form are not interesting with the exception
- // of generic methods: their dictionaries convey their identity.
+ // Methods that are not in their canonical form are not interesting
continue;
}
if ((GetMetadataCategory(method) & MetadataCategory.RuntimeMapping) == 0)
continue;
- // If we already added a canonically equivalent generic method, skip this one.
- if (method.HasInstantiation && !canonicalGenericMethods.Add(method.GetCanonMethodTarget(CanonicalFormKind.Specific)))
- continue;
-
MetadataRecord record = transformed.GetTransformedMethodDefinition(method.GetTypicalMethodDefinition());
if (record != null)
foreach (var field in GetFieldsWithRuntimeMapping())
{
FieldDesc fieldToAdd = field;
- if (!field.IsStatic)
+ TypeDesc canonOwningType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
+ if (canonOwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
{
- TypeDesc canonOwningType = field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific);
- if (canonOwningType != field.OwningType)
- {
- FieldDesc canonField = _typeSystemContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwningType);
+ FieldDesc canonField = _typeSystemContext.GetFieldForInstantiatedType(field.GetTypicalFieldDefinition(), (InstantiatedType)canonOwningType);
- // If we already added a canonically equivalent field, skip this one.
- if (!canonicalFields.Add(canonField))
- continue;
+ // If we already added a canonically equivalent field, skip this one.
+ if (!canonicalFields.Add(canonField))
+ continue;
- fieldToAdd = canonField;
- }
+ fieldToAdd = canonField;
}
Field record = transformed.GetTransformedFieldDefinition(fieldToAdd.GetTypicalFieldDefinition());
if (dictionaryNode != null)
{
_genericDictionariesGenerated.Add(dictionaryNode);
-
- if (dictionaryNode.OwningEntity is MethodDesc method && AllMethodsCanBeReflectable)
- _reflectableMethods.Add(method);
}
if (obj is InterfaceDispatchCellNode dispatchCell)
GetDependenciesDueToMethodCodePresenceInternal(ref dependencies, factory, method, methodIL);
}
- public virtual void GetConditionalDependenciesDueToMethodGenericDictionary(ref CombinedDependencyList dependencies, NodeFactory factory, MethodDesc method)
- {
- // MetadataManagers can override this to provide additional dependencies caused by the presence of
- // method generic dictionary.
- }
-
public virtual void GetConditionalDependenciesDueToMethodCodePresence(ref CombinedDependencyList dependencies, NodeFactory factory, MethodDesc method)
{
// MetadataManagers can override this to provide additional dependencies caused by the presence of
return null;
}
- public virtual void GetDependenciesForGenericDictionary(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
- {
- }
-
public virtual void NoteOverridingMethod(MethodDesc baseMethod, MethodDesc overridingMethod)
{
}
{
rootProvider.AddReflectionRoot(type, reason);
- InstantiatedType fallbackNonCanonicalOwningType = null;
-
// Instantiate generic types over something that will be useful at runtime
if (type.IsGenericDefinition)
{
- Instantiation canonInst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: true);
- if (canonInst.IsNull)
+ Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: true);
+ if (inst.IsNull)
return;
- Instantiation concreteInst = TypeExtensions.GetInstantiationThatMeetsConstraints(type.Instantiation, allowCanon: false);
- if (!concreteInst.IsNull)
- fallbackNonCanonicalOwningType = ((MetadataType)type).MakeInstantiatedType(concreteInst);
-
- type = ((MetadataType)type).MakeInstantiatedType(canonInst);
+ type = ((MetadataType)type).MakeInstantiatedType(inst);
rootProvider.AddReflectionRoot(type, reason);
}
if (type.IsDefType)
{
- foreach (var method in type.GetMethods())
+ foreach (var method in type.ConvertToCanonForm(CanonicalFormKind.Specific).GetMethods())
{
if (method.HasInstantiation)
{
- // Make a non-canonical instantiation.
- // We currently have a file format limitation that requires generic methods to be concrete.
- // A rooted canonical method body is not visible to the reflection mapping tables.
- Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(method.Instantiation, allowCanon: false);
-
+ Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(method.Instantiation, allowCanon: true);
if (inst.IsNull)
- {
- // Can't root anything useful
- }
- else if (!method.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
- {
- // Owning type is not canonical, can use the instantiation directly.
- TryRootMethod(rootProvider, method.MakeInstantiatedMethod(inst), reason);
- }
- else if (fallbackNonCanonicalOwningType != null)
- {
- // We have a fallback non-canonical type we can root a body on
- MethodDesc alternateMethod = method.Context.GetMethodForInstantiatedType(method.GetTypicalMethodDefinition(), fallbackNonCanonicalOwningType);
- TryRootMethod(rootProvider, alternateMethod.MakeInstantiatedMethod(inst), reason);
- }
+ continue;
+
+ TryRootMethod(rootProvider, method.MakeInstantiatedMethod(inst), reason);
}
else
{
if (method.OwningType.IsGenericDefinition || method.OwningType.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true))
{
TypeDesc owningType = method.OwningType.GetTypeDefinition();
- Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(owningType.Instantiation, allowCanon: !method.HasInstantiation);
+ Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(owningType.Instantiation, allowCanon: true);
if (inst.IsNull)
{
return false;
{
method = method.GetMethodDefinition();
- Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(method.Instantiation, allowCanon: false);
+ Instantiation inst = TypeExtensions.GetInstantiationThatMeetsConstraints(method.Instantiation, allowCanon: true);
if (inst.IsNull)
{
return false;
if (reflectedFieldNode != null)
{
FieldDesc field = reflectedFieldNode.Field;
- DefType fieldOwningType = field.OwningType;
// Filter out to those that make sense to have in the mapping tables
- if (!fieldOwningType.IsGenericDefinition
- && !field.IsLiteral
- && (!fieldOwningType.IsCanonicalSubtype(CanonicalFormKind.Specific) || !field.IsStatic))
+ if (!field.OwningType.IsGenericDefinition && !field.IsLiteral)
{
Debug.Assert((GetMetadataCategory(field) & MetadataCategory.RuntimeMapping) != 0);
_fieldsWithRuntimeMapping.Add(field);
}
}
- public override void GetConditionalDependenciesDueToMethodGenericDictionary(ref CombinedDependencyList dependencies, NodeFactory factory, MethodDesc method)
- {
- Debug.Assert(!method.IsSharedByGenericInstantiations && method.HasInstantiation && method.GetCanonMethodTarget(CanonicalFormKind.Specific) != method);
-
- if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) == 0
- && !IsReflectionBlocked(method))
- {
- // Ensure that if SomeMethod<T> is considered reflectable, SomeMethod<ConcreteType> is also reflectable.
- // We only need this because there's a file format limitation in the reflection mapping tables that
- // requires generic methods to be concrete (i.e. SomeMethod<__Canon> can never be in the mapping table).
- // If we ever lift this limitation, this code can be deleted: the reflectability is going to be covered
- // by GetConditionalDependenciesDueToMethodCodePresence below (we get that callback for SomeMethod<__Canon>).
- MethodDesc typicalMethod = method.GetTypicalMethodDefinition();
-
- dependencies ??= new CombinedDependencyList();
- dependencies.Add(new DependencyNodeCore<NodeFactory>.CombinedDependencyListEntry(
- factory.ReflectedMethod(method), factory.ReflectedMethod(typicalMethod), "Reflectability of methods is same across genericness"));
- }
- }
-
public override void GetConditionalDependenciesDueToMethodCodePresence(ref CombinedDependencyList dependencies, NodeFactory factory, MethodDesc method)
{
MethodDesc typicalMethod = method.GetTypicalMethodDefinition();
return null;
}
- public override void GetDependenciesForGenericDictionary(ref DependencyList dependencies, NodeFactory factory, MethodDesc method)
- {
- // Presence of code might trigger the reflectability dependencies.
- if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) != 0)
- {
- GetDependenciesDueToReflectability(ref dependencies, factory, method);
- }
- }
-
public bool GeneratesAttributeMetadata(TypeDesc attributeType)
{
var ecmaType = attributeType.GetTypeDefinition() as EcmaType;
<Method Name="Min_Generic_HasExpectedOutput" Dynamic="Required All">
<GenericArgument Name="System.Int32,System.Runtime" />
</Method>
+
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Byte,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.SByte,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt16,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int16,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt32,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int32,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt64,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int64,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Single,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Double,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Decimal,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.IntPtr,System.Runtime" />
+ </Method>
+ <Method Name="Min_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UIntPtr,System.Runtime" />
+ </Method>
</Type>
<Type Name="System.Linq.Tests.MaxTests">
<GenericArgument Name="System.Int32,System.Runtime" />
</Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Byte,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.SByte,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt16,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int16,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt32,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int32,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UInt64,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Int64,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Single,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Double,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.Decimal,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.IntPtr,System.Runtime" />
+ </Method>
+ <Method Name="Max_AllTypes" Dynamic="Required All">
+ <GenericArgument Name="System.UIntPtr,System.Runtime" />
+ </Method>
</Type>
<Type Name="System.Linq.Tests.CountTests">