From 963d8f01676cd29dca81aa0148342c9107bcb0f9 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Thu, 7 Sep 2023 10:14:27 -0700 Subject: [PATCH 1/4] Swap HasPointersFlag and OptionalFieldsFlag --- src/coreclr/gc/env/gcenv.object.h | 5 +++++ src/coreclr/nativeaot/Runtime/DebugHeader.cpp | 3 ++- src/coreclr/nativeaot/Runtime/inc/MethodTable.h | 4 ++-- .../tools/Common/Internal/Runtime/MethodTable.Constants.cs | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/coreclr/gc/env/gcenv.object.h b/src/coreclr/gc/env/gcenv.object.h index d04445ea36037c..028ebd2cf71c45 100644 --- a/src/coreclr/gc/env/gcenv.object.h +++ b/src/coreclr/gc/env/gcenv.object.h @@ -127,7 +127,12 @@ class MethodTable bool HasCriticalFinalizer() { +#ifdef FEATURE_NATIVEAOT + const int HasCriticalFinalizerFlag = 0x0002; + return (m_flags & HasCriticalFinalizerFlag) && !HasComponentSize(); +#else return (m_flags & MTFlag_HasCriticalFinalizer) != 0; +#endif } bool IsArray() diff --git a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp index 0519a3098d2458..607f0c4fb72480 100644 --- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp +++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp @@ -269,7 +269,8 @@ 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."); + // TODO, andrewau, bump version number, testing + 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."); diff --git a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h index e77f656f45675d..dda81411fa6d70 100644 --- a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h +++ b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h @@ -139,14 +139,14 @@ class MethodTable HasFinalizerFlag = 0x00100000, // This type contain gc pointers - HasPointersFlag = 0x00200000, + 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, + OptionalFieldsFlag = 0x00200000, // This type is generic. IsGenericFlag = 0x02000000, diff --git a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs index b528195d066b62..396d10dd8e38d4 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs @@ -34,7 +34,7 @@ internal enum EETypeFlags : uint /// /// This type contain GC pointers. /// - HasPointersFlag = 0x00200000, + HasPointersFlag = 0x01000000, /// /// This MethodTable has sealed vtable entries @@ -50,7 +50,7 @@ internal enum EETypeFlags : uint /// /// This type has optional fields present. /// - OptionalFieldsFlag = 0x01000000, + OptionalFieldsFlag = 0x00200000, /// /// This type is generic. From d704f7e6c892533adf7c0ce0e89450a661c2dc23 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Tue, 12 Sep 2023 11:01:23 -0700 Subject: [PATCH 2/4] Flip critical finalizer flag --- src/coreclr/gc/env/gcenv.object.h | 19 +++++++++++++------ src/coreclr/gc/gccommon.cpp | 1 + src/coreclr/gc/gcenv.ee.standalone.inl | 3 +++ src/coreclr/gc/gcinterface.h | 2 +- src/coreclr/gc/gcload.cpp | 1 + src/coreclr/vm/methodtable.h | 14 +++++++------- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/coreclr/gc/env/gcenv.object.h b/src/coreclr/gc/env/gcenv.object.h index 028ebd2cf71c45..9d51193589f636 100644 --- a/src/coreclr/gc/env/gcenv.object.h +++ b/src/coreclr/gc/env/gcenv.object.h @@ -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. @@ -46,7 +50,7 @@ static_assert(sizeof(ObjHeader) == sizeof(uintptr_t), "this assumption is made b #define MTFlag_Category_ValueType 0x00040000 #define MTFlag_Category_ValueType_Mask 0x000C0000 #define MTFlag_ContainsPointers 0x01000000 -#define MTFlag_HasCriticalFinalizer 0x08000000 +#define MTFlag_HasCriticalFinalizer 0x00000002 #define MTFlag_HasFinalizer 0x00100000 #define MTFlag_IsArray 0x00080000 #define MTFlag_Collectible 0x10000000 @@ -127,12 +131,15 @@ class MethodTable bool HasCriticalFinalizer() { -#ifdef FEATURE_NATIVEAOT - const int HasCriticalFinalizerFlag = 0x0002; - return (m_flags & HasCriticalFinalizerFlag) && !HasComponentSize(); -#else - return (m_flags & MTFlag_HasCriticalFinalizer) != 0; +#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 (m_flags & MTFlag_HasCriticalFinalizer) && !HasComponentSize(); } bool IsArray() diff --git a/src/coreclr/gc/gccommon.cpp b/src/coreclr/gc/gccommon.cpp index 413075246fd5c4..2986ce4c2105d4 100644 --- a/src/coreclr/gc/gccommon.cpp +++ b/src/coreclr/gc/gccommon.cpp @@ -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 diff --git a/src/coreclr/gc/gcenv.ee.standalone.inl b/src/coreclr/gc/gcenv.ee.standalone.inl index 24ca20f5837bda..46a18dcc6e1ca2 100644 --- a/src/coreclr/gc/gcenv.ee.standalone.inl +++ b/src/coreclr/gc/gcenv.ee.standalone.inl @@ -14,6 +14,9 @@ extern IGCToCLR* g_theGCToCLR; // GC version that the current runtime supports extern VersionInfo g_runtimeSupportedVersion; +// Does the runtime use the new method table flags +extern bool g_oldMethodTableFlags; + struct StressLogMsg; // When we are building the GC in a standalone environment, we diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index e992082b78ff68..3cf40f920ec9b9 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -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; diff --git a/src/coreclr/gc/gcload.cpp b/src/coreclr/gc/gcload.cpp index 48c1715020d834..05f297f2cb0ea2 100644 --- a/src/coreclr/gc/gcload.cpp +++ b/src/coreclr/gc/gcload.cpp @@ -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; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 69f16bec6ebdd4..91158645c910f3 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -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? @@ -2259,7 +2260,7 @@ class MethodTable DWORD HasCriticalFinalizer() const { LIMITED_METHOD_CONTRACT; - return GetFlag(enum_flag_HasCriticalFinalizer); + return !HasComponentSize() && GetFlag(enum_flag_HasCriticalFinalizer); } //------------------------------------------------------------------- @@ -3292,12 +3293,12 @@ public : enum_flag_UNUSED_ComponentSize_1 = 0x00000001, - enum_flag_StaticsMask = 0x00000006, + enum_flag_StaticsMask = 0x00002004, enum_flag_StaticsMask_NonDynamic = 0x00000000, - enum_flag_StaticsMask_Dynamic = 0x00000002, // dynamic statics (EnC, reflection.emit) + enum_flag_StaticsMask_Dynamic = 0x00002000, // 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 = 0x00002004, // cross module generics statics (NGen) + enum_flag_StaticsMask_IfGenericsThenCrossModule = 0x00002000, // helper constant to get rid of unnecessary check enum_flag_NotInPZM = 0x00000008, // True if this type is not in its PreferredZapModule @@ -3330,7 +3331,6 @@ public : // 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, @@ -3401,7 +3401,7 @@ public : enum_flag_IsTrackedReferenceWithFinalizer = 0x04000000, - enum_flag_HasCriticalFinalizer = 0x08000000, // finalizer must be run on Appdomain Unload + enum_flag_HasCriticalFinalizer = 0x00000002, // finalizer must be run on Appdomain Unload enum_flag_Collectible = 0x10000000, enum_flag_ContainsGenericVariables = 0x20000000, // we cache this flag to help detect these efficiently and // to detect this condition when restoring From 125964d33e03f152211f7b63224a76b6a6d2e99c Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 13 Sep 2023 16:28:21 -0700 Subject: [PATCH 3/4] Make sure both implementations use the same bit for Collectible --- .../RuntimeHelpers.CoreCLR.cs | 2 +- src/coreclr/gc/env/gcenv.object.h | 21 ++++++++----------- .../nativeaot/Runtime/inc/MethodTable.h | 10 +++++---- src/coreclr/vm/methodtable.h | 9 ++++++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 86f1f7d235609a..7a36f5df28bc42 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -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 diff --git a/src/coreclr/gc/env/gcenv.object.h b/src/coreclr/gc/env/gcenv.object.h index 9d51193589f636..5fe92180f4e0a7 100644 --- a/src/coreclr/gc/env/gcenv.object.h +++ b/src/coreclr/gc/env/gcenv.object.h @@ -53,7 +53,7 @@ static_assert(sizeof(ObjHeader) == sizeof(uintptr_t), "this assumption is made b #define MTFlag_HasCriticalFinalizer 0x00000002 #define MTFlag_HasFinalizer 0x00100000 #define MTFlag_IsArray 0x00080000 -#define MTFlag_Collectible 0x10000000 +#define MTFlag_Collectible 0x00200000 #define MTFlag_HasComponentSize 0x80000000 class MethodTable @@ -89,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; } @@ -142,17 +150,6 @@ class MethodTable return (m_flags & MTFlag_HasCriticalFinalizer) && !HasComponentSize(); } - bool IsArray() - { - return (m_flags & MTFlag_IsArray) != 0; - } - - MethodTable * GetParent() - { - _ASSERTE(!IsArray()); - return m_pRelatedType; - } - bool SanityCheck() { return true; diff --git a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h index dda81411fa6d70..32d7c0e37ff236 100644 --- a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h +++ b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h @@ -131,14 +131,15 @@ class MethodTable // simplified version of MethodTable. See LimitedEEType definition below. EETypeKindMask = 0x00030000, - // Unused = 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 + // 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 @@ -146,7 +147,7 @@ class MethodTable GenericVarianceFlag = 0x00800000, // This type has optional fields present. - OptionalFieldsFlag = 0x00200000, + OptionalFieldsFlag = 0x00040000, // This type is generic. IsGenericFlag = 0x02000000, @@ -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, }; diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 91158645c910f3..abb0c65f6cd6e0 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3342,6 +3342,7 @@ 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 + // TODO, AndrewAu, this looks important, do it! enum_flag_StringArrayValues = SET_TRUE(enum_flag_StaticsMask_NonDynamic) | SET_FALSE(enum_flag_NotInPZM) | SET_TRUE(enum_flag_GenericsMask_NonGeneric) | @@ -3387,9 +3388,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 @@ -3401,8 +3403,11 @@ public : enum_flag_IsTrackedReferenceWithFinalizer = 0x04000000, + // TODO, andrewau, move fields to reflect value changes + // GC depends on this bit enum_flag_HasCriticalFinalizer = 0x00000002, // 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 From 6d00f3753e6f43456e2a8e78b491e1d9d88f34b6 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 27 Sep 2023 10:27:04 -0700 Subject: [PATCH 4/4] Code Review feedback --- src/coreclr/gc/env/gcenv.object.h | 22 +++++++++---------- src/coreclr/gc/gcenv.ee.standalone.inl | 2 +- src/coreclr/nativeaot/Runtime/DebugHeader.cpp | 3 +-- .../nativeaot/Runtime/inc/MethodTable.h | 6 ++--- .../Internal/Runtime/MethodTable.Constants.cs | 8 +++---- src/coreclr/vm/methodtable.h | 21 +++++++++--------- 6 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/coreclr/gc/env/gcenv.object.h b/src/coreclr/gc/env/gcenv.object.h index 5fe92180f4e0a7..ff0dbb343ed1dd 100644 --- a/src/coreclr/gc/env/gcenv.object.h +++ b/src/coreclr/gc/env/gcenv.object.h @@ -46,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 0x00000002 -#define MTFlag_HasFinalizer 0x00100000 -#define MTFlag_IsArray 0x00080000 -#define MTFlag_Collectible 0x00200000 -#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 { @@ -112,7 +112,7 @@ class MethodTable bool RequiresAlign8() { - return (m_flags & MTFlag_RequireAlign8) != 0; + return (m_flags & MTFlag_RequiresAlign8) != 0; } bool IsValueType() @@ -147,7 +147,7 @@ class MethodTable return (m_flags & Old_MTFlag_HasCriticalFinalizer) != 0; } #endif - return (m_flags & MTFlag_HasCriticalFinalizer) && !HasComponentSize(); + return !HasComponentSize() && (m_flags & MTFlag_HasCriticalFinalizer); } bool SanityCheck() diff --git a/src/coreclr/gc/gcenv.ee.standalone.inl b/src/coreclr/gc/gcenv.ee.standalone.inl index 46a18dcc6e1ca2..1751e069c3e43a 100644 --- a/src/coreclr/gc/gcenv.ee.standalone.inl +++ b/src/coreclr/gc/gcenv.ee.standalone.inl @@ -14,7 +14,7 @@ extern IGCToCLR* g_theGCToCLR; // GC version that the current runtime supports extern VersionInfo g_runtimeSupportedVersion; -// Does the runtime use the new method table flags +// Does the runtime use the old method table flags extern bool g_oldMethodTableFlags; struct StressLogMsg; diff --git a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp index 607f0c4fb72480..b01339f812031f 100644 --- a/src/coreclr/nativeaot/Runtime/DebugHeader.cpp +++ b/src/coreclr/nativeaot/Runtime/DebugHeader.cpp @@ -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 @@ -269,7 +269,6 @@ 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."); - // TODO, andrewau, bump version number, testing 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."); diff --git a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h index 32d7c0e37ff236..559f9e3b59036b 100644 --- a/src/coreclr/nativeaot/Runtime/inc/MethodTable.h +++ b/src/coreclr/nativeaot/Runtime/inc/MethodTable.h @@ -131,6 +131,9 @@ class MethodTable // simplified version of MethodTable. See LimitedEEType definition below. EETypeKindMask = 0x00030000, + // This type has optional fields present. + OptionalFieldsFlag = 0x00040000, + // GC depends on this bit, this bit must be zero CollectibleFlag = 0x00200000, @@ -146,9 +149,6 @@ class MethodTable // applies to interface and delegate types. GenericVarianceFlag = 0x00800000, - // This type has optional fields present. - OptionalFieldsFlag = 0x00040000, - // This type is generic. IsGenericFlag = 0x02000000, diff --git a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs index 396d10dd8e38d4..4e0d70ab324715 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/MethodTable.Constants.cs @@ -32,9 +32,9 @@ internal enum EETypeFlags : uint HasFinalizerFlag = 0x00100000, /// - /// This type contain GC pointers. + /// This type has optional fields present. /// - HasPointersFlag = 0x01000000, + OptionalFieldsFlag = 0x00200000, /// /// This MethodTable has sealed vtable entries @@ -48,9 +48,9 @@ internal enum EETypeFlags : uint GenericVarianceFlag = 0x00800000, /// - /// This type has optional fields present. + /// This type contain GC pointers. /// - OptionalFieldsFlag = 0x00200000, + HasPointersFlag = 0x01000000, /// /// This type is generic. diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index abb0c65f6cd6e0..8a718cc159ceaa 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3292,15 +3292,15 @@ public : // apply to Strings / Arrays. enum_flag_UNUSED_ComponentSize_1 = 0x00000001, - - enum_flag_StaticsMask = 0x00002004, + // 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 = 0x00002000, // 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 = 0x00002004, // cross module generics statics (NGen) - enum_flag_StaticsMask_IfGenericsThenCrossModule = 0x00002000, // 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 @@ -3329,6 +3329,8 @@ 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_6 = 0x00004000, @@ -3342,8 +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 - // TODO, AndrewAu, this looks important, do it! - 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) | @@ -3403,9 +3405,6 @@ public : enum_flag_IsTrackedReferenceWithFinalizer = 0x04000000, - // TODO, andrewau, move fields to reflect value changes - // GC depends on this bit - enum_flag_HasCriticalFinalizer = 0x00000002, // finalizer must be run on Appdomain Unload // GC depends on this bit enum_flag_Collectible = 0x00200000, enum_flag_ContainsGenericVariables = 0x20000000, // we cache this flag to help detect these efficiently and