diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md index 2fbdacced987f9..204aa45b751eb7 100644 --- a/docs/design/datacontracts/RuntimeTypeSystem.md +++ b/docs/design/datacontracts/RuntimeTypeSystem.md @@ -326,8 +326,9 @@ internal partial struct RuntimeTypeSystem_1 internal enum WFLAGS_LOW : uint { GenericsMask = 0x00000030, - GenericsMask_NonGeneric = 0x00000000, // no instantiation - GenericsMask_TypicalInstantiation = 0x00000030, // the type instantiated at its formal parameters, e.g. List + GenericsMask_NonGeneric = 0x00000000, // no instantiation + GenericsMask_SharedInst = 0x00000020, // shared instantiation, e.g. List<__Canon> or List> + GenericsMask_TypicalInstantiation = 0x00000030, // the type instantiated at its formal parameters, e.g. List StringArrayValues = GenericsMask_NonGeneric, } @@ -402,6 +403,7 @@ internal partial struct RuntimeTypeSystem_1 public bool IsDynamicStatics => GetFlag(WFLAGS2_ENUM.DynamicStatics) != 0; public bool IsTrackedReferenceWithFinalizer => GetFlag(WFLAGS_HIGH.IsTrackedReferenceWithFinalizer) != 0; public bool IsGenericTypeDefinition => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_TypicalInstantiation); + public bool IsSharedByGenericInstantiations => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_SharedInst); } [Flags] @@ -1837,7 +1839,7 @@ Determining where a shared generic method obtains its generic context: return true; } MethodTable mt = _methodTables[md.MethodTable]; - return mt.IsCanonMT && mt.Flags.HasInstantiation; + return mt.Flags.IsSharedByGenericInstantiations; } ``` diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index b72bfe7a7f0fda..563cc497ec4d94 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3701,7 +3701,7 @@ public : // AS YOU ADD NEW FLAGS PLEASE CONSIDER WHETHER Generics::NewInstantiation NEEDS // TO BE UPDATED IN ORDER TO ENSURE THAT METHODTABLES DUPLICATED FOR GENERIC INSTANTIATIONS // CARRY THE CORECT FLAGS. - // [cDAC] [RuntimeTypeSystem]: Contract depends on the values of enum_flag_GenericsMask, enum_flag_GenericsMask_NonGeneric, and enum_flag_GenericsMask_TypicalInst. + // [cDAC] [RuntimeTypeSystem]: Contract depends on the values of enum_flag_GenericsMask, enum_flag_GenericsMask_NonGeneric, enum_flag_GenericsMask_SharedInst, and enum_flag_GenericsMask_TypicalInst. // We are overloading the low 2 bytes of m_dwFlags to be a component size for Strings // and Arrays and some set of flags which we can be assured are of a specified state diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs index 0350cb8412480d..807595cfb8ca67 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs @@ -1435,7 +1435,7 @@ private bool IsSharedByGenericInstantiations(MethodDesc methodDesc) // Check class-level sharing: canonical MethodTable with generic instantiation MethodTable mt = GetOrCreateMethodTable(methodDesc); - return mt.IsCanonMT && mt.Flags.HasInstantiation; + return mt.Flags.IsSharedByGenericInstantiations; } private bool IsAbstract(MethodDesc methodDesc) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs index e82522b79c672e..422f413eba57ac 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/RuntimeTypeSystemHelpers/MethodTableFlags_1.cs @@ -22,8 +22,9 @@ internal enum EEClassOrCanonMTBits internal enum WFLAGS_LOW : uint { GenericsMask = 0x00000030, - GenericsMask_NonGeneric = 0x00000000, // no instantiation - GenericsMask_TypicalInstantiation = 0x00000030, // the type instantiated at its formal parameters, e.g. List + GenericsMask_NonGeneric = 0x00000000, // no instantiation + GenericsMask_SharedInst = 0x00000020, // shared instantiation, e.g. List<__Canon> or List> + GenericsMask_TypicalInstantiation = 0x00000030, // the type instantiated at its formal parameters, e.g. List StringArrayValues = GenericsMask_NonGeneric | @@ -108,6 +109,7 @@ private bool TestFlagWithMask(WFLAGS2_ENUM mask, WFLAGS2_ENUM flag) public bool IsTrackedReferenceWithFinalizer => GetFlag(WFLAGS_HIGH.IsTrackedReferenceWithFinalizer) != 0; public bool IsDynamicStatics => GetFlag(WFLAGS2_ENUM.DynamicStatics) != 0; public bool IsGenericTypeDefinition => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_TypicalInstantiation); + public bool IsSharedByGenericInstantiations => TestFlagWithMask(WFLAGS_LOW.GenericsMask, WFLAGS_LOW.GenericsMask_SharedInst); public bool ContainsGenericVariables => GetFlag(WFLAGS_HIGH.ContainsGenericVariables) != 0; internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)