Skip to content

Commit

Permalink
Remove more Helper Method Frames (dotnet#100116)
Browse files Browse the repository at this point in the history
* Remove helper method frames

* Convert functions in customattribute.h into QCalls
  • Loading branch information
AaronRobinsonMSFT authored Mar 23, 2024
1 parent 3c4a231 commit 46870ff
Show file tree
Hide file tree
Showing 7 changed files with 527 additions and 493 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ public override IList<CustomAttributeNamedArgument> NamedArguments
if (p.EncodedArgument is not null
&& p.EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
{
Debug.Assert(p.MemberInfo is not null);
namedArgs[j++] = new CustomAttributeNamedArgument(
p.MemberInfo,
new CustomAttributeTypedArgument(m_scope, p.EncodedArgument));
Expand Down Expand Up @@ -1114,7 +1115,7 @@ public CustomAttributeType(RuntimeType parameterType)
public Type? EnumType { get; }
}

internal static unsafe class CustomAttribute
internal static unsafe partial class CustomAttribute
{
#region Internal Static Members
internal static bool IsDefined(RuntimeType type, RuntimeType? caType, bool inherit)
Expand Down Expand Up @@ -1526,7 +1527,7 @@ private static void AddCustomAttributes(
object attribute;
if (ctorWithParameters is not null)
{
attribute = CreateCaObject(decoratedModule, attributeType, ctorWithParameters, ref blobStart, blobEnd, out cNamedArgs);
attribute = CreateCustomAttributeInstance(decoratedModule, attributeType, ctorWithParameters, ref blobStart, blobEnd, out cNamedArgs);
}
else
{
Expand Down Expand Up @@ -1794,8 +1795,16 @@ internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedA
if (attributeUsageAttribute is not null)
throw new FormatException(SR.Format(SR.Format_AttributeUsage, attributeType));

ParseAttributeUsageAttribute(caRecord.blob, out AttributeTargets targets, out bool inherited, out bool allowMultiple);
attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited);
if (!ParseAttributeUsageAttribute(
caRecord.blob,
out AttributeTargets attrTargets,
out bool allowMultiple,
out bool inherited))
{
throw new CustomAttributeFormatException();
}

attributeUsageAttribute = new AttributeUsageAttribute(attrTargets, allowMultiple: allowMultiple, inherited: inherited);
}

return attributeUsageAttribute ?? AttributeUsageAttribute.Default;
Expand Down Expand Up @@ -1838,42 +1847,93 @@ internal static object[] CreateAttributeArrayHelper(RuntimeType caType, int elem
}
#endregion

#region Private Static FCalls
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _ParseAttributeUsageAttribute(
IntPtr pCa, int cCa, out int targets, out bool inherited, out bool allowMultiple);
private static void ParseAttributeUsageAttribute(
ConstArray ca, out AttributeTargets targets, out bool inherited, out bool allowMultiple)
{
_ParseAttributeUsageAttribute(ca.Signature, ca.Length, out int _targets, out inherited, out allowMultiple);
targets = (AttributeTargets)_targets;
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object _CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, byte** ppBlob, byte* pEndBlob, int* pcNamedArgs);
private static object CreateCaObject(RuntimeModule module, RuntimeType type, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
{
byte* pBlob = (byte*)blob;
byte* pBlobEnd = (byte*)blobEnd;
int cNamedArgs;
object ca = _CreateCaObject(module, type, ctor, &pBlob, pBlobEnd, &cNamedArgs);
blob = (IntPtr)pBlob;
namedArgs = cNamedArgs;
return ca;
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_ParseAttributeUsageAttribute")]
[SuppressGCTransition]
private static partial int ParseAttributeUsageAttribute(
IntPtr pData,
int cData,
int* pTargets,
int* pAllowMultiple,
int* pInherited);

private static bool ParseAttributeUsageAttribute(
ConstArray blob,
out AttributeTargets attrTargets,
out bool allowMultiple,
out bool inherited)
{
int attrTargetsLocal = 0;
int allowMultipleLocal = 0;
int inheritedLocal = 0;
int result = ParseAttributeUsageAttribute(blob.Signature, blob.Length, &attrTargetsLocal, &allowMultipleLocal, &inheritedLocal);
attrTargets = (AttributeTargets)attrTargetsLocal;
allowMultiple = allowMultipleLocal != 0;
inherited = inheritedLocal != 0;
return result != 0;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_CreateCustomAttributeInstance")]
private static partial void CreateCustomAttributeInstance(
QCallModule pModule,
ObjectHandleOnStack type,
ObjectHandleOnStack pCtor,
ref IntPtr ppBlob,
IntPtr pEndBlob,
out int pcNamedArgs,
ObjectHandleOnStack instance);

private static object CreateCustomAttributeInstance(RuntimeModule module, RuntimeType type, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
{
if (module is null)
{
throw new ArgumentNullException(SR.Arg_InvalidHandle);
}

object? result = null;
CreateCustomAttributeInstance(
new QCallModule(ref module),
ObjectHandleOnStack.Create(ref type),
ObjectHandleOnStack.Create(ref ctor),
ref blob,
blobEnd,
out namedArgs,
ObjectHandleOnStack.Create(ref result));
return result!;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_CreatePropertyOrFieldData", StringMarshalling = StringMarshalling.Utf16)]
private static partial void CreatePropertyOrFieldData(
QCallModule pModule,
ref IntPtr ppBlobStart,
IntPtr pBlobEnd,
StringHandleOnStack name,
[MarshalAs(UnmanagedType.Bool)] out bool bIsProperty,
ObjectHandleOnStack type,
ObjectHandleOnStack value);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _GetPropertyOrFieldData(
RuntimeModule pModule, byte** ppBlobStart, byte* pBlobEnd, out string name, out bool bIsProperty, out RuntimeType type, out object value);
private static void GetPropertyOrFieldData(
RuntimeModule module, ref IntPtr blobStart, IntPtr blobEnd, out string name, out bool isProperty, out RuntimeType? type, out object? value)
{
byte* pBlobStart = (byte*)blobStart;
_GetPropertyOrFieldData(
module, &pBlobStart, (byte*)blobEnd, out name, out isProperty, out type, out value);
blobStart = (IntPtr)pBlobStart;
if (module is null)
{
throw new ArgumentNullException(SR.Arg_InvalidHandle);
}

string? nameLocal = null;
RuntimeType? typeLocal = null;
object? valueLocal = null;
CreatePropertyOrFieldData(
new QCallModule(ref module),
ref blobStart,
blobEnd,
new StringHandleOnStack(ref nameLocal),
out isProperty,
ObjectHandleOnStack.Create(ref typeLocal),
ObjectHandleOnStack.Create(ref valueLocal));
name = nameLocal!;
type = typeLocal;
value = valueLocal;
}
#endregion
}

internal static class PseudoCustomAttribute
Expand Down Expand Up @@ -1918,12 +1978,18 @@ private static HashSet<RuntimeType> CreatePseudoCustomAttributeHashSet()
private static void VerifyPseudoCustomAttribute(RuntimeType pca)
{
// If any of these are invariants are no longer true will have to
// re-architect the PCA product logic and test cases -- you've been warned!
Debug.Assert(pca.BaseType == typeof(Attribute), "Pseudo CA Error");
// re-architect the PCA product logic and test cases.
Debug.Assert(pca.BaseType == typeof(Attribute), "Pseudo CA Error - Incorrect base type");
AttributeUsageAttribute usage = CustomAttribute.GetAttributeUsage(pca);
Debug.Assert(!usage.Inherited, "Pseudo CA Error");
// AllowMultiple is true for TypeForwardedToAttribute
// Debug.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
Debug.Assert(!usage.Inherited, "Pseudo CA Error - Unexpected Inherited value");
if (pca == typeof(TypeForwardedToAttribute))
{
Debug.Assert(usage.AllowMultiple, "Pseudo CA Error - Unexpected AllowMultiple value");
}
else
{
Debug.Assert(!usage.AllowMultiple, "Pseudo CA Error - Unexpected AllowMultiple value");
}
}
#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2373,7 +2373,9 @@ private static bool FilterApplyMethodBase(
#region Private Data Members

#pragma warning disable CA1823
#pragma warning disable CS0169
private readonly object m_keepalive; // This will be filled with a LoaderAllocator reference when this RuntimeType represents a collectible type
#pragma warning restore CS0169
#pragma warning restore CA1823
private IntPtr m_cache;
internal IntPtr m_handle;
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/callconvbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ HRESULT CallConv::TryGetCallingConventionFromUnmanagedCallConv(

InlineFactory<SArray<CaValue>, 4> caValueArrayFactory;
DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly();
IfFailThrow(Attribute::ParseAttributeArgumentValues(
IfFailThrow(Attribute::ParseArgumentValues(
pData,
cData,
&caValueArrayFactory,
Expand Down Expand Up @@ -528,7 +528,7 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc*

InlineFactory<SArray<CaValue>, 4> caValueArrayFactory;
DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly();
IfFailThrow(Attribute::ParseAttributeArgumentValues(
IfFailThrow(Attribute::ParseArgumentValues(
pData,
cData,
&caValueArrayFactory,
Expand Down
Loading

0 comments on commit 46870ff

Please sign in to comment.