Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimise GetCustomAttribute(s) #45121

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
321 changes: 42 additions & 279 deletions src/coreclr/System.Private.CoreLib/src/System/Attribute.CoreCLR.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,20 @@ public static Assembly GetCallingAssembly()

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern uint GetAssemblyCount();

internal virtual Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
// Returns an Attribute of base class/inteface attributeType on the Assembly or null if none exists.
// throws an AmbiguousMatchException if there are more than one defined.
Attribute[] attrib = Attribute.GetCustomAttributes(this, attributeType, inherit);

if (attrib == null || attrib.Length == 0)
return null;

if (attrib.Length == 1)
return attrib[0];

throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,15 @@ public static bool IsTokenOfType(int token, params MetadataTokenType[] types)

internal unsafe struct MetadataEnumResult
{
public const int SmallSizeLength = 16;
// Keep the definition in sync with vm\ManagedMdImport.hpp
private int[] largeResult;
private int length;
private fixed int smallResult[16];
private fixed int smallResult[SmallSizeLength];

public int Length => length;
public readonly int Length => length;

public int this[int index]
public readonly int this[int index]
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,18 @@ internal bool HasSameMetadataDefinitionAsCore<TOther>(MemberInfo other) where TO

return true;
}

internal virtual Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
Attribute[]? attrib = GetCustomAttributes(attributeType, inherit) as Attribute[];

if (attrib == null || attrib.Length == 0)
return null;

if (attrib.Length == 1)
return attrib[0];

throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,19 @@ public override bool IsCollectible
return null;
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType);
}

// ISerializable implementation
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,19 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType);
}

public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
Expand Down Expand Up @@ -253,7 +266,7 @@ public override MethodImplAttributes GetMethodImplementationFlags()

internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
{
if (declaringType == null)
if (declaringType is null)
throw new ArgumentNullException(nameof(declaringType));

// ctor is declared on interface class
Expand All @@ -267,7 +280,7 @@ internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
SR.Format(SR.Acc_CreateAbstEx, declaringType));

// ctor is on a class that contains stack pointers
else if (declaringType.GetRootElementType() == typeof(ArgIterator))
else if (ReferenceEquals(declaringType.GetRootElementType(), typeof(ArgIterator)))
throw new NotSupportedException();

// ctor is vararg
Expand All @@ -282,7 +295,7 @@ internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
}

// ctor is declared on System.Void
else if (declaringType == typeof(void))
else if (ReferenceEquals(declaringType, typeof(void)))
throw new MemberAccessException(SR.Access_Void);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType, inherit);
}

public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType);
}

public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,19 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType, inherit);
}

public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,19 @@ internal bool IsTransientInternal()
return RuntimeModule.nIsTransientInternal(new QCallModule(ref thisAsLocal));
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType);
}

internal MetadataImport MetadataImport => ModuleHandle.GetMetadataImport(this);
#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,25 @@ internal void SetAttributes(ParameterAttributes attributes)
{
AttrsImpl = attributes;
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

if (MdToken.IsNullToken(m_tkParamDef))
{
if (!inherit || Member.MemberType != MemberTypes.Method)
return null;
}

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType, inherit);
}
#endregion

#region Constructor
Expand Down Expand Up @@ -502,9 +521,12 @@ public override Type[] GetOptionalCustomModifiers()
public override object[] GetCustomAttributes(bool inherit)
{
if (MdToken.IsNullToken(m_tkParamDef))
return Array.Empty<object>();
{
if (!inherit || Member.MemberType != MemberTypes.Method)
return Array.Empty<object>();
}

return CustomAttribute.GetCustomAttributes(this, (typeof(object) as RuntimeType)!);
return CustomAttribute.GetCustomAttributes(this, (typeof(object) as RuntimeType)!, inherit);
}

public override object[] GetCustomAttributes(Type attributeType, bool inherit)
Expand All @@ -513,14 +535,17 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
throw new ArgumentNullException(nameof(attributeType));

if (MdToken.IsNullToken(m_tkParamDef))
return Array.Empty<object>();
{
if (!inherit || Member.MemberType != MemberTypes.Method)
return Array.Empty<object>();
}

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}

public override bool IsDefined(Type attributeType, bool inherit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public override string ToString()
#region ICustomAttributeProvider
public override object[] GetCustomAttributes(bool inherit)
{
return CustomAttribute.GetCustomAttributes(this, (typeof(object) as RuntimeType)!);
return CustomAttribute.GetCustomAttributes(this, (typeof(object) as RuntimeType)!, inherit);
}

public override object[] GetCustomAttributes(Type attributeType, bool inherit)
Expand All @@ -147,7 +147,20 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType, inherit);
}

public override bool IsDefined(Type attributeType, bool inherit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public ListBuilder(int capacity)
_capacity = capacity;
}

public T this[int index]
public readonly T this[int index]
{
get
{
Expand Down Expand Up @@ -104,7 +104,7 @@ public void CopyTo(object[] array, int index)
Array.Copy(_items!, 0, array, index, _count);
}

public int Count => _count;
public readonly int Count => _count;

public void Add(T item)
{
Expand Down Expand Up @@ -1870,6 +1870,32 @@ internal FieldInfo GetField(RuntimeFieldHandleInternal field)
return retval;
}

internal override Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));

RuntimeType? attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));

return CustomAttribute.GetCustomAttribute(this, attributeRuntimeType, inherit);
}

internal override AttributeUsageAttribute GetAttributeUsageAttribute()
{
if (!this.IsSubclassOf(typeof(Attribute)))
throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);

RuntimeType? attributeRuntimeType = typeof(AttributeUsageAttribute).UnderlyingSystemType as RuntimeType;

if (attributeRuntimeType == null)
throw new ArgumentException(SR.Arg_MustBeType, nameof(Attribute));

return CustomAttribute.GetAttributeUsage(this);
}

internal object? GenericCache
{
get => CacheIfExists?.GenericCache;
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/System.Private.CoreLib/src/System/Type.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,21 @@ internal virtual RuntimeTypeHandle GetTypeHandleInternal()
// Exists to faciliate code sharing between CoreCLR and CoreRT.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal bool IsRuntimeImplemented() => this is RuntimeType;

internal virtual AttributeUsageAttribute GetAttributeUsageAttribute()
{
if (!this.IsSubclassOf(typeof(Attribute)))
throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);

Attribute[]? attrib = GetCustomAttributes(typeof(AttributeUsageAttribute), false) as Attribute[];

if (attrib == null || attrib.Length == 0)
return AttributeUsageAttribute.Default;

if (attrib.Length == 1)
return (AttributeUsageAttribute)attrib[0];

throw new FormatException(SR.Format(SR.Format_AttributeUsage, this));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,5 +189,20 @@ private static bool FilterTypeNameImpl(Type cls, object filterCriteria, StringCo

return cls.Name.Equals(str, comparison);
}

internal virtual Attribute? GetCustomAttribute(Type attributeType, bool inherit)
{
// Returns an Attribute of base class/interface attributeType on the Module or null if none exists.
// throws an AmbiguousMatchException if there are more than one defined.
Attribute[] attrib = Attribute.GetCustomAttributes(this, attributeType, inherit);

if (attrib == null || attrib.Length == 0)
return null;

if (attrib.Length == 1)
return attrib[0];

throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
}
}
Loading