Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ internal unsafe struct MethodTable
private const uint enum_flag_NonTrivialInterfaceCast = 0x00080000 // enum_flag_Category_Array
| 0x40000000 // enum_flag_ComObject
| 0x00400000 // enum_flag_ICastable;
| 0x00200000 // enum_flag_IDynamicInterfaceCastable;
| 0x10000000 // enum_flag_IDynamicInterfaceCastable;
| 0x00040000; // enum_flag_Category_ValueType

private const int DebugClassNamePtr = // adjust for debug_m_szClassName
Expand Down
53 changes: 31 additions & 22 deletions src/coreclr/gc/env/gcenv.object.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#ifndef __GCENV_OBJECT_H__
#define __GCENV_OBJECT_H__

#ifdef BUILD_AS_STANDALONE
extern bool g_oldMethodTableFlags;
#endif

// ARM requires that 64-bit primitive types are aligned at 64-bit boundaries for interlocked-like operations.
// Additionally the platform ABI requires these types and composite type containing them to be similarly
// aligned when passed as arguments.
Expand Down Expand Up @@ -42,15 +46,15 @@ class ObjHeader

static_assert(sizeof(ObjHeader) == sizeof(uintptr_t), "this assumption is made by the VM!");

#define MTFlag_RequireAlign8 0x00001000
#define MTFlag_Category_ValueType 0x00040000
#define MTFlag_Category_ValueType_Mask 0x000C0000
#define MTFlag_ContainsPointers 0x01000000
#define MTFlag_HasCriticalFinalizer 0x08000000
#define MTFlag_HasFinalizer 0x00100000
#define MTFlag_IsArray 0x00080000
#define MTFlag_Collectible 0x10000000
#define MTFlag_HasComponentSize 0x80000000
#define MTFlag_RequiresAlign8 0x00001000 // enum_flag_RequiresAlign8
#define MTFlag_Category_ValueType 0x00040000 // enum_flag_Category_ValueType
#define MTFlag_Category_ValueType_Mask 0x000C0000 // enum_flag_Category_ValueType_Mask
#define MTFlag_ContainsPointers 0x01000000 // enum_flag_ContainsPointers
#define MTFlag_HasCriticalFinalizer 0x00000002 // enum_flag_HasCriticalFinalizer
#define MTFlag_HasFinalizer 0x00100000 // enum_flag_HasFinalizer
#define MTFlag_IsArray 0x00080000 // enum_flag_Category_Array
#define MTFlag_Collectible 0x00200000 // enum_flag_Collectible
#define MTFlag_HasComponentSize 0x80000000 // enum_flag_HasComponentSize

