diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs
index 4764545fccc405..c0cac16f99fbf8 100644
--- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs
+++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs
@@ -639,14 +639,6 @@ internal bool IsInterface
}
}
- internal bool IsAbstract
- {
- get
- {
- return IsInterface || (RareFlags & EETypeRareFlags.IsAbstractClassFlag) != 0;
- }
- }
-
internal bool IsByRefLike
{
get
@@ -773,7 +765,7 @@ internal bool IsIDynamicInterfaceCastable
{
get
{
- return ((_uFlags & (uint)EETypeFlags.IDynamicInterfaceCastableFlag) != 0);
+ return ((ExtendedFlags & (ushort)EETypeFlagsEx.IDynamicInterfaceCastableFlag) != 0);
}
}
@@ -794,6 +786,14 @@ internal bool IsPrimitive
}
}
+ internal bool HasSealedVTableEntries
+ {
+ get
+ {
+ return (_uFlags & (uint)EETypeFlags.HasSealedVTableEntriesFlag) != 0;
+ }
+ }
+
internal bool ContainsGCPointers
{
get
@@ -1064,7 +1064,7 @@ private static IntPtr FollowRelativePointer(int* pDist)
#endif
void* GetSealedVirtualTable()
{
- Debug.Assert((RareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0);
+ Debug.Assert(HasSealedVTableEntries);
uint cbSealedVirtualSlotsTypeOffset = GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
byte* pThis = (byte*)Unsafe.AsPointer(ref this);
@@ -1387,10 +1387,8 @@ public uint GetFieldOffset(EETypeField eField)
if (eField == EETypeField.ETF_SealedVirtualSlots)
return cbOffset;
- EETypeRareFlags rareFlags = RareFlags;
-
// in the case of sealed vtable entries on static types, we have a UInt sized relative pointer
- if ((rareFlags & EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
+ if (HasSealedVTableEntries)
cbOffset += relativeOrFullPointerOffset;
if (eField == EETypeField.ETF_GenericDefinition)
@@ -1431,6 +1429,7 @@ public uint GetFieldOffset(EETypeField eField)
if (IsDynamicType)
cbOffset += (uint)IntPtr.Size;
+ EETypeRareFlags rareFlags = RareFlags;
if (eField == EETypeField.ETF_DynamicGcStatics)
{
Debug.Assert((rareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0);
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
index 1048c76d583a06..bcbc4008351d0a 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
@@ -304,7 +304,7 @@ public static unsafe object GetUninitializedObject(
throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type));
}
- if (type.HasElementType || type.IsGenericParameter)
+ if (type.HasElementType || type.IsGenericParameter || type.IsFunctionPointer)
{
throw new ArgumentException(SR.Argument_InvalidValue);
}
@@ -319,6 +319,11 @@ public static unsafe object GetUninitializedObject(
throw new NotSupportedException(SR.NotSupported_ManagedActivation);
}
+ if (type.IsAbstract)
+ {
+ throw new MemberAccessException(SR.Acc_CreateAbst);
+ }
+
MethodTable* mt = type.TypeHandle.ToMethodTable();
if (mt->ElementType == Internal.Runtime.EETypeElementType.Void)
@@ -337,11 +342,6 @@ public static unsafe object GetUninitializedObject(
throw new MemberAccessException();
}
- if (mt->IsAbstract)
- {
- throw new MemberAccessException(SR.Acc_CreateAbst);
- }
-
if (mt->IsByRefLike)
{
throw new NotSupportedException(SR.NotSupported_ByRefLike);
diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
index 66e6835792cccc..2dd90578fc83dd 100644
--- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
+++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs
@@ -168,6 +168,7 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo
bool isNullable;
bool isArray;
bool isGeneric;
+ bool hasSealedVTable;
uint flags;
ushort runtimeInterfacesLength = 0;
IntPtr typeManager = IntPtr.Zero;
@@ -184,6 +185,7 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo
flags = pTemplateEEType->Flags;
isArray = pTemplateEEType->IsArray;
isGeneric = pTemplateEEType->IsGeneric;
+ hasSealedVTable = pTemplateEEType->HasSealedVTableEntries;
typeManager = pTemplateEEType->PointerToTypeManager;
Debug.Assert(pTemplateEEType->NumInterfaces == runtimeInterfacesLength);
@@ -260,7 +262,7 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo
runtimeInterfacesLength,
hasFinalizer,
cbOptionalFieldsSize > 0,
- (rareFlags & (int)EETypeRareFlags.HasSealedVTableEntriesFlag) != 0,
+ hasSealedVTable,
isGeneric,
numFunctionPointerTypeParameters,
allocatedNonGCDataSize != 0,
@@ -315,7 +317,7 @@ private static void CreateEETypeWorker(MethodTable* pTemplateEEType, uint hashCo
}
// Copy the sealed vtable entries if they exist on the template type
- if ((rareFlags & (int)EETypeRareFlags.HasSealedVTableEntriesFlag) != 0)
+ if (hasSealedVTable)
{
uint cbSealedVirtualSlotsTypeOffset = pEEType->GetFieldOffset(EETypeField.ETF_SealedVirtualSlots);
*((void**)((byte*)pEEType + cbSealedVirtualSlotsTypeOffset)) = pTemplateEEType->GetSealedVirtualTable();
diff --git a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs
index 914b44d7df76c6..d61d2d41d427ef 100644
--- a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs
+++ b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs
@@ -123,6 +123,11 @@ mdType.Name is "WeakReference" or "WeakReference`1" &&
flagsEx |= (ushort)EETypeFlagsEx.IsTrackedReferenceWithFinalizerFlag;
}
+ if (type.IsIDynamicInterfaceCastable)
+ {
+ flagsEx |= (ushort)EETypeFlagsEx.IDynamicInterfaceCastableFlag;
+ }
+
return flagsEx;
}
diff --git a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs
index 10edf5bf58ccf2..29a1044f2c8068 100644
--- a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs
+++ b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs
@@ -34,9 +34,9 @@ internal enum EETypeFlags : uint
HasPointersFlag = 0x00200000,
///
- /// This type implements IDynamicInterfaceCastable to allow dynamic resolution of interface casts.
+ /// This MethodTable has sealed vtable entries
///
- IDynamicInterfaceCastableFlag = 0x00400000,
+ HasSealedVTableEntriesFlag = 0x00400000,
///
/// This type is generic and one or more of its type parameters is co- or contra-variant. This
@@ -81,6 +81,11 @@ internal enum EETypeFlagsEx : ushort
HasEagerFinalizerFlag = 0x0001,
HasCriticalFinalizerFlag = 0x0002,
IsTrackedReferenceWithFinalizerFlag = 0x0004,
+
+ ///
+ /// This type implements IDynamicInterfaceCastable to allow dynamic resolution of interface casts.
+ ///
+ IDynamicInterfaceCastableFlag = 0x0008,
}
internal enum EETypeKind : uint
@@ -140,10 +145,7 @@ internal enum EETypeRareFlags : int
///
IsHFAFlag = 0x00000100,
- ///
- /// This MethodTable has sealed vtable entries
- ///
- HasSealedVTableEntriesFlag = 0x00000200,
+ // Unused = 0x00000200,
///
/// This dynamically created types has gc statics
@@ -162,10 +164,7 @@ internal enum EETypeRareFlags : int
// UNUSED = 0x00002000,
- ///
- /// This MethodTable is an abstract class (but not an interface).
- ///
- IsAbstractClassFlag = 0x00004000,
+ // UNUSED = 0x00004000,
///
/// This MethodTable is for a Byref-like class (TypedReference, Span<T>,...)
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs
index 3689b9b2a9d082..7d0d3656ddc123 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -648,7 +648,7 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo
ComputeOptionalEETypeFields(factory, relocsOnly);
OutputGCDesc(ref objData);
- OutputFlags(factory, ref objData);
+ OutputFlags(factory, ref objData, relocsOnly);
objData.EmitInt(BaseSize);
OutputRelatedType(factory, ref objData);
@@ -715,7 +715,7 @@ protected virtual void OutputGCDesc(ref ObjectDataBuilder builder)
Debug.Assert(GCDescSize == 0);
}
- private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
+ private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData, bool relocsOnly)
{
uint flags = EETypeBuilderHelpers.ComputeFlags(_type);
@@ -733,9 +733,11 @@ private void OutputFlags(NodeFactory factory, ref ObjectDataBuilder objData)
flags |= (uint)EETypeFlags.GenericVarianceFlag;
}
- if (_type.IsIDynamicInterfaceCastable)
+ if (EmitVirtualSlotsAndInterfaces && !_type.IsArrayTypeWithoutGenericInterfaces())
{
- flags |= (uint)EETypeFlags.IDynamicInterfaceCastableFlag;
+ SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific));
+ if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0)
+ flags |= (uint)EETypeFlags.HasSealedVTableEntriesFlag;
}
if (HasOptionalFields)
@@ -1189,12 +1191,12 @@ protected internal virtual void ComputeOptionalEETypeFields(NodeFactory factory,
_optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.DispatchMap, checked((uint)factory.InterfaceDispatchMapIndirection(canonType).IndexFromBeginningOfArray));
}
- ComputeRareFlags(factory, relocsOnly);
+ ComputeRareFlags(factory);
ComputeNullableValueOffset();
ComputeValueTypeFieldPadding();
}
- private void ComputeRareFlags(NodeFactory factory, bool relocsOnly)
+ private void ComputeRareFlags(NodeFactory factory)
{
uint flags = 0;
@@ -1219,23 +1221,11 @@ private void ComputeRareFlags(NodeFactory factory, bool relocsOnly)
flags |= (uint)EETypeRareFlags.IsHFAFlag;
}
- if (metadataType != null && !_type.IsInterface && metadataType.IsAbstract)
- {
- flags |= (uint)EETypeRareFlags.IsAbstractClassFlag;
- }
-
if (_type.IsByRefLike)
{
flags |= (uint)EETypeRareFlags.IsByRefLikeFlag;
}
- if (EmitVirtualSlotsAndInterfaces && !_type.IsArrayTypeWithoutGenericInterfaces())
- {
- SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific));
- if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0)
- flags |= (uint)EETypeRareFlags.HasSealedVTableEntriesFlag;
- }
-
if (flags != 0)
{
_optionalFieldsBuilder.SetFieldValue(EETypeOptionalFieldTag.RareFlags, flags);