class MethodTable
{
Expand Down Expand Up @@ -85,6 +89,14 @@ class MethodTable

bool Collectible()
{
#ifdef BUILD_AS_STANDALONE
if (g_oldMethodTableFlags)
{
// This flag is used for .NET 8 or below
const int Old_MTFlag_Collectible = 0x10000000;
return (m_flags & Old_MTFlag_Collectible) != 0;
}
#endif
return (m_flags & MTFlag_Collectible) != 0;
}

Expand All @@ -100,7 +112,7 @@ class MethodTable

bool RequiresAlign8()
{
return (m_flags & MTFlag_RequireAlign8) != 0;
return (m_flags & MTFlag_RequiresAlign8) != 0;
}

bool IsValueType()
Expand All @@ -127,18 +139,15 @@ class MethodTable

bool HasCriticalFinalizer()
{
return (m_flags & MTFlag_HasCriticalFinalizer) != 0;
}

bool IsArray()
{
return (m_flags & MTFlag_IsArray) != 0;
}

MethodTable * GetParent()
{
_ASSERTE(!IsArray());
return m_pRelatedType;
#ifdef BUILD_AS_STANDALONE
if (g_oldMethodTableFlags)
{
// This flag is used for .NET 8 or below
const int Old_MTFlag_HasCriticalFinalizer = 0x08000000;
return (m_flags & Old_MTFlag_HasCriticalFinalizer) != 0;
}
#endif
return !HasComponentSize() && (m_flags & MTFlag_HasCriticalFinalizer);
}

bool SanityCheck()
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/gc/gccommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ IGCHandleManager* g_theGCHandleManager;
#ifdef BUILD_AS_STANDALONE
IGCToCLR* g_theGCToCLR;
VersionInfo g_runtimeSupportedVersion;
bool g_oldMethodTableFlags;
#endif // BUILD_AS_STANDALONE

#ifdef GC_CONFIG_DRIVEN
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/gc/gcenv.ee.standalone.inl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ extern IGCToCLR* g_theGCToCLR;
// GC version that the current runtime supports
extern VersionInfo g_runtimeSupportedVersion;

// Does the runtime use the old method table flags
extern bool g_oldMethodTableFlags;

struct StressLogMsg;

// When we are building the GC in a standalone environment, we
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/gc/gcinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

// The major version of the IGCToCLR interface. Breaking changes to this interface
// require bumps in the major version number.
#define EE_INTERFACE_MAJOR_VERSION 1
#define EE_INTERFACE_MAJOR_VERSION 2

struct ScanContext;
struct gc_alloc_context;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/gc/gcload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ GC_VersionInfo(/* InOut */ VersionInfo* info)
// For example, GC would only call functions on g_theGCToCLR interface that the runtime
// supports.
g_runtimeSupportedVersion = *info;
g_oldMethodTableFlags = g_runtimeSupportedVersion.MajorVersion < 2;
#endif
info->MajorVersion = GC_INTERFACE_MAJOR_VERSION;
info->MinorVersion = GC_INTERFACE_MINOR_VERSION;
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/nativeaot/Runtime/DebugHeader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct DotNetRuntimeDebugHeader
// This counter can be incremented to indicate breaking changes
// This field must be encoded little endian, regardless of the typical endianness of
// the machine
const uint16_t MajorVersion = 3;
const uint16_t MajorVersion = 4;

// This counter can be incremented to indicate back-compatible changes
// This field must be encoded little endian, regardless of the typical endianness of
Expand Down Expand Up @@ -269,7 +269,7 @@ extern "C" void PopulateDebugHeaders()

static_assert(MethodTable::Flags::EETypeKindMask == 0x00030000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::HasFinalizerFlag == 0x00100000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::HasPointersFlag == 0x00200000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::HasPointersFlag == 0x01000000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::GenericVarianceFlag == 0x00800000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::IsGenericFlag == 0x02000000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
static_assert(MethodTable::Flags::ElementTypeMask == 0x7C000000, "The debugging data contract has a hard coded dependency on this value of MethodTable::Flags. If you change this value you must bump major_version_number.");
Expand Down
16 changes: 9 additions & 7 deletions src/coreclr/nativeaot/Runtime/inc/MethodTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,23 +131,24 @@ class MethodTable
// simplified version of MethodTable. See LimitedEEType definition below.
EETypeKindMask = 0x00030000,

// Unused = 0x00040000,
// This type has optional fields present.
OptionalFieldsFlag = 0x00040000,

// GC depends on this bit, this bit must be zero
CollectibleFlag = 0x00200000,

IsDynamicTypeFlag = 0x00080000,

// This MethodTable represents a type which requires finalization
// GC depends on this bit, this type requires finalization
HasFinalizerFlag = 0x00100000,

// This type contain gc pointers
HasPointersFlag = 0x00200000,
// GC depends on this bit, this type contain gc pointers
HasPointersFlag = 0x01000000,

// This type is generic and one or more of it's type parameters is co- or contra-variant. This only
// applies to interface and delegate types.
GenericVarianceFlag = 0x00800000,

// This type has optional fields present.
OptionalFieldsFlag = 0x01000000,

// This type is generic.
IsGenericFlag = 0x02000000,

Expand All @@ -162,6 +163,7 @@ class MethodTable
enum ExtendedFlags
{
HasEagerFinalizerFlag = 0x0001,
// GC depends on this bit, this type has a critical finalizer
HasCriticalFinalizerFlag = 0x0002,
IsTrackedReferenceWithFinalizerFlag = 0x0004,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ internal enum EETypeFlags : uint
HasFinalizerFlag = 0x00100000,

/// <summary>
/// This type contain GC pointers.
/// This type has optional fields present.
/// </summary>
HasPointersFlag = 0x00200000,
OptionalFieldsFlag = 0x00200000,

/// <summary>
/// This MethodTable has sealed vtable entries
Expand All @@ -48,9 +48,9 @@ internal enum EETypeFlags : uint
GenericVarianceFlag = 0x00800000,

/// <summary>
/// This type has optional fields present.
/// This type contain GC pointers.
/// </summary>
OptionalFieldsFlag = 0x01000000,
HasPointersFlag = 0x01000000,

/// <summary>
/// This type is generic.
Expand Down
28 changes: 16 additions & 12 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,7 @@ class MethodTable
void SetHasCriticalFinalizer()
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(!HasComponentSize());
SetFlag(enum_flag_HasCriticalFinalizer);
}
// Does this class have non-trivial finalization requirements?
Expand All @@ -2259,7 +2260,7 @@ class MethodTable
DWORD HasCriticalFinalizer() const
{
LIMITED_METHOD_CONTRACT;
return GetFlag(enum_flag_HasCriticalFinalizer);
return !HasComponentSize() && GetFlag(enum_flag_HasCriticalFinalizer);
}

//-------------------------------------------------------------------
Expand Down Expand Up @@ -3291,15 +3292,15 @@ public :
// apply to Strings / Arrays.

enum_flag_UNUSED_ComponentSize_1 = 0x00000001,

enum_flag_StaticsMask = 0x00000006,
// GC depends on this bit
enum_flag_HasCriticalFinalizer = 0x00000002, // finalizer must be run on Appdomain Unload
enum_flag_StaticsMask = 0x0000000C,
enum_flag_StaticsMask_NonDynamic = 0x00000000,
enum_flag_StaticsMask_Dynamic = 0x00000002, // dynamic statics (EnC, reflection.emit)
enum_flag_StaticsMask_Dynamic = 0x00000008, // dynamic statics (EnC, reflection.emit)
enum_flag_StaticsMask_Generics = 0x00000004, // generics statics
enum_flag_StaticsMask_CrossModuleGenerics = 0x00000006, // cross module generics statics (NGen)
enum_flag_StaticsMask_IfGenericsThenCrossModule = 0x00000002, // helper constant to get rid of unnecessary check
enum_flag_StaticsMask_CrossModuleGenerics = 0x0000000C, // cross module generics statics (NGen)
enum_flag_StaticsMask_IfGenericsThenCrossModule = 0x00000008, // helper constant to get rid of unnecessary check

enum_flag_NotInPZM = 0x00000008, // True if this type is not in its PreferredZapModule

enum_flag_GenericsMask = 0x00000030,
enum_flag_GenericsMask_NonGeneric = 0x00000000, // no instantiation
Expand Down Expand Up @@ -3328,9 +3329,10 @@ public :

enum_flag_IsByRefLike = 0x00001000,

enum_flag_NotInPZM = 0x00002000, // True if this type is not in its PreferredZapModule

// In a perfect world we would fill these flags using other flags that we already have
// which have a constant value for something which has a component size.
enum_flag_UNUSED_ComponentSize_5 = 0x00002000,
enum_flag_UNUSED_ComponentSize_6 = 0x00004000,
enum_flag_UNUSED_ComponentSize_7 = 0x00008000,

Expand All @@ -3342,7 +3344,8 @@ public :
// As you change the flags in WFLAGS_LOW_ENUM you also need to change this
// to be up to date to reflect the default values of those flags for the
// case where this MethodTable is for a String or Array
enum_flag_StringArrayValues = SET_TRUE(enum_flag_StaticsMask_NonDynamic) |
enum_flag_StringArrayValues = SET_FALSE(enum_flag_HasCriticalFinalizer) |
SET_TRUE(enum_flag_StaticsMask_NonDynamic) |
SET_FALSE(enum_flag_NotInPZM) |
SET_TRUE(enum_flag_GenericsMask_NonGeneric) |
SET_FALSE(enum_flag_HasVariance) |
Expand Down Expand Up @@ -3387,9 +3390,10 @@ public :
enum_flag_Category_ElementTypeMask = 0x000E0000, // bits that matter for element type mask


// GC depends on this bit
enum_flag_HasFinalizer = 0x00100000, // instances require finalization

enum_flag_IDynamicInterfaceCastable = 0x00200000, // class implements IDynamicInterfaceCastable interface
enum_flag_IDynamicInterfaceCastable = 0x10000000, // class implements IDynamicInterfaceCastable interface

enum_flag_ICastable = 0x00400000, // class implements ICastable interface

Expand All @@ -3401,8 +3405,8 @@ public :

enum_flag_IsTrackedReferenceWithFinalizer = 0x04000000,

enum_flag_HasCriticalFinalizer = 0x08000000, // finalizer must be run on Appdomain Unload
enum_flag_Collectible = 0x10000000,
// GC depends on this bit
enum_flag_Collectible = 0x00200000,
enum_flag_ContainsGenericVariables = 0x20000000, // we cache this flag to help detect these efficiently and
// to detect this condition when restoring

Expand Down