From 2744c1cb7dbd5e8bd5d17e2819fdcea9385b1e21 Mon Sep 17 00:00:00 2001 From: petris Date: Tue, 5 Jul 2022 20:22:02 +0200 Subject: [PATCH 01/52] Make Type.GetTypeCode an intrinsic Makes Type.GetTypeCode a JIT intrinsic for primitive types, enums and strings. Makes Type.IsEnum use intrinsics instead of IsSubclassOf Makes Enum.GetUnderlyingType use Type.GetTypeCode Moves the legacy FCall to InternalGetUnderlyingTypeImpl, so that the non-intrinsic GetTypeCode can use it. Introduces JIT tests checking the generated codegen. --- .../src/System/Enum.CoreCLR.cs | 50 ++++++++++++- src/coreclr/jit/fgbasic.cpp | 1 + src/coreclr/jit/importer.cpp | 73 +++++++++++++++++++ src/coreclr/jit/namedintrinsiclist.h | 1 + .../src/System/Enum.NativeAot.cs | 5 ++ src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/reflectioninvocation.cpp | 2 +- src/coreclr/vm/reflectioninvocation.h | 2 +- .../src/System/RuntimeType.cs | 2 +- .../System.Private.CoreLib/src/System/Type.cs | 3 +- .../src/System/Enum.Mono.cs | 5 ++ src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 37 +++++++++- 12 files changed, 176 insertions(+), 7 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index b8e41c06c23db..ddfe352df0464 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; @@ -20,7 +21,54 @@ public abstract partial class Enum private extern CorElementType InternalGetCorElementType(); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType InternalGetUnderlyingType(RuntimeType enumType); + internal static extern RuntimeType InternalGetUnderlyingTypeImpl(RuntimeType enumType); + + internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) + { + Type type; + TypeCode typeCode = Type.GetTypeCode(enumType); + switch (typeCode) + { + case TypeCode.Boolean: + type = typeof(bool); + break; + case TypeCode.Char: + type = typeof(char); + break; + case TypeCode.SByte: + type = typeof(sbyte); + break; + case TypeCode.Byte: + type = typeof(byte); + break; + case TypeCode.Int16: + type = typeof(short); + break; + case TypeCode.UInt16: + type = typeof(ushort); + break; + case TypeCode.Int32: + type = typeof(int); + break; + case TypeCode.UInt32: + type = typeof(uint); + break; + case TypeCode.Int64: + type = typeof(long); + break; + case TypeCode.UInt64: + type = typeof(ulong); + break; + case TypeCode.Single: + type = typeof(float); + break; + default: + Debug.Assert(typeCode == TypeCode.Double); + type = typeof(double); + break; + } + return (RuntimeType)type; + } private static EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true) { diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index f818fd6018e6d..5c94bd3c8bfb6 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1165,6 +1165,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: case NI_System_Type_GetTypeFromHandle: + case NI_System_Type_GetTypeCode: case NI_System_String_get_Length: case NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness: case NI_System_Numerics_BitOperations_PopCount: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 697cd838dc4d5..3a25d410ce9b1 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4218,6 +4218,75 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } + case NI_System_Type_GetTypeCode: + { + if (impStackTop().val->IsCall()) + { + GenTreeCall* call = impStackTop().val->AsCall(); + if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + { + assert(call->gtArgs.CountArgs() == 1); + CORINFO_CLASS_HANDLE hClass = + gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); + if (hClass != NO_CLASS_HANDLE) + { + int typeCode = -1; + switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) + { + case CORINFO_TYPE_BOOL: + typeCode = 3; + break; + case CORINFO_TYPE_CHAR: + typeCode = 4; + break; + case CORINFO_TYPE_BYTE: + typeCode = 5; + break; + case CORINFO_TYPE_UBYTE: + typeCode = 6; + break; + case CORINFO_TYPE_SHORT: + typeCode = 7; + break; + case CORINFO_TYPE_USHORT: + typeCode = 8; + break; + case CORINFO_TYPE_INT: + typeCode = 9; + break; + case CORINFO_TYPE_UINT: + typeCode = 10; + break; + case CORINFO_TYPE_LONG: + typeCode = 11; + break; + case CORINFO_TYPE_ULONG: + typeCode = 12; + break; + case CORINFO_TYPE_FLOAT: + typeCode = 13; + break; + case CORINFO_TYPE_DOUBLE: + typeCode = 14; + break; + default: + if (hClass == impGetStringClass()) + { + typeCode = 18; + } + break; + } + if (typeCode != -1) + { + retNode = gtNewIconNode(typeCode); + impPopStack(); + } + } + } + } + break; + } + case NI_System_Threading_Thread_get_ManagedThreadId: { if (impStackTop().val->OperIs(GT_RET_EXPR)) @@ -5715,6 +5784,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_GetTypeFromHandle; } + else if (strcmp(methodName, "GetTypeCode") == 0) + { + result = NI_System_Type_GetTypeCode; + } } else if (strcmp(className, "String") == 0) { diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index ca812ab66e311..46c4623e61972 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -62,6 +62,7 @@ enum NamedIntrinsic : unsigned short NI_System_Type_op_Equality, NI_System_Type_op_Inequality, NI_System_Type_GetTypeFromHandle, + NI_System_Type_GetTypeCode, NI_System_Array_Clone, NI_System_Array_GetLength, NI_System_Array_GetLowerBound, diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs index 7a4928b1cd03f..737882ce18444 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs @@ -105,6 +105,11 @@ internal static bool TryGetUnboxedValueOfEnumOrInteger(object value, out ulong r } } + internal static Type InternalGetUnderlyingTypeImpl(RuntimeType enumType) + { + return InternalGetUnderlyingType(enumType); + } + internal static Type InternalGetUnderlyingType(RuntimeType enumType) { Debug.Assert(enumType is RuntimeType); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index d2c3822f9de83..dc749c02dffc6 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -55,7 +55,7 @@ FCFuncStart(gDependentHandleFuncs) FCFuncEnd() FCFuncStart(gEnumFuncs) - FCFuncElement("InternalGetUnderlyingType", ReflectionEnum::InternalGetEnumUnderlyingType) + FCFuncElement("InternalGetUnderlyingTypeImpl", ReflectionEnum::InternalGetEnumUnderlyingTypeImpl) FCFuncElement("InternalGetCorElementType", ReflectionEnum::InternalGetCorElementType) FCFuncElement("InternalBoxEnum", ReflectionEnum::InternalBoxEnum) FCFuncEnd() diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index 83eaa09471011..cecd391346ff1 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1901,7 +1901,7 @@ extern "C" void QCALLTYPE ReflectionSerialization_GetUninitializedObject(QCall:: //************************************************************************************************* //************************************************************************************************* -FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingType, ReflectClassBaseObject *target) { +FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingTypeImpl, ReflectClassBaseObject *target) { FCALL_CONTRACT; VALIDATEOBJECT(target); diff --git a/src/coreclr/vm/reflectioninvocation.h b/src/coreclr/vm/reflectioninvocation.h index 780ac7a29b418..8aac101bb936b 100644 --- a/src/coreclr/vm/reflectioninvocation.h +++ b/src/coreclr/vm/reflectioninvocation.h @@ -76,7 +76,7 @@ extern "C" void QCALLTYPE ReflectionSerialization_GetUninitializedObject(QCall:: class ReflectionEnum { public: - static FCDECL1(Object *, InternalGetEnumUnderlyingType, ReflectClassBaseObject *target); + static FCDECL1(Object *, InternalGetEnumUnderlyingTypeImpl, ReflectClassBaseObject *target); static FCDECL1(INT32, InternalGetCorElementType, Object *pRefThis); static FCDECL2_IV(Object*, InternalBoxEnum, ReflectClassBaseObject* pEnumType, INT64 value); }; diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 1af83dc8ce592..8e4c319f1ca6a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -203,7 +203,7 @@ protected override TypeCode GetTypeCodeImpl() else if (ReferenceEquals(this, typeof(DateTime))) typeCode = TypeCode.DateTime; else if (IsEnum) - typeCode = GetTypeCode(Enum.InternalGetUnderlyingType(this)); + typeCode = GetTypeCode(Enum.InternalGetUnderlyingTypeImpl(this)); else typeCode = TypeCode.Object; break; diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 4907875d591c5..a9d3db7076f74 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -104,7 +104,7 @@ public virtual Type[] GetGenericParameterConstraints() public bool IsContextful => IsContextfulImpl(); protected virtual bool IsContextfulImpl() => false; - public virtual bool IsEnum => IsSubclassOf(typeof(Enum)); + public virtual bool IsEnum => IsValueType && IsAssignableTo(typeof(Enum)); public bool IsMarshalByRef => IsMarshalByRefImpl(); protected virtual bool IsMarshalByRefImpl() => false; public bool IsPrimitive => IsPrimitiveImpl(); @@ -438,6 +438,7 @@ public static Type[] GetTypeArray(object[] args) return cls; } + [Intrinsic] public static TypeCode GetTypeCode(Type? type) { return type?.GetTypeCodeImpl() ?? TypeCode.Empty; diff --git a/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs index 765a2865f60ce..be5e72765a371 100644 --- a/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs @@ -33,6 +33,11 @@ private CorElementType InternalGetCorElementType() return InternalGetCorElementType(new QCallTypeHandle(ref this_type)); } + internal static RuntimeType InternalGetUnderlyingTypeImpl(RuntimeType enumType) + { + return InternalGetUnderlyingType(enumType); + } + internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) { RuntimeType? res = null; diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 0c91318abb34f..a8ae637468e0d 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -99,6 +99,27 @@ public static int Main(string[] args) TestIsAssignableFrom(); + AreSame(Type.GetTypeCode(null), TypeCode.Empty); + AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); + AreSame(Type.GetTypeCode(typeof(char)), TypeCode.Char); + AreSame(Type.GetTypeCode(typeof(sbyte)), TypeCode.SByte); + AreSame(Type.GetTypeCode(typeof(byte)), TypeCode.Byte); + AreSame(Type.GetTypeCode(typeof(short)), TypeCode.Int16); + AreSame(Type.GetTypeCode(typeof(ushort)), TypeCode.UInt16); + AreSame(Type.GetTypeCode(typeof(int)), TypeCode.Int32); + AreSame(Type.GetTypeCode(typeof(uint)), TypeCode.UInt32); + AreSame(Type.GetTypeCode(typeof(long)), TypeCode.Int64); + AreSame(Type.GetTypeCode(typeof(ulong)), TypeCode.UInt64); + AreSame(Type.GetTypeCode(typeof(float)), TypeCode.Single); + AreSame(Type.GetTypeCode(typeof(double)), TypeCode.Double); + AreSame(Type.GetTypeCode(typeof(decimal)), TypeCode.Decimal); + AreSame(Type.GetTypeCode(typeof(string)), TypeCode.String); + AreSame(Type.GetTypeCode(typeof(object)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(DateTime)), TypeCode.DateTime); + AreSame(Type.GetTypeCode(typeof(GenericStruct)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(SimpleStruct)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(SimpleEnum)), TypeCode.Int32); + return 100 + _errors; } @@ -135,7 +156,6 @@ public static int Main(string[] args) [MethodImpl(MethodImplOptions.NoInlining)] private static dynamic CreateDynamic2() => new { Name = "Test" }; - static void IsTrue(bool expression, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") { if (!expression) @@ -170,6 +190,16 @@ static void ThrowsNRE(Action action, [CallerLineNumber] int line = 0, [CallerFil } Console.WriteLine($"Line {line}: test failed (expected: NullReferenceException)"); } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void AreSame(TypeCode a, TypeCode b, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") + { + if (a != b) + { + Console.WriteLine($"{file}:L{line} test failed (not equal)."); + _errors++; + } + } } public struct GenericStruct @@ -177,6 +207,11 @@ public struct GenericStruct public T field; } +public struct SimpleStruct +{ + public int field; +} + public enum SimpleEnum { A,B,C From f20053b2f40d73256d3d90d04473c6cbc0e9a54c Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 6 Jul 2022 16:29:07 +0200 Subject: [PATCH 02/52] Change IsEnum to an intrinsic --- src/coreclr/jit/fgbasic.cpp | 1 + src/coreclr/jit/importer.cpp | 14 ++++++++++++++ src/coreclr/jit/namedintrinsiclist.h | 1 + .../System.Private.CoreLib/src/System/Type.cs | 2 +- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 12 ++++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 5c94bd3c8bfb6..13b277f311607 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1162,6 +1162,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed break; // These are foldable if the first argument is a constant + case NI_System_Type_get_IsEnum: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: case NI_System_Type_GetTypeFromHandle: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 3a25d410ce9b1..b20c6419137fe 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4173,6 +4173,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } + case NI_System_Type_get_IsEnum: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: { @@ -4196,6 +4197,15 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { switch (ni) { + case NI_System_Type_get_IsEnum: + retNode = gtNewIconNode( + (eeIsValueClass(hClass) && + // getTypeForPrimitiveNumericClass seems to not normalize enums + info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && + info.compCompHnd->getTypeForPrimitiveValueClass(hClass) != CORINFO_TYPE_UNDEF) + ? 1 + : 0); + break; case NI_System_Type_get_IsValueType: retNode = gtNewIconNode( (eeIsValueClass(hClass) && @@ -5788,6 +5798,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_GetTypeCode; } + else if (strcmp(methodName, "get_IsEnum") == 0) + { + result = NI_System_Type_get_IsEnum; + } } else if (strcmp(className, "String") == 0) { diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 46c4623e61972..8e3c8f1d27fb4 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -55,6 +55,7 @@ enum NamedIntrinsic : unsigned short NI_System_GC_KeepAlive, NI_System_Threading_Thread_get_CurrentThread, NI_System_Threading_Thread_get_ManagedThreadId, + NI_System_Type_get_IsEnum, NI_System_Type_get_IsValueType, NI_System_Type_get_IsByRefLike, NI_System_Type_IsAssignableFrom, diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index a9d3db7076f74..afb0469591b48 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -104,7 +104,7 @@ public virtual Type[] GetGenericParameterConstraints() public bool IsContextful => IsContextfulImpl(); protected virtual bool IsContextfulImpl() => false; - public virtual bool IsEnum => IsValueType && IsAssignableTo(typeof(Enum)); + public virtual bool IsEnum => IsSubclassOf(typeof(Enum)); public bool IsMarshalByRef => IsMarshalByRefImpl(); protected virtual bool IsMarshalByRefImpl() => false; public bool IsPrimitive => IsPrimitiveImpl(); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index a8ae637468e0d..20f0c8ae54af4 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -99,6 +99,18 @@ public static int Main(string[] args) TestIsAssignableFrom(); + IsFalse(typeof(byte).IsEnum); + IsFalse(typeof(int).IsEnum); + IsFalse(typeof(int?).IsEnum); + IsFalse(typeof(int*).IsEnum); + IsFalse(typeof(void).IsEnum); + IsFalse(typeof(object).IsEnum); + IsFalse(typeof(Enum).IsEnum); + IsFalse(typeof(ValueType).IsEnum); + IsFalse(typeof(GenericStruct).IsEnum); + IsFalse(typeof(SimpleStruct).IsEnum); + IsTrue (typeof(SimpleEnum).IsValueType); + AreSame(Type.GetTypeCode(null), TypeCode.Empty); AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); AreSame(Type.GetTypeCode(typeof(char)), TypeCode.Char); From 195bad6e15fd727182ab35ef113b79351e31a1dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:20:28 +0200 Subject: [PATCH 03/52] Fix formatting --- src/coreclr/jit/importer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index b20c6419137fe..0960d76a9ec22 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4201,7 +4201,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, retNode = gtNewIconNode( (eeIsValueClass(hClass) && // getTypeForPrimitiveNumericClass seems to not normalize enums - info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && + info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) + == CORINFO_TYPE_UNDEF && info.compCompHnd->getTypeForPrimitiveValueClass(hClass) != CORINFO_TYPE_UNDEF) ? 1 : 0); From f60efb6015e42feaae5ee6ff452141913772a97c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 17:51:39 +0200 Subject: [PATCH 04/52] Fix formatting 2 --- src/coreclr/jit/importer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 0960d76a9ec22..aaabafef36ea4 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4201,8 +4201,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, retNode = gtNewIconNode( (eeIsValueClass(hClass) && // getTypeForPrimitiveNumericClass seems to not normalize enums - info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) - == CORINFO_TYPE_UNDEF && + info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == + CORINFO_TYPE_UNDEF && info.compCompHnd->getTypeForPrimitiveValueClass(hClass) != CORINFO_TYPE_UNDEF) ? 1 : 0); From 4317f2ddeee6709259477f6b058ccf5b1e4c6973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 18:24:22 +0200 Subject: [PATCH 05/52] Formatting fix 3 --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index aaabafef36ea4..adcaebc3592c1 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4202,7 +4202,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, (eeIsValueClass(hClass) && // getTypeForPrimitiveNumericClass seems to not normalize enums info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == - CORINFO_TYPE_UNDEF && + CORINFO_TYPE_UNDEF && info.compCompHnd->getTypeForPrimitiveValueClass(hClass) != CORINFO_TYPE_UNDEF) ? 1 : 0); From 616be5de4ab200f1ddcbf521bc0d414d68125842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:03:23 +0200 Subject: [PATCH 06/52] Fix test --- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 20f0c8ae54af4..668b203a12543 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -109,7 +109,7 @@ public static int Main(string[] args) IsFalse(typeof(ValueType).IsEnum); IsFalse(typeof(GenericStruct).IsEnum); IsFalse(typeof(SimpleStruct).IsEnum); - IsTrue (typeof(SimpleEnum).IsValueType); + IsTrue (typeof(SimpleEnum).IsEnum); AreSame(Type.GetTypeCode(null), TypeCode.Empty); AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); From dff9f046b0eb9782e2cd0ee61020b1ef9f22e665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 20:17:36 +0200 Subject: [PATCH 07/52] Fallback to the FCall for nint/nuint enums --- .../src/System/Enum.CoreCLR.cs | 56 +++++-------------- 1 file changed, 15 insertions(+), 41 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index ddfe352df0464..484b4fbbd4d52 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -25,48 +25,22 @@ public abstract partial class Enum internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) { - Type type; - TypeCode typeCode = Type.GetTypeCode(enumType); - switch (typeCode) + Type type = Type.GetTypeCode(enumType) switch { - case TypeCode.Boolean: - type = typeof(bool); - break; - case TypeCode.Char: - type = typeof(char); - break; - case TypeCode.SByte: - type = typeof(sbyte); - break; - case TypeCode.Byte: - type = typeof(byte); - break; - case TypeCode.Int16: - type = typeof(short); - break; - case TypeCode.UInt16: - type = typeof(ushort); - break; - case TypeCode.Int32: - type = typeof(int); - break; - case TypeCode.UInt32: - type = typeof(uint); - break; - case TypeCode.Int64: - type = typeof(long); - break; - case TypeCode.UInt64: - type = typeof(ulong); - break; - case TypeCode.Single: - type = typeof(float); - break; - default: - Debug.Assert(typeCode == TypeCode.Double); - type = typeof(double); - break; - } + TypeCode.Boolean => typeof(bool), + TypeCode.Char => typeof(char), + TypeCode.SByte => typeof(sbyte), + TypeCode.Byte => typeof(byte), + TypeCode.Int16 => typeof(short), + TypeCode.UInt16 => typeof(ushort), + TypeCode.Int32 => typeof(int), + TypeCode.UInt32 => typeof(uint), + TypeCode.Int64 => typeof(long), + TypeCode.UInt64 => typeof(ulong), + TypeCode.Single => typeof(float), + TypeCode.Double => typeof(double), + _ => InternalGetUnderlyingTypeImpl(enumType); + }; return (RuntimeType)type; } From 6959e9096e000bdcb64b73940b25ac48acfe2a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 6 Jul 2022 20:38:17 +0200 Subject: [PATCH 08/52] Fix compilation --- src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index 484b4fbbd4d52..1cee6b91b4116 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -39,7 +39,7 @@ internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) TypeCode.UInt64 => typeof(ulong), TypeCode.Single => typeof(float), TypeCode.Double => typeof(double), - _ => InternalGetUnderlyingTypeImpl(enumType); + _ => InternalGetUnderlyingTypeImpl(enumType) }; return (RuntimeType)type; } From c27672c396bf9ebd99a901c4a0ba2984301dc9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 7 Jul 2022 01:34:05 +0200 Subject: [PATCH 09/52] Add missing Intrinsic --- src/libraries/System.Private.CoreLib/src/System/Type.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index afb0469591b48..b99c7460b8d67 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -104,7 +104,7 @@ public virtual Type[] GetGenericParameterConstraints() public bool IsContextful => IsContextfulImpl(); protected virtual bool IsContextfulImpl() => false; - public virtual bool IsEnum => IsSubclassOf(typeof(Enum)); + public virtual bool IsEnum { [Intrinsic] get => IsSubclassOf(typeof(Enum)); } public bool IsMarshalByRef => IsMarshalByRefImpl(); protected virtual bool IsMarshalByRefImpl() => false; public bool IsPrimitive => IsPrimitiveImpl(); From 1745d84b940628b6e028dc2ff33b4e7ac2fdea28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 7 Jul 2022 02:53:08 +0200 Subject: [PATCH 10/52] Fix void handling --- src/coreclr/jit/importer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index adcaebc3592c1..8a21ca0509ecf 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4198,12 +4198,14 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, switch (ni) { case NI_System_Type_get_IsEnum: + CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); retNode = gtNewIconNode( (eeIsValueClass(hClass) && // getTypeForPrimitiveNumericClass seems to not normalize enums info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && - info.compCompHnd->getTypeForPrimitiveValueClass(hClass) != CORINFO_TYPE_UNDEF) + // we need to check for void here + infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) ? 1 : 0); break; From 509842b17e1ef5cb5f959d018f34c62c709ee3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 7 Jul 2022 03:09:48 +0200 Subject: [PATCH 11/52] Fix compilation --- src/coreclr/jit/importer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 8a21ca0509ecf..e9ce67e5d0201 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4198,6 +4198,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, switch (ni) { case NI_System_Type_get_IsEnum: + { CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); retNode = gtNewIconNode( (eeIsValueClass(hClass) && @@ -4209,6 +4210,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, ? 1 : 0); break; + } case NI_System_Type_get_IsValueType: retNode = gtNewIconNode( (eeIsValueClass(hClass) && From e1300f42874ba694bb6505727c106f393826414f Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 7 Jul 2022 19:52:32 +0200 Subject: [PATCH 12/52] Fix formatting --- src/coreclr/jit/importer.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e9ce67e5d0201..7312355fcbe36 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4200,15 +4200,15 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_get_IsEnum: { CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); - retNode = gtNewIconNode( - (eeIsValueClass(hClass) && - // getTypeForPrimitiveNumericClass seems to not normalize enums - info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == - CORINFO_TYPE_UNDEF && - // we need to check for void here - infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) - ? 1 - : 0); + retNode = + gtNewIconNode((eeIsValueClass(hClass) && + // getTypeForPrimitiveNumericClass seems to not normalize enums + info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == + CORINFO_TYPE_UNDEF && + // we need to check for void here + infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) + ? 1 + : 0); break; } case NI_System_Type_get_IsValueType: From 94f19da51cd3f1db2a9f348105975badaa023832 Mon Sep 17 00:00:00 2001 From: petris Date: Fri, 8 Jul 2022 23:19:43 +0200 Subject: [PATCH 13/52] Add typeof support to IsKnownConstant --- .../src/System/Enum.CoreCLR.cs | 1 + src/coreclr/jit/gentree.cpp | 32 ++++ src/coreclr/jit/gentree.h | 2 + src/coreclr/jit/importer.cpp | 180 ++++++++---------- src/coreclr/jit/morph.cpp | 2 +- .../System.Private.CoreLib/src/System/Enum.cs | 5 + .../CompilerServices/RuntimeHelpers.cs | 3 + 7 files changed, 124 insertions(+), 101 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index 1cee6b91b4116..625b9e78a9aeb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -23,6 +23,7 @@ public abstract partial class Enum [MethodImpl(MethodImplOptions.InternalCall)] internal static extern RuntimeType InternalGetUnderlyingTypeImpl(RuntimeType enumType); + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) { Type type = Type.GetTypeCode(enumType) switch diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ae7583871a2bc..cba3a5a505c71 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18349,6 +18349,38 @@ bool GenTree::IsArrayAddr(GenTreeArrAddr** pArrAddr) return false; } +//------------------------------------------------------------------------ +// IsTypeof: Checks if the tree is a typeof() +// +// Arguments: +// tree - the tree that is checked +// handle - (optional, default nullptr) - if non-null is set to the type +// +// Return Value: +// Is the tree typeof() +// +bool GenTree::IsTypeof(CORINFO_CLASS_HANDLE* handle) +{ + if (tree->IsCall()) + { + GenTreeCall* call = tree->AsCall(); + if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + { + assert(call->gtArgs.CountArgs() == 1); + CORINFO_CLASS_HANDLE hClass = gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); + if (hClass != NO_CLASS_HANDLE) + { + if (handle != nullptr) + { + *handle = hClass; + } + return true; + } + } + } + return false; +} + // Note that the value of the below field doesn't matter; it exists only to provide a distinguished address. // // static diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index f180d0fbe70c1..7e3a1dea0b59b 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2264,6 +2264,8 @@ struct GenTree } inline bool IsHelperCall(); + bool IsTypeof(CORINFO_CLASS_HANDLE* handle = nullptr) const; + bool gtOverflow() const; bool gtOverflowEx() const; bool gtSetFlags() const; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 7312355fcbe36..673270346286c 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3912,12 +3912,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant: { GenTree* op1 = impPopStack().val; - if (op1->OperIsConst()) + if (op1->OperIsConst() || op1->IsTypeof()) { // op1 is a known constant, replace with 'true'. retNode = gtNewIconNode(1); JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to true early\n"); - // We can also consider FTN_ADDR and typeof(T) here + // We can also consider FTN_ADDR here } else { @@ -4185,121 +4185,101 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // to `true` or `false` // e.g., `typeof(int).IsValueType` => `true` // e.g., `typeof(Span).IsByRefLike` => `true` - if (impStackTop().val->IsCall()) + CORINFO_CLASS_HANDLE hClass = nullptr; + if (impStackTop().val->IsTypeof(&hClass)) { - GenTreeCall* call = impStackTop().val->AsCall(); - if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + switch (ni) { - assert(call->gtArgs.CountArgs() == 1); - CORINFO_CLASS_HANDLE hClass = - gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); - if (hClass != NO_CLASS_HANDLE) + case NI_System_Type_get_IsEnum: { - switch (ni) - { - case NI_System_Type_get_IsEnum: - { - CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); - retNode = - gtNewIconNode((eeIsValueClass(hClass) && - // getTypeForPrimitiveNumericClass seems to not normalize enums - info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == - CORINFO_TYPE_UNDEF && - // we need to check for void here - infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) - ? 1 - : 0); - break; - } - case NI_System_Type_get_IsValueType: - retNode = gtNewIconNode( - (eeIsValueClass(hClass) && - // pointers are not value types (e.g. typeof(int*).IsValueType is false) - info.compCompHnd->asCorInfoType(hClass) != CORINFO_TYPE_PTR) - ? 1 - : 0); - break; - case NI_System_Type_get_IsByRefLike: - retNode = gtNewIconNode( - (info.compCompHnd->getClassAttribs(hClass) & CORINFO_FLG_BYREF_LIKE) ? 1 : 0); - break; - default: - NO_WAY("Intrinsic not supported in this path."); - } - impPopStack(); // drop CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE call + CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); + retNode = gtNewIconNode( + (eeIsValueClass(hClass) && + // getTypeForPrimitiveNumericClass seems to not normalize enums + info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && + // we need to check for void here + infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) + ? 1 + : 0); + break; } + case NI_System_Type_get_IsValueType: + retNode = + gtNewIconNode((eeIsValueClass(hClass) && + // pointers are not value types (e.g. typeof(int*).IsValueType is false) + info.compCompHnd->asCorInfoType(hClass) != CORINFO_TYPE_PTR) + ? 1 + : 0); + break; + case NI_System_Type_get_IsByRefLike: + retNode = gtNewIconNode( + (info.compCompHnd->getClassAttribs(hClass) & CORINFO_FLG_BYREF_LIKE) ? 1 : 0); + break; + default: + NO_WAY("Intrinsic not supported in this path."); } + impPopStack(); // drop CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE call } break; } case NI_System_Type_GetTypeCode: { - if (impStackTop().val->IsCall()) + CORINFO_CLASS_HANDLE hClass = nullptr; + if (impStackTop().val->IsTypeof(&hClass)) { - GenTreeCall* call = impStackTop().val->AsCall(); - if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + int typeCode = -1; + switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) { - assert(call->gtArgs.CountArgs() == 1); - CORINFO_CLASS_HANDLE hClass = - gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); - if (hClass != NO_CLASS_HANDLE) - { - int typeCode = -1; - switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) - { - case CORINFO_TYPE_BOOL: - typeCode = 3; - break; - case CORINFO_TYPE_CHAR: - typeCode = 4; - break; - case CORINFO_TYPE_BYTE: - typeCode = 5; - break; - case CORINFO_TYPE_UBYTE: - typeCode = 6; - break; - case CORINFO_TYPE_SHORT: - typeCode = 7; - break; - case CORINFO_TYPE_USHORT: - typeCode = 8; - break; - case CORINFO_TYPE_INT: - typeCode = 9; - break; - case CORINFO_TYPE_UINT: - typeCode = 10; - break; - case CORINFO_TYPE_LONG: - typeCode = 11; - break; - case CORINFO_TYPE_ULONG: - typeCode = 12; - break; - case CORINFO_TYPE_FLOAT: - typeCode = 13; - break; - case CORINFO_TYPE_DOUBLE: - typeCode = 14; - break; - default: - if (hClass == impGetStringClass()) - { - typeCode = 18; - } - break; - } - if (typeCode != -1) + case CORINFO_TYPE_BOOL: + typeCode = 3; + break; + case CORINFO_TYPE_CHAR: + typeCode = 4; + break; + case CORINFO_TYPE_BYTE: + typeCode = 5; + break; + case CORINFO_TYPE_UBYTE: + typeCode = 6; + break; + case CORINFO_TYPE_SHORT: + typeCode = 7; + break; + case CORINFO_TYPE_USHORT: + typeCode = 8; + break; + case CORINFO_TYPE_INT: + typeCode = 9; + break; + case CORINFO_TYPE_UINT: + typeCode = 10; + break; + case CORINFO_TYPE_LONG: + typeCode = 11; + break; + case CORINFO_TYPE_ULONG: + typeCode = 12; + break; + case CORINFO_TYPE_FLOAT: + typeCode = 13; + break; + case CORINFO_TYPE_DOUBLE: + typeCode = 14; + break; + default: + if (hClass == impGetStringClass()) { - retNode = gtNewIconNode(typeCode); - impPopStack(); + typeCode = 18; } - } + break; + } + if (typeCode != -1) + { + retNode = gtNewIconNode(typeCode); + impPopStack(); } } - break; } case NI_System_Threading_Thread_get_ManagedThreadId: diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 1c3394e7d68b3..b5e45d5ea80c3 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -11922,7 +11922,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) assert(!optValnumCSE_phase); JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to "); - if (op1->OperIsConst()) + if (op1->OperIsConst() || op1->IsTypeof()) { // We're lucky to catch a constant here while importer was not JITDUMP("true\n"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 194f0b6906835..0f0d5b4f76377 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -304,8 +304,13 @@ internal static string[] InternalGetNames(RuntimeType enumType) => // Get all of the names GetEnumInfo(enumType, true).Names; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Type GetUnderlyingType(Type enumType) { + // call the actual implementation directly so that intrinsics can be used + if (RuntimeHelpers.IsKnownConstant(enumType) && enumType is RuntimeType runtimeType && enumType.IsEnum) + InternalGetUnderlyingType(runtimeType); + ArgumentNullException.ThrowIfNull(enumType); return enumType.GetEnumUnderlyingType(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs index 5b52162fa14af..47014ec5d718f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs @@ -103,6 +103,9 @@ internal static bool IsPrimitiveType(this CorElementType et) // The following intrinsics return true if input is a compile-time constant // Feel free to add more overloads on demand #pragma warning disable IDE0060 + [Intrinsic] + internal static bool IsKnownConstant(Type? t) => false; + [Intrinsic] internal static bool IsKnownConstant(string? t) => false; From c3dc12f14ad0c69d6d311353f32664cdb0ee578d Mon Sep 17 00:00:00 2001 From: petris Date: Sat, 9 Jul 2022 00:08:23 +0200 Subject: [PATCH 14/52] Move the helper --- src/coreclr/jit/compiler.h | 2 ++ src/coreclr/jit/gentree.cpp | 64 ++++++++++++++++++------------------ src/coreclr/jit/gentree.h | 2 -- src/coreclr/jit/importer.cpp | 6 ++-- src/coreclr/jit/morph.cpp | 2 +- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ec1bcb0c0bd98..e820e547ae423 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2822,6 +2822,8 @@ class Compiler CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull); // Check if this tree is a gc static base helper call bool gtIsStaticGCBaseHelperCall(GenTree* tree); + // Check if this tree is a typeof() + bool gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle = nullptr); GenTree* gtCallGetDefinedRetBufLclAddr(GenTreeCall* call); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index f2b88fcb03987..b3856f84da212 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17950,6 +17950,38 @@ bool Compiler::gtIsStaticGCBaseHelperCall(GenTree* tree) return false; } +//------------------------------------------------------------------------ +// gtIsTypeof: Checks if the tree is a typeof() +// +// Arguments: +// tree - the tree that is checked +// handle - (optional, default nullptr) - if non-null is set to the type +// +// Return Value: +// Is the tree typeof() +// +bool Compiler::gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle) +{ + if (tree->IsCall()) + { + GenTreeCall* call = tree->AsCall(); + if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + { + assert(call->gtArgs.CountArgs() == 1); + CORINFO_CLASS_HANDLE hClass = gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); + if (hClass != NO_CLASS_HANDLE) + { + if (handle != nullptr) + { + *handle = hClass; + } + return true; + } + } + } + return false; +} + //------------------------------------------------------------------------ // gtCallGetDefinedRetBufLclAddr: // Get the tree corresponding to the address of the retbuf that this call defines. @@ -18251,38 +18283,6 @@ bool GenTree::IsArrayAddr(GenTreeArrAddr** pArrAddr) return false; } -//------------------------------------------------------------------------ -// IsTypeof: Checks if the tree is a typeof() -// -// Arguments: -// tree - the tree that is checked -// handle - (optional, default nullptr) - if non-null is set to the type -// -// Return Value: -// Is the tree typeof() -// -bool GenTree::IsTypeof(CORINFO_CLASS_HANDLE* handle) -{ - if (tree->IsCall()) - { - GenTreeCall* call = tree->AsCall(); - if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) - { - assert(call->gtArgs.CountArgs() == 1); - CORINFO_CLASS_HANDLE hClass = gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); - if (hClass != NO_CLASS_HANDLE) - { - if (handle != nullptr) - { - *handle = hClass; - } - return true; - } - } - } - return false; -} - //------------------------------------------------------------------------ // Create: Create or retrieve a field sequence for the given field handle. // diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 1647661680021..d572143ac4e08 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2213,8 +2213,6 @@ struct GenTree } inline bool IsHelperCall(); - bool IsTypeof(CORINFO_CLASS_HANDLE* handle = nullptr) const; - bool gtOverflow() const; bool gtOverflowEx() const; bool gtSetFlags() const; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 0bc1a4dbdcd3e..58bd3ee04f43e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3862,7 +3862,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Runtime_CompilerServices_RuntimeHelpers_IsKnownConstant: { GenTree* op1 = impPopStack().val; - if (op1->OperIsConst() || op1->IsTypeof()) + if (op1->OperIsConst() || gtIsTypeof(op1)) { // op1 is a known constant, replace with 'true'. retNode = gtNewIconNode(1); @@ -4136,7 +4136,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // e.g., `typeof(int).IsValueType` => `true` // e.g., `typeof(Span).IsByRefLike` => `true` CORINFO_CLASS_HANDLE hClass = nullptr; - if (impStackTop().val->IsTypeof(&hClass)) + if (gtIsTypeof(impStackTop().val, &hClass)) { switch (ni) { @@ -4176,7 +4176,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_GetTypeCode: { CORINFO_CLASS_HANDLE hClass = nullptr; - if (impStackTop().val->IsTypeof(&hClass)) + if (gtIsTypeof(impStackTop().val, &hClass)) { int typeCode = -1; switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 4e928330a1156..cd7f14256f1b3 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -11779,7 +11779,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) assert(!optValnumCSE_phase); JITDUMP("\nExpanding RuntimeHelpers.IsKnownConstant to "); - if (op1->OperIsConst() || op1->IsTypeof()) + if (op1->OperIsConst() || gtIsTypeof(op1)) { // We're lucky to catch a constant here while importer was not JITDUMP("true\n"); From eb0bc1ba0c1373144631f10b94d41bf1d6b3d68b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 9 Jul 2022 00:38:53 +0200 Subject: [PATCH 15/52] Add missing break --- src/coreclr/jit/importer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 58bd3ee04f43e..96776147ccbf2 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4230,6 +4230,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, impPopStack(); } } + break; } case NI_System_Threading_Thread_get_ManagedThreadId: From 098d47200153be7ff8b0ea530c5d6eaecb16f9a1 Mon Sep 17 00:00:00 2001 From: petris Date: Sat, 9 Jul 2022 17:14:29 +0200 Subject: [PATCH 16/52] Revert some changes, simplify code --- .../src/System/Enum.CoreCLR.cs | 25 +------------------ src/coreclr/jit/importer.cpp | 9 +++++-- .../src/System/Enum.NativeAot.cs | 5 ---- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/reflectioninvocation.cpp | 2 +- src/coreclr/vm/reflectioninvocation.h | 2 +- .../System.Private.CoreLib/src/System/Enum.cs | 4 --- .../src/System/RuntimeType.cs | 22 +++++++++++++++- .../src/System/Enum.Mono.cs | 5 ---- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 5 ++++ 10 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index 625b9e78a9aeb..b8e41c06c23db 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; @@ -21,29 +20,7 @@ public abstract partial class Enum private extern CorElementType InternalGetCorElementType(); [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeType InternalGetUnderlyingTypeImpl(RuntimeType enumType); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) - { - Type type = Type.GetTypeCode(enumType) switch - { - TypeCode.Boolean => typeof(bool), - TypeCode.Char => typeof(char), - TypeCode.SByte => typeof(sbyte), - TypeCode.Byte => typeof(byte), - TypeCode.Int16 => typeof(short), - TypeCode.UInt16 => typeof(ushort), - TypeCode.Int32 => typeof(int), - TypeCode.UInt32 => typeof(uint), - TypeCode.Int64 => typeof(long), - TypeCode.UInt64 => typeof(ulong), - TypeCode.Single => typeof(float), - TypeCode.Double => typeof(double), - _ => InternalGetUnderlyingTypeImpl(enumType) - }; - return (RuntimeType)type; - } + internal static extern RuntimeType InternalGetUnderlyingType(RuntimeType enumType); private static EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true) { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 96776147ccbf2..e2a3d5283cf50 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4149,8 +4149,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && // we need to check for void here infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) - ? 1 - : 0); + ? 1 + : 0); break; } case NI_System_Type_get_IsValueType: @@ -4217,6 +4217,11 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case CORINFO_TYPE_DOUBLE: typeCode = 14; break; + case CORINFO_TYPE_NATIVEINT: + case CORINFO_TYPE_NATIVEUINT: + case CORINFO_TYPE_PTR: + typeCode = 1; + break; default: if (hClass == impGetStringClass()) { diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs index 737882ce18444..7a4928b1cd03f 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Enum.NativeAot.cs @@ -105,11 +105,6 @@ internal static bool TryGetUnboxedValueOfEnumOrInteger(object value, out ulong r } } - internal static Type InternalGetUnderlyingTypeImpl(RuntimeType enumType) - { - return InternalGetUnderlyingType(enumType); - } - internal static Type InternalGetUnderlyingType(RuntimeType enumType) { Debug.Assert(enumType is RuntimeType); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index dc749c02dffc6..d2c3822f9de83 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -55,7 +55,7 @@ FCFuncStart(gDependentHandleFuncs) FCFuncEnd() FCFuncStart(gEnumFuncs) - FCFuncElement("InternalGetUnderlyingTypeImpl", ReflectionEnum::InternalGetEnumUnderlyingTypeImpl) + FCFuncElement("InternalGetUnderlyingType", ReflectionEnum::InternalGetEnumUnderlyingType) FCFuncElement("InternalGetCorElementType", ReflectionEnum::InternalGetCorElementType) FCFuncElement("InternalBoxEnum", ReflectionEnum::InternalBoxEnum) FCFuncEnd() diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index cecd391346ff1..83eaa09471011 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1901,7 +1901,7 @@ extern "C" void QCALLTYPE ReflectionSerialization_GetUninitializedObject(QCall:: //************************************************************************************************* //************************************************************************************************* -FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingTypeImpl, ReflectClassBaseObject *target) { +FCIMPL1(Object *, ReflectionEnum::InternalGetEnumUnderlyingType, ReflectClassBaseObject *target) { FCALL_CONTRACT; VALIDATEOBJECT(target); diff --git a/src/coreclr/vm/reflectioninvocation.h b/src/coreclr/vm/reflectioninvocation.h index 8aac101bb936b..780ac7a29b418 100644 --- a/src/coreclr/vm/reflectioninvocation.h +++ b/src/coreclr/vm/reflectioninvocation.h @@ -76,7 +76,7 @@ extern "C" void QCALLTYPE ReflectionSerialization_GetUninitializedObject(QCall:: class ReflectionEnum { public: - static FCDECL1(Object *, InternalGetEnumUnderlyingTypeImpl, ReflectClassBaseObject *target); + static FCDECL1(Object *, InternalGetEnumUnderlyingType, ReflectClassBaseObject *target); static FCDECL1(INT32, InternalGetCorElementType, Object *pRefThis); static FCDECL2_IV(Object*, InternalBoxEnum, ReflectClassBaseObject* pEnumType, INT64 value); }; diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 0f0d5b4f76377..a14114547c539 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -307,10 +307,6 @@ internal static string[] InternalGetNames(RuntimeType enumType) => [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Type GetUnderlyingType(Type enumType) { - // call the actual implementation directly so that intrinsics can be used - if (RuntimeHelpers.IsKnownConstant(enumType) && enumType is RuntimeType runtimeType && enumType.IsEnum) - InternalGetUnderlyingType(runtimeType); - ArgumentNullException.ThrowIfNull(enumType); return enumType.GetEnumUnderlyingType(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 8e4c319f1ca6a..fef7d8267d831 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -139,8 +139,28 @@ public override Array GetEnumValues() return ret; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override Type GetEnumUnderlyingType() { + if (RuntimeHelpers.IsKnownConstant(this)) + { + switch (Type.GetTypeCode(this)) + { + case TypeCode.Boolean: return typeof(bool); + case TypeCode.Char: return typeof(char); + case TypeCode.SByte: return typeof(sbyte); + case TypeCode.Byte: return typeof(byte); + case TypeCode.Int16: return typeof(short); + case TypeCode.UInt16: return typeof(ushort); + case TypeCode.Int32: return typeof(int); + case TypeCode.UInt32: return typeof(uint); + case TypeCode.Int64: return typeof(long); + case TypeCode.UInt64: return typeof(ulong); + case TypeCode.Single: return typeof(float); + case TypeCode.Double: return typeof(double); + } + } + if (!IsEnum) throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); @@ -203,7 +223,7 @@ protected override TypeCode GetTypeCodeImpl() else if (ReferenceEquals(this, typeof(DateTime))) typeCode = TypeCode.DateTime; else if (IsEnum) - typeCode = GetTypeCode(Enum.InternalGetUnderlyingTypeImpl(this)); + typeCode = GetTypeCode(Enum.InternalGetUnderlyingType(this)); else typeCode = TypeCode.Object; break; diff --git a/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs index be5e72765a371..765a2865f60ce 100644 --- a/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Enum.Mono.cs @@ -33,11 +33,6 @@ private CorElementType InternalGetCorElementType() return InternalGetCorElementType(new QCallTypeHandle(ref this_type)); } - internal static RuntimeType InternalGetUnderlyingTypeImpl(RuntimeType enumType) - { - return InternalGetUnderlyingType(enumType); - } - internal static RuntimeType InternalGetUnderlyingType(RuntimeType enumType) { RuntimeType? res = null; diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 668b203a12543..51a4d4a44f755 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -112,6 +112,11 @@ public static int Main(string[] args) IsTrue (typeof(SimpleEnum).IsEnum); AreSame(Type.GetTypeCode(null), TypeCode.Empty); + AreSame(Type.GetTypeCode(typeof(void*)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(nint)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(nuint)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(IntPtr)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(UIntPtr)), TypeCode.Object); AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); AreSame(Type.GetTypeCode(typeof(char)), TypeCode.Char); AreSame(Type.GetTypeCode(typeof(sbyte)), TypeCode.SByte); From f05b1b25ba9459c550fc134b061e304462a2b4d3 Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 10 Jul 2022 16:09:56 +0200 Subject: [PATCH 17/52] Use gtIsTypeHandleToRuntimeTypeHelper --- src/coreclr/jit/gentree.cpp | 2 +- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b3856f84da212..9f310edd7322e 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17965,7 +17965,7 @@ bool Compiler::gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle) if (tree->IsCall()) { GenTreeCall* call = tree->AsCall(); - if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE)) + if (gtIsTypeHandleToRuntimeTypeHelper(call)) { assert(call->gtArgs.CountArgs() == 1); CORINFO_CLASS_HANDLE hClass = gtGetHelperArgClassHandle(call->gtArgs.GetArgByIndex(0)->GetEarlyNode()); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 51a4d4a44f755..b53fb366213c4 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -96,6 +96,8 @@ public static int Main(string[] args) ThrowsNRE(() => { IsValueType(_varStringNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varNullableIntNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varStringNull); }); + ThrowsNRE(() => { Type.GetTypeFromHandle(default).IsValueType; }); + ThrowsNRE(() => { Type.GetTypeFromHandle(new RuntimeTypeHandle()).IsValueType; }); TestIsAssignableFrom(); @@ -103,6 +105,7 @@ public static int Main(string[] args) IsFalse(typeof(int).IsEnum); IsFalse(typeof(int?).IsEnum); IsFalse(typeof(int*).IsEnum); + IsFalse(typeof(nint).IsEnum); IsFalse(typeof(void).IsEnum); IsFalse(typeof(object).IsEnum); IsFalse(typeof(Enum).IsEnum); From 02cd2526cf53c435a5046b505d4be62737160fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sun, 10 Jul 2022 16:53:09 +0200 Subject: [PATCH 18/52] Fix test --- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index b53fb366213c4..0b830666a12ee 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -96,8 +96,8 @@ public static int Main(string[] args) ThrowsNRE(() => { IsValueType(_varStringNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varNullableIntNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varStringNull); }); - ThrowsNRE(() => { Type.GetTypeFromHandle(default).IsValueType; }); - ThrowsNRE(() => { Type.GetTypeFromHandle(new RuntimeTypeHandle()).IsValueType; }); + ThrowsNRE(() => { _ = Type.GetTypeFromHandle(default).IsValueType; }); + ThrowsNRE(() => { _ = Type.GetTypeFromHandle(new RuntimeTypeHandle()).IsValueType; }); TestIsAssignableFrom(); From 753dca25920d0fe661b5d2b41f8b52a3ec906425 Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 10 Jul 2022 18:23:16 +0200 Subject: [PATCH 19/52] Add __reftype tests --- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 0b830666a12ee..1c23a1415453d 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -92,12 +92,19 @@ public static int Main(string[] args) IsTrue (IsValueTypeRef(ref _varGenericStructStr)); IsTrue (IsValueTypeRef(ref _varEnum)); + // test __reftype + int testInt = 0; + IsTrue (__reftype(__makeref(testInt)).IsValueType); + object testObject = null; + IsFalse(__reftype(__makeref(testInt)).IsValueType); + ThrowsNRE(() => { IsValueType(_varNullableIntNull); }); ThrowsNRE(() => { IsValueType(_varStringNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varNullableIntNull); }); ThrowsNRE(() => { IsValueTypeRef(ref _varStringNull); }); ThrowsNRE(() => { _ = Type.GetTypeFromHandle(default).IsValueType; }); ThrowsNRE(() => { _ = Type.GetTypeFromHandle(new RuntimeTypeHandle()).IsValueType; }); + ThrowsNRE(() => { _ = __reftype(default).IsValueType; }); TestIsAssignableFrom(); From a65d81ca6ed1e1ecbddc086c0fe9d65e5e64823e Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 10 Jul 2022 20:11:36 +0200 Subject: [PATCH 20/52] Make more places use gtIsTypeof --- src/coreclr/jit/importer.cpp | 56 +++++++------------ .../TypeIntrinsics.IsAssignableFrom.cs | 10 +++- .../TypeIntrinsics.IsAssignableTo.cs | 10 +++- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 8 ++- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1537956341b14..d5cbd651ee71e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4135,7 +4135,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // to `true` or `false` // e.g., `typeof(int).IsValueType` => `true` // e.g., `typeof(Span).IsByRefLike` => `true` - CORINFO_CLASS_HANDLE hClass = nullptr; + CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; if (gtIsTypeof(impStackTop().val, &hClass)) { switch (ni) @@ -4175,7 +4175,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_GetTypeCode: { - CORINFO_CLASS_HANDLE hClass = nullptr; + CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; if (gtIsTypeof(impStackTop().val, &hClass)) { int typeCode = -1; @@ -5418,37 +5418,24 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) // // to true/false - if (typeTo->IsCall() && typeFrom->IsCall()) + // make sure both arguments are `typeof()` + CORINFO_CLASS_HANDLE hClassTo = NO_CLASS_HANDLE; + CORINFO_CLASS_HANDLE hClassFrom = NO_CLASS_HANDLE; + if (gtIsTypeof(typeTo, &hClassTo) && gtIsTypeof(typeFrom, &hClassFrom)) { - // make sure both arguments are `typeof()` - CORINFO_METHOD_HANDLE hTypeof = eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE); - if ((typeTo->AsCall()->gtCallMethHnd == hTypeof) && (typeFrom->AsCall()->gtCallMethHnd == hTypeof)) + TypeCompareState castResult = info.compCompHnd->compareTypesForCast(hClassFrom, hClassTo); + if (castResult == TypeCompareState::May) { - assert((typeTo->AsCall()->gtArgs.CountArgs() == 1) && (typeFrom->AsCall()->gtArgs.CountArgs() == 1)); - CORINFO_CLASS_HANDLE hClassTo = - gtGetHelperArgClassHandle(typeTo->AsCall()->gtArgs.GetArgByIndex(0)->GetEarlyNode()); - CORINFO_CLASS_HANDLE hClassFrom = - gtGetHelperArgClassHandle(typeFrom->AsCall()->gtArgs.GetArgByIndex(0)->GetEarlyNode()); - - if (hClassTo == NO_CLASS_HANDLE || hClassFrom == NO_CLASS_HANDLE) - { - return nullptr; - } - - TypeCompareState castResult = info.compCompHnd->compareTypesForCast(hClassFrom, hClassTo); - if (castResult == TypeCompareState::May) - { - // requires runtime check - // e.g. __Canon, COMObjects, Nullable - return nullptr; - } + // requires runtime check + // e.g. __Canon, COMObjects, Nullable + return nullptr; + } - GenTreeIntCon* retNode = gtNewIconNode((castResult == TypeCompareState::Must) ? 1 : 0); - impPopStack(); // drop both CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE calls - impPopStack(); + GenTreeIntCon* retNode = gtNewIconNode((castResult == TypeCompareState::Must) ? 1 : 0); + impPopStack(); // drop both CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE calls + impPopStack(); - return retNode; - } + return retNode; } return nullptr; @@ -20334,15 +20321,10 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo, return; } } - else + else if (gtIsTypeof(curArgVal)) { - if (curArgVal->IsHelperCall() && gtIsTypeHandleToRuntimeTypeHelper(curArgVal->AsCall()) && - (gtGetHelperArgClassHandle(curArgVal->AsCall()->gtArgs.GetArgByIndex(0)->GetEarlyNode()) != - NO_CLASS_HANDLE)) - { - inlCurArgInfo->argIsInvariant = true; - inlCurArgInfo->argHasSideEff = false; - } + inlCurArgInfo->argIsInvariant = true; + inlCurArgInfo->argHasSideEff = false; } bool isExact = false; diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs index d6520d30f9b7e..5714422a3a8de 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs @@ -71,7 +71,7 @@ public static void TestIsAssignableFrom() IsFalse(typeof(float).IsAssignableFrom(typeof(SimpleEnum_uint))); IsFalse(typeof(SimpleEnum_uint).IsAssignableFrom(typeof(ValueType))); - // Covariance/Contravariance + // Covariance/Contravariance IsTrue (typeof(IEnumerable).IsAssignableFrom(typeof(List))); IsTrue (typeof(IEnumerable).IsAssignableFrom(typeof(List))); IsTrue (typeof(IEnumerable).IsAssignableFrom(typeof(IList))); @@ -166,6 +166,14 @@ public static void TestIsAssignableFrom() IsFalse(typeof(Vector128).IsAssignableFrom(typeof(Vector))); IsFalse(typeof(Vector256).IsAssignableFrom(typeof(Vector))); + // null type + IsFalse(typeof(int).IsAssignableFrom(null)); + IsFalse(typeof(object).IsAssignableFrom(null)); + ThrowsNRE(() => { _ = null.IsAssignableFrom(typeof(int)); }); + ThrowsNRE(() => { _ = null.IsAssignableFrom(typeof(object)); }); + ThrowsNRE(() => { _ = null.IsAssignableFrom(null); }); + ThrowsNRE(() => { _ = null.IsAssignableFrom(null); }); + // System.__Canon IsTrue (IsAssignableFrom, KeyValuePair>()); IsTrue (IsAssignableFrom, KeyValuePair>()); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs index 6a7ccc73e362b..2880335c05418 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs @@ -71,7 +71,7 @@ public static void TestIsAssignableTo() IsFalse(typeof(SimpleEnum_uint).IsAssignableTo(typeof(float))); IsFalse(typeof(ValueType).IsAssignableTo(typeof(SimpleEnum_uint))); - // Covariance/Contravariance + // Covariance/Contravariance IsTrue (typeof(List).IsAssignableTo(typeof(IEnumerable))); IsTrue (typeof(List).IsAssignableTo(typeof(IEnumerable))); IsTrue (typeof(IList).IsAssignableTo(typeof(IEnumerable))); @@ -166,6 +166,14 @@ public static void TestIsAssignableTo() IsFalse(typeof(Vector).IsAssignableTo(typeof(Vector128))); IsFalse(typeof(Vector).IsAssignableTo(typeof(Vector256))); + // null type + IsFalse(typeof(int).IsAssignableTo(null)); + IsFalse(typeof(object).IsAssignableTo(null)); + ThrowsNRE(() => { _ = null.IsAssignableTo(typeof(int)); }); + ThrowsNRE(() => { _ = null.IsAssignableTo(typeof(object)); }); + ThrowsNRE(() => { _ = null.IsAssignableTo(null); }); + ThrowsNRE(() => { _ = null.IsAssignableTo(null); }); + // System.__Canon IsTrue (IsAssignableTo, KeyValuePair>()); IsTrue (IsAssignableTo, KeyValuePair>()); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 1c23a1415453d..b9f64f3a560c5 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -96,7 +96,7 @@ public static int Main(string[] args) int testInt = 0; IsTrue (__reftype(__makeref(testInt)).IsValueType); object testObject = null; - IsFalse(__reftype(__makeref(testInt)).IsValueType); + IsFalse(__reftype(__makeref(testObject)).IsValueType); ThrowsNRE(() => { IsValueType(_varNullableIntNull); }); ThrowsNRE(() => { IsValueType(_varStringNull); }); @@ -121,6 +121,7 @@ public static int Main(string[] args) IsFalse(typeof(SimpleStruct).IsEnum); IsTrue (typeof(SimpleEnum).IsEnum); + AreSame(Type.GetTypeCode(__reftype(default)), TypeCode.Empty); AreSame(Type.GetTypeCode(null), TypeCode.Empty); AreSame(Type.GetTypeCode(typeof(void*)), TypeCode.Object); AreSame(Type.GetTypeCode(typeof(nint)), TypeCode.Object); @@ -147,6 +148,11 @@ public static int Main(string[] args) AreSame(Type.GetTypeCode(typeof(SimpleStruct)), TypeCode.Object); AreSame(Type.GetTypeCode(typeof(SimpleEnum)), TypeCode.Int32); + int testInt = 0; + AreSame(Type.GetTypeCode(__reftype(__makeref(testInt))), TypeCode.Int32); + object testObject = null; + AreSame(Type.GetTypeCode(__reftype(__makeref(testObject))), TypeCode.Object); + return 100 + _errors; } From 9f1eb3e3bfff6c9cfaae307b07d653e26feda980 Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 10 Jul 2022 20:52:09 +0200 Subject: [PATCH 21/52] Fix tests --- src/coreclr/jit/importer.cpp | 2 +- .../Intrinsics/TypeIntrinsics.IsAssignableFrom.cs | 14 ++++++++++---- .../Intrinsics/TypeIntrinsics.IsAssignableTo.cs | 14 ++++++++++---- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 12 ++++-------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index d5cbd651ee71e..d1e94908e1873 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5419,7 +5419,7 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) // to true/false // make sure both arguments are `typeof()` - CORINFO_CLASS_HANDLE hClassTo = NO_CLASS_HANDLE; + CORINFO_CLASS_HANDLE hClassTo = NO_CLASS_HANDLE; CORINFO_CLASS_HANDLE hClassFrom = NO_CLASS_HANDLE; if (gtIsTypeof(typeTo, &hClassTo) && gtIsTypeof(typeFrom, &hClassFrom)) { diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs index 5714422a3a8de..706cae6a8e83f 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableFrom.cs @@ -169,10 +169,16 @@ public static void TestIsAssignableFrom() // null type IsFalse(typeof(int).IsAssignableFrom(null)); IsFalse(typeof(object).IsAssignableFrom(null)); - ThrowsNRE(() => { _ = null.IsAssignableFrom(typeof(int)); }); - ThrowsNRE(() => { _ = null.IsAssignableFrom(typeof(object)); }); - ThrowsNRE(() => { _ = null.IsAssignableFrom(null); }); - ThrowsNRE(() => { _ = null.IsAssignableFrom(null); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableFrom(typeof(int)); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableFrom(typeof(object)); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableFrom(null); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableFrom(null); }); + IsFalse(typeof(int).IsAssignableFrom(__reftype(default))); + IsFalse(typeof(object).IsAssignableFrom(__reftype(default))); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableFrom(typeof(int)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableFrom(typeof(object)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableFrom(__reftype(default)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableFrom(__reftype(default)); }); // System.__Canon IsTrue (IsAssignableFrom, KeyValuePair>()); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs index 2880335c05418..d5bb363d8e221 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.IsAssignableTo.cs @@ -169,10 +169,16 @@ public static void TestIsAssignableTo() // null type IsFalse(typeof(int).IsAssignableTo(null)); IsFalse(typeof(object).IsAssignableTo(null)); - ThrowsNRE(() => { _ = null.IsAssignableTo(typeof(int)); }); - ThrowsNRE(() => { _ = null.IsAssignableTo(typeof(object)); }); - ThrowsNRE(() => { _ = null.IsAssignableTo(null); }); - ThrowsNRE(() => { _ = null.IsAssignableTo(null); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableTo(typeof(int)); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableTo(typeof(object)); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableTo(null); }); + ThrowsNRE(() => { _ = ((Type)null).IsAssignableTo(null); }); + IsFalse(typeof(int).IsAssignableTo(__reftype(default))); + IsFalse(typeof(object).IsAssignableTo(__reftype(default))); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableTo(typeof(int)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableTo(typeof(object)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableTo(__reftype(default)); }); + ThrowsNRE(() => { _ = __reftype(default).IsAssignableTo(__reftype(default)); }); // System.__Canon IsTrue (IsAssignableTo, KeyValuePair>()); diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index b9f64f3a560c5..a0c345778e01e 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -93,10 +93,8 @@ public static int Main(string[] args) IsTrue (IsValueTypeRef(ref _varEnum)); // test __reftype - int testInt = 0; - IsTrue (__reftype(__makeref(testInt)).IsValueType); - object testObject = null; - IsFalse(__reftype(__makeref(testObject)).IsValueType); + IsTrue (__reftype(__makeref(_varInt)).IsValueType); + IsFalse(__reftype(__makeref(_varObject)).IsValueType); ThrowsNRE(() => { IsValueType(_varNullableIntNull); }); ThrowsNRE(() => { IsValueType(_varStringNull); }); @@ -148,10 +146,8 @@ public static int Main(string[] args) AreSame(Type.GetTypeCode(typeof(SimpleStruct)), TypeCode.Object); AreSame(Type.GetTypeCode(typeof(SimpleEnum)), TypeCode.Int32); - int testInt = 0; - AreSame(Type.GetTypeCode(__reftype(__makeref(testInt))), TypeCode.Int32); - object testObject = null; - AreSame(Type.GetTypeCode(__reftype(__makeref(testObject))), TypeCode.Object); + AreSame(Type.GetTypeCode(__reftype(__makeref(_varInt))), TypeCode.Int32); + AreSame(Type.GetTypeCode(__reftype(__makeref(_varObject))), TypeCode.Object); return 100 + _errors; } From 4f99338dc08ac417dea1c48071ec88e93a752019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sun, 10 Jul 2022 22:19:13 +0200 Subject: [PATCH 22/52] Move the IsEnum check --- .../System.Private.CoreLib/src/System/RuntimeType.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index fef7d8267d831..67bdc250df545 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -142,6 +142,9 @@ public override Array GetEnumValues() [MethodImpl(MethodImplOptions.AggressiveInlining)] public override Type GetEnumUnderlyingType() { + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + if (RuntimeHelpers.IsKnownConstant(this)) { switch (Type.GetTypeCode(this)) @@ -161,9 +164,6 @@ public override Type GetEnumUnderlyingType() } } - if (!IsEnum) - throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); - return Enum.InternalGetUnderlyingType(this); } From d2957e79814da3ece5b431a8bd243a4b1d25445e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sun, 10 Jul 2022 22:23:20 +0200 Subject: [PATCH 23/52] Update EnumTests.cs --- src/libraries/System.Runtime/tests/System/EnumTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime/tests/System/EnumTests.cs b/src/libraries/System.Runtime/tests/System/EnumTests.cs index a764555bd93fd..122129acada8f 100644 --- a/src/libraries/System.Runtime/tests/System/EnumTests.cs +++ b/src/libraries/System.Runtime/tests/System/EnumTests.cs @@ -1307,6 +1307,7 @@ public static void GetUnderlyingType_Invalid() { AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(null)); // Enum type is null AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(typeof(Enum))); // Enum type is simply an enum + AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(typeof(int))); // Enum type is a primtive type } [Fact] From 791476b037ef795b1596319aa74a3d8563deb6d2 Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 13 Jul 2022 15:24:36 +0200 Subject: [PATCH 24/52] Apply suggestions, add more tests --- src/coreclr/jit/gentree.cpp | 4 + src/coreclr/jit/importer.cpp | 129 ++++++++++-------- .../IsKnownConstant/EnumGetUnderlyingType.cs | 102 ++++++++++++++ .../EnumGetUnderlyingType.csproj | 12 ++ .../EnumGetUnderlyingTypeEnums.il | 42 ++++++ .../EnumGetUnderlyingTypeEnums.ilproj | 11 ++ 6 files changed, 240 insertions(+), 60 deletions(-) create mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs create mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj create mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il create mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index fc8117f0d5798..4c939ab613a07 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17985,6 +17985,10 @@ bool Compiler::gtIsTypeof(GenTree* tree, CORINFO_CLASS_HANDLE* handle) } } } + if (handle != nullptr) + { + *handle = NO_CLASS_HANDLE; + } return false; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index d1e94908e1873..aa80db14c872e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4175,66 +4175,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_GetTypeCode: { - CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; - if (gtIsTypeof(impStackTop().val, &hClass)) - { - int typeCode = -1; - switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) - { - case CORINFO_TYPE_BOOL: - typeCode = 3; - break; - case CORINFO_TYPE_CHAR: - typeCode = 4; - break; - case CORINFO_TYPE_BYTE: - typeCode = 5; - break; - case CORINFO_TYPE_UBYTE: - typeCode = 6; - break; - case CORINFO_TYPE_SHORT: - typeCode = 7; - break; - case CORINFO_TYPE_USHORT: - typeCode = 8; - break; - case CORINFO_TYPE_INT: - typeCode = 9; - break; - case CORINFO_TYPE_UINT: - typeCode = 10; - break; - case CORINFO_TYPE_LONG: - typeCode = 11; - break; - case CORINFO_TYPE_ULONG: - typeCode = 12; - break; - case CORINFO_TYPE_FLOAT: - typeCode = 13; - break; - case CORINFO_TYPE_DOUBLE: - typeCode = 14; - break; - case CORINFO_TYPE_NATIVEINT: - case CORINFO_TYPE_NATIVEUINT: - case CORINFO_TYPE_PTR: - typeCode = 1; - break; - default: - if (hClass == impGetStringClass()) - { - typeCode = 18; - } - break; - } - if (typeCode != -1) - { - retNode = gtNewIconNode(typeCode); - impPopStack(); - } - } + GenTree* type = impStackTop().val; + + retNode = impTypeGetTypeCode(type); break; } @@ -5441,6 +5384,72 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) return nullptr; } +GenTree* Compiler::impTypeGetTypeCode(GenTree* type) +{ + GenTree* retNode = nullptr; + CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; + if (gtIsTypeof(type, &hClass)) + { + int typeCode = -1; + switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) + { + case CORINFO_TYPE_BOOL: + typeCode = 3; + break; + case CORINFO_TYPE_CHAR: + typeCode = 4; + break; + case CORINFO_TYPE_BYTE: + typeCode = 5; + break; + case CORINFO_TYPE_UBYTE: + typeCode = 6; + break; + case CORINFO_TYPE_SHORT: + typeCode = 7; + break; + case CORINFO_TYPE_USHORT: + typeCode = 8; + break; + case CORINFO_TYPE_INT: + typeCode = 9; + break; + case CORINFO_TYPE_UINT: + typeCode = 10; + break; + case CORINFO_TYPE_LONG: + typeCode = 11; + break; + case CORINFO_TYPE_ULONG: + typeCode = 12; + break; + case CORINFO_TYPE_FLOAT: + typeCode = 13; + break; + case CORINFO_TYPE_DOUBLE: + typeCode = 14; + break; + case CORINFO_TYPE_NATIVEINT: + case CORINFO_TYPE_NATIVEUINT: + case CORINFO_TYPE_PTR: + typeCode = 1; + break; + default: + if (hClass == impGetStringClass()) + { + typeCode = 18; + } + break; + } + if (typeCode != -1) + { + retNode = gtNewIconNode(typeCode); + impPopStack(); + } + } + return retNode; +} + GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs new file mode 100644 index 0000000000000..d583db027fd45 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs @@ -0,0 +1,102 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +public class Program +{ + public static int Main() + { + AssertEquals(typeof(sbyte), Enum.GetUnderlyingType(typeof(SByteEnum))); + AssertEquals(typeof(byte), Enum.GetUnderlyingType(typeof(ByteEnum))); + AssertEquals(typeof(short), Enum.GetUnderlyingType(typeof(ShortEnum))); + AssertEquals(typeof(ushort), Enum.GetUnderlyingType(typeof(UShortEnum))); + AssertEquals(typeof(int), Enum.GetUnderlyingType(typeof(IntEnum))); + AssertEquals(typeof(uint), Enum.GetUnderlyingType(typeof(UIntEnum))); + AssertEquals(typeof(long), Enum.GetUnderlyingType(typeof(LongEnum))); + AssertEquals(typeof(ulong), Enum.GetUnderlyingType(typeof(ULongEnum))); + + AssertEquals(typeof(char), Enum.GetUnderlyingType(typeof(CharEnum))); + AssertEquals(typeof(bool), Enum.GetUnderlyingType(typeof(BoolEnum))); + AssertEquals(typeof(float), Enum.GetUnderlyingType(typeof(FloatEnum))); + AssertEquals(typeof(double), Enum.GetUnderlyingType(typeof(DoubleEnum))); + AssertEquals(typeof(nint), Enum.GetUnderlyingType(typeof(IntPtrEnum))); + AssertEquals(typeof(nuint), Enum.GetUnderlyingType(typeof(UIntPtrEnum))); + + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(int))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(nint))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(Enum))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(object))); + AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(null)); + + AssertEquals(typeof(sbyte), Enum.GetUnderlyingType(NoInline(typeof(SByteEnum)))); + AssertEquals(typeof(byte), Enum.GetUnderlyingType(NoInline(typeof(ByteEnum)))); + AssertEquals(typeof(short), Enum.GetUnderlyingType(NoInline(typeof(ShortEnum)))); + AssertEquals(typeof(ushort), Enum.GetUnderlyingType(NoInline(typeof(UShortEnum)))); + AssertEquals(typeof(int), Enum.GetUnderlyingType(NoInline(typeof(IntEnum)))); + AssertEquals(typeof(uint), Enum.GetUnderlyingType(NoInline(typeof(UIntEnum)))); + AssertEquals(typeof(long), Enum.GetUnderlyingType(NoInline(typeof(LongEnum)))); + AssertEquals(typeof(ulong), Enum.GetUnderlyingType(NoInline(typeof(ULongEnum)))); + + AssertEquals(typeof(char), Enum.GetUnderlyingType(NoInline(typeof(CharEnum)))); + AssertEquals(typeof(bool), Enum.GetUnderlyingType(NoInline(typeof(BoolEnum)))); + AssertEquals(typeof(float), Enum.GetUnderlyingType(NoInline(typeof(FloatEnum)))); + AssertEquals(typeof(double), Enum.GetUnderlyingType(NoInline(typeof(DoubleEnum)))); + AssertEquals(typeof(nint), Enum.GetUnderlyingType(NoInline(typeof(IntPtrEnum)))); + AssertEquals(typeof(nuint), Enum.GetUnderlyingType(NoInline(typeof(UIntPtrEnum)))); + + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(int)))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(nint)))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(Enum)))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(object)))); + AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(NoInline(null))); + + return 100; + } + + public enum SByteEnum : sbyte {} + public enum ByteEnum : byte {} + public enum ShortEnum : short {} + public enum UShortEnum : ushort {} + public enum IntEnum {} + public enum UIntEnum : uint {} + public enum LongEnum : long {} + public enum ULongEnum : ulong {} + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Type NoInline(Type type) => type; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void AssertEquals(Type expected, Type actual, [CallerLineNumber] int l = 0) + { + if (expected != actual) + throw new InvalidOperationException($"Invalid type, expected {expected.FullName}, got {actual.FullName} at line {l}"); + } + + private static void AssertThrowsArgumentException(Action a, [CallerLineNumber] int l = 0) + { + try + { + a(); + } + catch (ArgumentException) + { + return; + } + throw new InvalidOperationException($"Expected ArgumentException at line {l}"); + } + + private static void AssertThrowsArgumentNullException(Action a, [CallerLineNumber] int l = 0) + { + try + { + a(); + } + catch (ArgumentNullException) + { + return; + } + throw new InvalidOperationException($"Expected ArgumentNullException at line {l}"); + } +} diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj new file mode 100644 index 0000000000000..5d3631a5de7f5 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj @@ -0,0 +1,12 @@ + + + Exe + True + + + + + + + + diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il new file mode 100644 index 0000000000000..cd7a39502a1c2 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Runtime { } + +.assembly EnumGetUnderlyingTypeEnums { } + +.class public auto ansi sealed CharEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname char value__ +} // end of class CharEnum + +.class public auto ansi sealed BoolEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname bool value__ +} // end of class BoolEnum + +.class public auto ansi sealed FloatEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float32 value__ +} // end of class FloatEnum + +.class public auto ansi sealed DoubleEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float64 value__ +} // end of class DoubleEnum + +.class public auto ansi sealed IntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native int value__ +} // end of class IntPtrEnum + +.class public auto ansi sealed UIntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native uint value__ +} // end of class UIntPtrEnum diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj new file mode 100644 index 0000000000000..05fbf28a4e307 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj @@ -0,0 +1,11 @@ + + + Library + true + BuildOnly + false + + + + + From 1f2bf41d362ae0b9e800a543249739ffe5c926e2 Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 13 Jul 2022 15:48:44 +0200 Subject: [PATCH 25/52] Add impTypeGetTypeCode to the header --- src/coreclr/jit/compiler.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index e820e547ae423..b45c642118316 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3661,6 +3661,7 @@ class Compiler void impImportLeave(BasicBlock* block); void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr); GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom); + GenTree* impTypeGetTypeCode(GenTree* type); // Mirrors StringComparison.cs enum StringComparison From d0769b959c5e0483d606b67f7941dd1f85f81a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 13 Jul 2022 16:20:04 +0200 Subject: [PATCH 26/52] Fix formatting --- src/coreclr/jit/importer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index aa80db14c872e..15efc652af962 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -5386,8 +5386,8 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) GenTree* Compiler::impTypeGetTypeCode(GenTree* type) { - GenTree* retNode = nullptr; - CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; + GenTree* retNode = nullptr; + CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; if (gtIsTypeof(type, &hClass)) { int typeCode = -1; From 2a121d51dc62dcaac0e6cc08357d29f1d90f8136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 13 Jul 2022 17:21:59 +0200 Subject: [PATCH 27/52] Update EnumGetUnderlyingTypeEnums.il --- src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il index cd7a39502a1c2..591b5e3baa88a 100644 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -.assembly extern System.Runtime { } +.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } .assembly EnumGetUnderlyingTypeEnums { } From efc9f64a9112e453e75e078b9570c9caf943d0c4 Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 14 Jul 2022 22:11:41 +0200 Subject: [PATCH 28/52] Make the IsActualEnum helper an intrinsic --- .../src/System/RuntimeType.CoreCLR.cs | 1 + src/coreclr/jit/fgbasic.cpp | 1 + src/coreclr/jit/importer.cpp | 9 +++++++++ src/coreclr/jit/namedintrinsiclist.h | 1 + src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 7 +++++++ .../JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs | 7 +++++++ 6 files changed, 26 insertions(+) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index 3ae8e5f385034..15cc6d63bb717 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -3397,6 +3397,7 @@ public override unsafe bool IsEnum // This returns true for actual enum types only. internal unsafe bool IsActualEnum { + [Intrinsic] get { TypeHandle th = GetNativeTypeHandle(); diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 13b277f311607..72a2c1dba7e7c 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1162,6 +1162,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed break; // These are foldable if the first argument is a constant + case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 50c56c7df40a1..98ae5789b8794 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4123,6 +4123,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } + case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: @@ -4140,6 +4141,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { switch (ni) { + case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: { CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); @@ -5838,6 +5840,13 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) result = NI_System_RuntimeTypeHandle_GetValueInternal; } } + else if (strcmp(className, "RuntimeType") == 0) + { + if (strcmp(methodName, "get_IsActualEnum") == 0) + { + result = NI_System_RuntimeType_get_IsActualEnum; + } + } else if (strcmp(className, "Type") == 0) { if (strcmp(methodName, "get_IsValueType") == 0) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 51d40d8903a7d..1c2c3483bf5b4 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -60,6 +60,7 @@ enum NamedIntrinsic : unsigned short NI_System_GC_KeepAlive, NI_System_Threading_Thread_get_CurrentThread, NI_System_Threading_Thread_get_ManagedThreadId, + NI_System_RuntimeType_get_IsActualEnum, NI_System_Type_get_IsEnum, NI_System_Type_get_IsValueType, NI_System_Type_get_IsByRefLike, diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index a0c345778e01e..684af4b7d532f 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -119,6 +119,8 @@ public static int Main(string[] args) IsFalse(typeof(SimpleStruct).IsEnum); IsTrue (typeof(SimpleEnum).IsEnum); + IsTrue(typeof(GenericEnumClass<>).GetGenericArguments()[0].IsEnum); + AreSame(Type.GetTypeCode(__reftype(default)), TypeCode.Empty); AreSame(Type.GetTypeCode(null), TypeCode.Empty); AreSame(Type.GetTypeCode(typeof(void*)), TypeCode.Object); @@ -231,6 +233,11 @@ static void AreSame(TypeCode a, TypeCode b, [CallerLineNumber] int line = 0, [Ca } } +public class GenericEnumClass where T : Enum +{ + public T field; +} + public struct GenericStruct { public T field; diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs index d583db027fd45..1c8ce3115d417 100644 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs @@ -52,6 +52,8 @@ public static int Main() AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(object)))); AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(NoInline(null))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(GenericEnumClass<>).GetGenericArguments()[0]))); + return 100; } @@ -64,6 +66,11 @@ public enum UIntEnum : uint {} public enum LongEnum : long {} public enum ULongEnum : ulong {} + public class GenericEnumClass where T : Enum + { + public T field; + } + [MethodImpl(MethodImplOptions.NoInlining)] private static Type NoInline(Type type) => type; From 0b3b868d769a500f6dbeb6963f7eab113b8acb77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 14 Jul 2022 23:40:58 +0200 Subject: [PATCH 29/52] Update EnumGetUnderlyingType.cs --- src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs index 1c8ce3115d417..a34c69c836dc5 100644 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs +++ b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs @@ -52,7 +52,7 @@ public static int Main() AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(object)))); AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(NoInline(null))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(GenericEnumClass<>).GetGenericArguments()[0]))); + AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(GenericEnumClass<>).GetGenericArguments()[0])); return 100; } From 9d8b3c6b91fed3621336b6b66214c296bfd20ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 23 Jul 2022 22:41:00 +0200 Subject: [PATCH 30/52] Fix tests --- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 684af4b7d532f..dfdef1eb36ef9 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -220,6 +220,7 @@ static void ThrowsNRE(Action action, [CallerLineNumber] int line = 0, [CallerFil Console.WriteLine($"{file}:L{line} {exc}"); } Console.WriteLine($"Line {line}: test failed (expected: NullReferenceException)"); + _errors++; } [MethodImpl(MethodImplOptions.NoInlining)] From f2ec8a908628d3e02e439975d1a117ddc4f435c1 Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 1 Sep 2022 18:33:29 +0200 Subject: [PATCH 31/52] Remove GetTypeCode intrinsics --- src/coreclr/jit/compiler.h | 1 - src/coreclr/jit/fgbasic.cpp | 1 - src/coreclr/jit/importer.cpp | 78 ------------- src/coreclr/jit/namedintrinsiclist.h | 1 - .../System.Private.CoreLib/src/System/Enum.cs | 1 - .../src/System/RuntimeType.cs | 20 ---- .../System.Private.CoreLib/src/System/Type.cs | 1 - .../System.Runtime/tests/System/EnumTests.cs | 7 +- src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 40 ------- .../IsKnownConstant/EnumGetUnderlyingType.cs | 109 ------------------ .../EnumGetUnderlyingType.csproj | 12 -- .../EnumGetUnderlyingTypeEnums.il | 42 ------- .../EnumGetUnderlyingTypeEnums.ilproj | 11 -- 13 files changed, 3 insertions(+), 321 deletions(-) delete mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs delete mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj delete mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il delete mode 100644 src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 5e9110be47074..3b50db1055722 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3672,7 +3672,6 @@ class Compiler void impImportLeave(BasicBlock* block); void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr); GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom); - GenTree* impTypeGetTypeCode(GenTree* type); // Mirrors StringComparison.cs enum StringComparison diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 1361e7d9cd85f..41092151be7c2 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1168,7 +1168,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: case NI_System_Type_GetTypeFromHandle: - case NI_System_Type_GetTypeCode: case NI_System_String_get_Length: case NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness: case NI_System_Numerics_BitOperations_PopCount: diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index c9e955a262b22..d811ab16a4a55 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -4170,14 +4170,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } - case NI_System_Type_GetTypeCode: - { - GenTree* type = impStackTop().val; - - retNode = impTypeGetTypeCode(type); - break; - } - case NI_System_Threading_Thread_get_ManagedThreadId: { if (impStackTop().val->OperIs(GT_RET_EXPR)) @@ -5392,72 +5384,6 @@ GenTree* Compiler::impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom) return nullptr; } -GenTree* Compiler::impTypeGetTypeCode(GenTree* type) -{ - GenTree* retNode = nullptr; - CORINFO_CLASS_HANDLE hClass = NO_CLASS_HANDLE; - if (gtIsTypeof(type, &hClass)) - { - int typeCode = -1; - switch (info.compCompHnd->getTypeForPrimitiveValueClass(hClass)) - { - case CORINFO_TYPE_BOOL: - typeCode = 3; - break; - case CORINFO_TYPE_CHAR: - typeCode = 4; - break; - case CORINFO_TYPE_BYTE: - typeCode = 5; - break; - case CORINFO_TYPE_UBYTE: - typeCode = 6; - break; - case CORINFO_TYPE_SHORT: - typeCode = 7; - break; - case CORINFO_TYPE_USHORT: - typeCode = 8; - break; - case CORINFO_TYPE_INT: - typeCode = 9; - break; - case CORINFO_TYPE_UINT: - typeCode = 10; - break; - case CORINFO_TYPE_LONG: - typeCode = 11; - break; - case CORINFO_TYPE_ULONG: - typeCode = 12; - break; - case CORINFO_TYPE_FLOAT: - typeCode = 13; - break; - case CORINFO_TYPE_DOUBLE: - typeCode = 14; - break; - case CORINFO_TYPE_NATIVEINT: - case CORINFO_TYPE_NATIVEUINT: - case CORINFO_TYPE_PTR: - typeCode = 1; - break; - default: - if (hClass == impGetStringClass()) - { - typeCode = 18; - } - break; - } - if (typeCode != -1) - { - retNode = gtNewIconNode(typeCode); - impPopStack(); - } - } - return retNode; -} - GenTree* Compiler::impMathIntrinsic(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, var_types callType, @@ -5883,10 +5809,6 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_GetTypeFromHandle; } - else if (strcmp(methodName, "GetTypeCode") == 0) - { - result = NI_System_Type_GetTypeCode; - } else if (strcmp(methodName, "get_IsEnum") == 0) { result = NI_System_Type_get_IsEnum; diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 1c2c3483bf5b4..a384375347d70 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -69,7 +69,6 @@ enum NamedIntrinsic : unsigned short NI_System_Type_op_Equality, NI_System_Type_op_Inequality, NI_System_Type_GetTypeFromHandle, - NI_System_Type_GetTypeCode, NI_System_Array_Clone, NI_System_Array_GetLength, NI_System_Array_GetLowerBound, diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 0f577f8885d3d..cd4535867b033 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -304,7 +304,6 @@ internal static string[] InternalGetNames(RuntimeType enumType) => // Get all of the names GetEnumInfo(enumType, true).Names; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Type GetUnderlyingType(Type enumType) { ArgumentNullException.ThrowIfNull(enumType); diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index f49584babffc5..81d6f994da54f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -240,31 +240,11 @@ public override Array GetEnumValuesAsUnderlyingType() } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public override Type GetEnumUnderlyingType() { if (!IsActualEnum) throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); - if (RuntimeHelpers.IsKnownConstant(this)) - { - switch (Type.GetTypeCode(this)) - { - case TypeCode.Boolean: return typeof(bool); - case TypeCode.Char: return typeof(char); - case TypeCode.SByte: return typeof(sbyte); - case TypeCode.Byte: return typeof(byte); - case TypeCode.Int16: return typeof(short); - case TypeCode.UInt16: return typeof(ushort); - case TypeCode.Int32: return typeof(int); - case TypeCode.UInt32: return typeof(uint); - case TypeCode.Int64: return typeof(long); - case TypeCode.UInt64: return typeof(ulong); - case TypeCode.Single: return typeof(float); - case TypeCode.Double: return typeof(double); - } - } - return Enum.InternalGetUnderlyingType(this); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 6f84777cb1f73..10a7b9303f84e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -438,7 +438,6 @@ public static Type[] GetTypeArray(object[] args) return cls; } - [Intrinsic] public static TypeCode GetTypeCode(Type? type) { return type?.GetTypeCodeImpl() ?? TypeCode.Empty; diff --git a/src/libraries/System.Runtime/tests/System/EnumTests.cs b/src/libraries/System.Runtime/tests/System/EnumTests.cs index 619fe76c38a17..a4cbc4a52ac17 100644 --- a/src/libraries/System.Runtime/tests/System/EnumTests.cs +++ b/src/libraries/System.Runtime/tests/System/EnumTests.cs @@ -464,7 +464,7 @@ public static IEnumerable GetName_CharEnum_TestData() yield return new object[] { (char)2, "Value2" }; yield return new object[] { (char)4, null }; } - + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [MemberData(nameof(GetName_CharEnum_TestData))] public void GetName_InvokeCharEnum_ReturnsExpected(object value, string expected) @@ -479,7 +479,7 @@ public static IEnumerable GetName_BoolEnum_TestData() yield return new object[] { true, "Value1" }; yield return new object[] { false, "Value2" }; } - + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsReflectionEmitSupported))] [MemberData(nameof(GetName_BoolEnum_TestData))] public void GetName_InvokeBoolEnum_ReturnsExpected(object value, string expected) @@ -1307,7 +1307,6 @@ public static void GetUnderlyingType_Invalid() { AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(null)); // Enum type is null AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(typeof(Enum))); // Enum type is simply an enum - AssertExtensions.Throws("enumType", () => Enum.GetUnderlyingType(typeof(int))); // Enum type is a primtive type } [Fact] @@ -1444,7 +1443,7 @@ public static void GetNames_NullEnumType_ThrowsArgumentNullException() { AssertExtensions.Throws("enumType", () => Enum.GetNames(null)); } - + [Theory] [InlineData(typeof(object))] [InlineData(typeof(int))] diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index dfdef1eb36ef9..7b8d9fa6623a3 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -121,36 +121,6 @@ public static int Main(string[] args) IsTrue(typeof(GenericEnumClass<>).GetGenericArguments()[0].IsEnum); - AreSame(Type.GetTypeCode(__reftype(default)), TypeCode.Empty); - AreSame(Type.GetTypeCode(null), TypeCode.Empty); - AreSame(Type.GetTypeCode(typeof(void*)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(nint)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(nuint)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(IntPtr)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(UIntPtr)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); - AreSame(Type.GetTypeCode(typeof(char)), TypeCode.Char); - AreSame(Type.GetTypeCode(typeof(sbyte)), TypeCode.SByte); - AreSame(Type.GetTypeCode(typeof(byte)), TypeCode.Byte); - AreSame(Type.GetTypeCode(typeof(short)), TypeCode.Int16); - AreSame(Type.GetTypeCode(typeof(ushort)), TypeCode.UInt16); - AreSame(Type.GetTypeCode(typeof(int)), TypeCode.Int32); - AreSame(Type.GetTypeCode(typeof(uint)), TypeCode.UInt32); - AreSame(Type.GetTypeCode(typeof(long)), TypeCode.Int64); - AreSame(Type.GetTypeCode(typeof(ulong)), TypeCode.UInt64); - AreSame(Type.GetTypeCode(typeof(float)), TypeCode.Single); - AreSame(Type.GetTypeCode(typeof(double)), TypeCode.Double); - AreSame(Type.GetTypeCode(typeof(decimal)), TypeCode.Decimal); - AreSame(Type.GetTypeCode(typeof(string)), TypeCode.String); - AreSame(Type.GetTypeCode(typeof(object)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(DateTime)), TypeCode.DateTime); - AreSame(Type.GetTypeCode(typeof(GenericStruct)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(SimpleStruct)), TypeCode.Object); - AreSame(Type.GetTypeCode(typeof(SimpleEnum)), TypeCode.Int32); - - AreSame(Type.GetTypeCode(__reftype(__makeref(_varInt))), TypeCode.Int32); - AreSame(Type.GetTypeCode(__reftype(__makeref(_varObject))), TypeCode.Object); - return 100 + _errors; } @@ -222,16 +192,6 @@ static void ThrowsNRE(Action action, [CallerLineNumber] int line = 0, [CallerFil Console.WriteLine($"Line {line}: test failed (expected: NullReferenceException)"); _errors++; } - - [MethodImpl(MethodImplOptions.NoInlining)] - static void AreSame(TypeCode a, TypeCode b, [CallerLineNumber] int line = 0, [CallerFilePath] string file = "") - { - if (a != b) - { - Console.WriteLine($"{file}:L{line} test failed (not equal)."); - _errors++; - } - } } public class GenericEnumClass where T : Enum diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs deleted file mode 100644 index a34c69c836dc5..0000000000000 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.CompilerServices; - -public class Program -{ - public static int Main() - { - AssertEquals(typeof(sbyte), Enum.GetUnderlyingType(typeof(SByteEnum))); - AssertEquals(typeof(byte), Enum.GetUnderlyingType(typeof(ByteEnum))); - AssertEquals(typeof(short), Enum.GetUnderlyingType(typeof(ShortEnum))); - AssertEquals(typeof(ushort), Enum.GetUnderlyingType(typeof(UShortEnum))); - AssertEquals(typeof(int), Enum.GetUnderlyingType(typeof(IntEnum))); - AssertEquals(typeof(uint), Enum.GetUnderlyingType(typeof(UIntEnum))); - AssertEquals(typeof(long), Enum.GetUnderlyingType(typeof(LongEnum))); - AssertEquals(typeof(ulong), Enum.GetUnderlyingType(typeof(ULongEnum))); - - AssertEquals(typeof(char), Enum.GetUnderlyingType(typeof(CharEnum))); - AssertEquals(typeof(bool), Enum.GetUnderlyingType(typeof(BoolEnum))); - AssertEquals(typeof(float), Enum.GetUnderlyingType(typeof(FloatEnum))); - AssertEquals(typeof(double), Enum.GetUnderlyingType(typeof(DoubleEnum))); - AssertEquals(typeof(nint), Enum.GetUnderlyingType(typeof(IntPtrEnum))); - AssertEquals(typeof(nuint), Enum.GetUnderlyingType(typeof(UIntPtrEnum))); - - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(int))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(nint))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(Enum))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(object))); - AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(null)); - - AssertEquals(typeof(sbyte), Enum.GetUnderlyingType(NoInline(typeof(SByteEnum)))); - AssertEquals(typeof(byte), Enum.GetUnderlyingType(NoInline(typeof(ByteEnum)))); - AssertEquals(typeof(short), Enum.GetUnderlyingType(NoInline(typeof(ShortEnum)))); - AssertEquals(typeof(ushort), Enum.GetUnderlyingType(NoInline(typeof(UShortEnum)))); - AssertEquals(typeof(int), Enum.GetUnderlyingType(NoInline(typeof(IntEnum)))); - AssertEquals(typeof(uint), Enum.GetUnderlyingType(NoInline(typeof(UIntEnum)))); - AssertEquals(typeof(long), Enum.GetUnderlyingType(NoInline(typeof(LongEnum)))); - AssertEquals(typeof(ulong), Enum.GetUnderlyingType(NoInline(typeof(ULongEnum)))); - - AssertEquals(typeof(char), Enum.GetUnderlyingType(NoInline(typeof(CharEnum)))); - AssertEquals(typeof(bool), Enum.GetUnderlyingType(NoInline(typeof(BoolEnum)))); - AssertEquals(typeof(float), Enum.GetUnderlyingType(NoInline(typeof(FloatEnum)))); - AssertEquals(typeof(double), Enum.GetUnderlyingType(NoInline(typeof(DoubleEnum)))); - AssertEquals(typeof(nint), Enum.GetUnderlyingType(NoInline(typeof(IntPtrEnum)))); - AssertEquals(typeof(nuint), Enum.GetUnderlyingType(NoInline(typeof(UIntPtrEnum)))); - - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(int)))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(nint)))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(Enum)))); - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(NoInline(typeof(object)))); - AssertThrowsArgumentNullException(() => Enum.GetUnderlyingType(NoInline(null))); - - AssertThrowsArgumentException(() => Enum.GetUnderlyingType(typeof(GenericEnumClass<>).GetGenericArguments()[0])); - - return 100; - } - - public enum SByteEnum : sbyte {} - public enum ByteEnum : byte {} - public enum ShortEnum : short {} - public enum UShortEnum : ushort {} - public enum IntEnum {} - public enum UIntEnum : uint {} - public enum LongEnum : long {} - public enum ULongEnum : ulong {} - - public class GenericEnumClass where T : Enum - { - public T field; - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static Type NoInline(Type type) => type; - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void AssertEquals(Type expected, Type actual, [CallerLineNumber] int l = 0) - { - if (expected != actual) - throw new InvalidOperationException($"Invalid type, expected {expected.FullName}, got {actual.FullName} at line {l}"); - } - - private static void AssertThrowsArgumentException(Action a, [CallerLineNumber] int l = 0) - { - try - { - a(); - } - catch (ArgumentException) - { - return; - } - throw new InvalidOperationException($"Expected ArgumentException at line {l}"); - } - - private static void AssertThrowsArgumentNullException(Action a, [CallerLineNumber] int l = 0) - { - try - { - a(); - } - catch (ArgumentNullException) - { - return; - } - throw new InvalidOperationException($"Expected ArgumentNullException at line {l}"); - } -} diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj deleted file mode 100644 index 5d3631a5de7f5..0000000000000 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingType.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - Exe - True - - - - - - - - diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il deleted file mode 100644 index 591b5e3baa88a..0000000000000 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.il +++ /dev/null @@ -1,42 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } - -.assembly EnumGetUnderlyingTypeEnums { } - -.class public auto ansi sealed CharEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname char value__ -} // end of class CharEnum - -.class public auto ansi sealed BoolEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname bool value__ -} // end of class BoolEnum - -.class public auto ansi sealed FloatEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname float32 value__ -} // end of class FloatEnum - -.class public auto ansi sealed DoubleEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname float64 value__ -} // end of class DoubleEnum - -.class public auto ansi sealed IntPtrEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname native int value__ -} // end of class IntPtrEnum - -.class public auto ansi sealed UIntPtrEnum - extends [System.Runtime]System.Enum -{ - .field public specialname rtspecialname native uint value__ -} // end of class UIntPtrEnum diff --git a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj b/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj deleted file mode 100644 index 05fbf28a4e307..0000000000000 --- a/src/tests/JIT/opt/IsKnownConstant/EnumGetUnderlyingTypeEnums.ilproj +++ /dev/null @@ -1,11 +0,0 @@ - - - Library - true - BuildOnly - false - - - - - From 1a609d10b504dc7d98947754ebad38f39852603c Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 02:52:19 +0200 Subject: [PATCH 32/52] Create a new JIT-EE api, add GetEnumUnderlyingType back --- src/coreclr/inc/corinfo.h | 14 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 4 + src/coreclr/jit/ICorJitInfo_names_generated.h | 1 + .../jit/ICorJitInfo_wrapper_generated.hpp | 10 + src/coreclr/jit/fgbasic.cpp | 1 + src/coreclr/jit/importercalls.cpp | 45 +++- src/coreclr/jit/namedintrinsiclist.h | 1 + .../tools/Common/JitInterface/CorInfoImpl.cs | 28 +++ .../JitInterface/CorInfoImpl_generated.cs | 210 ++++++++++-------- .../ThunkGenerator/ThunkInput.txt | 1 + .../aot/jitinterface/jitinterface_generated.h | 11 + .../tools/superpmi/superpmi-shared/lwmlist.h | 1 + .../superpmi-shared/methodcontext.cpp | 35 +++ .../superpmi/superpmi-shared/methodcontext.h | 5 + .../superpmi-shim-collector/icorjitinfo.cpp | 13 ++ .../icorjitinfo_generated.cpp | 8 + .../icorjitinfo_generated.cpp | 7 + .../tools/superpmi/superpmi/icorjitinfo.cpp | 11 + src/coreclr/vm/jitinterface.cpp | 49 ++++ .../System.Private.CoreLib/src/System/Enum.cs | 1 + .../System.Private.CoreLib/src/System/Type.cs | 1 + .../TypeIntrinsics.GetEnumUnderlyingType.cs | 111 +++++++++ src/tests/JIT/Intrinsics/TypeIntrinsics.cs | 9 + .../JIT/Intrinsics/TypeIntrinsicsEnums.il | 42 ++++ .../JIT/Intrinsics/TypeIntrinsicsEnums.ilproj | 11 + .../JIT/Intrinsics/TypeIntrinsics_r.csproj | 4 + .../JIT/Intrinsics/TypeIntrinsics_ro.csproj | 4 + 27 files changed, 528 insertions(+), 110 deletions(-) create mode 100644 src/tests/JIT/Intrinsics/TypeIntrinsics.GetEnumUnderlyingType.cs create mode 100644 src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.il create mode 100644 src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.ilproj diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 7a76372184007..3a7eb1de04bb0 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2269,7 +2269,7 @@ class ICorStaticInfo //------------------------------------------------------------------------------ // printObjectDescription: Prints a (possibly truncated) textual UTF8 representation of the given - // object to a preallocated buffer. It's intended to be used only for debug/diagnostic + // object to a preallocated buffer. It's intended to be used only for debug/diagnostic // purposes such as JitDisasm. The buffer is null-terminated (even if truncated). // // Arguments: @@ -2634,6 +2634,16 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE cls2 ) = 0; + // Returns TypeCompareState::Must if cls is known to be an enum. + // For enums with known exact type returns the underlying + // type in underlyingType when the provided pointer is + // non-NULL. + // Returns TypeCompareState::May when a runtime check is required. + virtual TypeCompareState isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType + ) = 0; + // Given a class handle, returns the Parent type. // For COMObjectType, it returns Class Handle of System.Object. // Returns 0 if System.Object is passed in. @@ -2846,7 +2856,7 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */ ) = 0; - // Obtains a list of exact classes for a given base type. Returns 0 if the number of + // Obtains a list of exact classes for a given base type. Returns 0 if the number of // the exact classes is greater than maxExactClasses or if more types might be loaded // in future. virtual int getExactClasses( diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index ec0d19a4c7972..f468bd646ef98 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -352,6 +352,10 @@ bool isMoreSpecificType( CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) override; +TypeCompareState isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) override; + CORINFO_CLASS_HANDLE getParentType( CORINFO_CLASS_HANDLE cls) override; diff --git a/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/coreclr/jit/ICorJitInfo_names_generated.h index ed9a2be8c8d72..e132f89c9b0fa 100644 --- a/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -88,6 +88,7 @@ DEF_CLR_API(compareTypesForCast) DEF_CLR_API(compareTypesForEquality) DEF_CLR_API(mergeClasses) DEF_CLR_API(isMoreSpecificType) +DEF_CLR_API(isEnum) DEF_CLR_API(getParentType) DEF_CLR_API(getChildType) DEF_CLR_API(satisfiesClassConstraints) diff --git a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index 38179829a21ae..f9f6dd2da4481 100644 --- a/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -830,6 +830,16 @@ bool WrapICorJitInfo::isMoreSpecificType( return temp; } +TypeCompareState WrapICorJitInfo::isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) +{ + API_ENTER(isEnum); + TypeCompareState temp = wrapHnd->isEnum(cls, underlyingType); + API_LEAVE(isEnum); + return temp; +} + CORINFO_CLASS_HANDLE WrapICorJitInfo::getParentType( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index fd317121e35a8..176e5aaa570f0 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1165,6 +1165,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed // These are foldable if the first argument is a constant case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: + case NI_System_Type_GetEnumUnderlyingType: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: case NI_System_Type_GetTypeFromHandle: diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 9a72570c631ff..87b0587a41345 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2872,18 +2872,18 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { switch (ni) { - case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: + case NI_System_RuntimeType_get_IsActualEnum: { - CorInfoType infoType = info.compCompHnd->getTypeForPrimitiveValueClass(hClass); - retNode = gtNewIconNode( - (eeIsValueClass(hClass) && - // getTypeForPrimitiveNumericClass seems to not normalize enums - info.compCompHnd->getTypeForPrimitiveNumericClass(hClass) == CORINFO_TYPE_UNDEF && - // we need to check for void here - infoType != CORINFO_TYPE_UNDEF && infoType != CORINFO_TYPE_VOID) - ? 1 - : 0); + CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; + TypeCompareState state = info.compCompHnd->isEnum(hClass, &hClassUnderlying); + if (state == TypeCompareState::May || + (state == TypeCompareState::Must && hClassUnderlying == NO_CLASS_HANDLE)) + { + retNode = NULL; + break; + } + retNode = gtNewIconNode(state == TypeCompareState::Must ? 1 : 0); break; } case NI_System_Type_get_IsValueType: @@ -2896,7 +2896,26 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, default: NO_WAY("Intrinsic not supported in this path."); } - impPopStack(); // drop CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE call + if (retNode != NULL) + { + impPopStack(); // drop CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE call + } + } + break; + } + + case NI_System_Type_GetEnumUnderlyingType: + { + GenTree* type = impStackTop().val; + CORINFO_CLASS_HANDLE hClassEnum = NO_CLASS_HANDLE; + CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; + if (gtIsTypeof(type, &hClassEnum) && + info.compCompHnd->isEnum(hClassEnum, &hClassUnderlying) == TypeCompareState::Must && + hClassUnderlying != NO_CLASS_HANDLE) + { + GenTree* handle = gtNewIconEmbClsHndNode(hClassUnderlying); + retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); + impPopStack(); } break; } @@ -7187,6 +7206,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Type_get_IsEnum; } + else if (strcmp(methodName, "GetEnumUnderlyingType") == 0) + { + result = NI_System_Type_GetEnumUnderlyingType; + } } else if (strcmp(className, "String") == 0) { diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index a384375347d70..87d1884be3624 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -62,6 +62,7 @@ enum NamedIntrinsic : unsigned short NI_System_Threading_Thread_get_ManagedThreadId, NI_System_RuntimeType_get_IsActualEnum, NI_System_Type_get_IsEnum, + NI_System_Type_GetEnumUnderlyingType, NI_System_Type_get_IsValueType, NI_System_Type_get_IsByRefLike, NI_System_Type_IsAssignableFrom, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index a5c324a33fada..dc4cb4460ec01 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2751,6 +2751,34 @@ private bool isMoreSpecificType(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUC return merged == type1; } + private TypeCompareState isEnum(CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) + { + if (underlyingType != null) + { + *underlyingType = null; + } + + if (cls == null) + { + return TypeCompareState.May; + } + + TypeDesc type = HandleToObject(cls); + + if (type.IsEnum) + { + if (underlyingType != null) + { + *underlyingType = ObjectToHandle(type.UnderlyingType); + } + return TypeCompareState.Must; + } + else + { + return TypeCompareState.MustNot; + } + } + private CORINFO_CLASS_STRUCT_* getParentType(CORINFO_CLASS_STRUCT_* cls) { throw new NotImplementedException("getParentType"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 048c6bf00fbe3..45f46d3cadfcb 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1255,6 +1255,21 @@ private static byte _isMoreSpecificType(IntPtr thisHandle, IntPtr* ppException, } } + [UnmanagedCallersOnly] + private static TypeCompareState _isEnum(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) + { + var _this = GetThis(thisHandle); + try + { + return _this.isEnum(cls, underlyingType); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] private static CORINFO_CLASS_STRUCT_* _getParentType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { @@ -2670,7 +2685,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 180); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 181); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2756,102 +2771,103 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; callbacks[82] = (delegate* unmanaged)&_mergeClasses; callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[84] = (delegate* unmanaged)&_getParentType; - callbacks[85] = (delegate* unmanaged)&_getChildType; - callbacks[86] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[87] = (delegate* unmanaged)&_isSDArray; - callbacks[88] = (delegate* unmanaged)&_getArrayRank; - callbacks[89] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[90] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[91] = (delegate* unmanaged)&_canAccessClass; - callbacks[92] = (delegate* unmanaged)&_getFieldName; - callbacks[93] = (delegate* unmanaged)&_getFieldClass; - callbacks[94] = (delegate* unmanaged)&_getFieldType; - callbacks[95] = (delegate* unmanaged)&_getFieldOffset; - callbacks[96] = (delegate* unmanaged)&_getFieldInfo; - callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - callbacks[98] = (delegate* unmanaged)&_getBoundaries; - callbacks[99] = (delegate* unmanaged)&_setBoundaries; - callbacks[100] = (delegate* unmanaged)&_getVars; - callbacks[101] = (delegate* unmanaged)&_setVars; - callbacks[102] = (delegate* unmanaged)&_reportRichMappings; - callbacks[103] = (delegate* unmanaged)&_allocateArray; - callbacks[104] = (delegate* unmanaged)&_freeArray; - callbacks[105] = (delegate* unmanaged)&_getArgNext; - callbacks[106] = (delegate* unmanaged)&_getArgType; - callbacks[107] = (delegate* unmanaged)&_getExactClasses; - callbacks[108] = (delegate* unmanaged)&_getArgClass; - callbacks[109] = (delegate* unmanaged)&_getHFAType; - callbacks[110] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[111] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[112] = (delegate* unmanaged)&_FilterException; - callbacks[113] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[115] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[116] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[117] = (delegate* unmanaged)&_getEEInfo; - callbacks[118] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[119] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[120] = (delegate* unmanaged)&_getMethodName; - callbacks[121] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[122] = (delegate* unmanaged)&_getMethodHash; - callbacks[123] = (delegate* unmanaged)&_findNameOfToken; - callbacks[124] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[125] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[126] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[127] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[128] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[129] = (delegate* unmanaged)&_getHelperFtn; - callbacks[130] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[131] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[132] = (delegate* unmanaged)&_getMethodSync; - callbacks[133] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[134] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[135] = (delegate* unmanaged)&_embedClassHandle; - callbacks[136] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[137] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[138] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[139] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[140] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[141] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[142] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[143] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[144] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[145] = (delegate* unmanaged)&_getCallInfo; - callbacks[146] = (delegate* unmanaged)&_canAccessFamily; - callbacks[147] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[148] = (delegate* unmanaged)&_getClassDomainID; - callbacks[149] = (delegate* unmanaged)&_getFieldAddress; - callbacks[150] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; - callbacks[151] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[152] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[153] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[154] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[155] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[156] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[157] = (delegate* unmanaged)&_addActiveDependency; - callbacks[158] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[159] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[160] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[161] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[162] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[163] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[164] = (delegate* unmanaged)&_allocMem; - callbacks[165] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[166] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[167] = (delegate* unmanaged)&_allocGCInfo; - callbacks[168] = (delegate* unmanaged)&_setEHcount; - callbacks[169] = (delegate* unmanaged)&_setEHinfo; - callbacks[170] = (delegate* unmanaged)&_logMsg; - callbacks[171] = (delegate* unmanaged)&_doAssert; - callbacks[172] = (delegate* unmanaged)&_reportFatalError; - callbacks[173] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[174] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[175] = (delegate* unmanaged)&_recordCallSite; - callbacks[176] = (delegate* unmanaged)&_recordRelocation; - callbacks[177] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[178] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[179] = (delegate* unmanaged)&_getJitFlags; + callbacks[84] = (delegate* unmanaged)&_isEnum; + callbacks[85] = (delegate* unmanaged)&_getParentType; + callbacks[86] = (delegate* unmanaged)&_getChildType; + callbacks[87] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[88] = (delegate* unmanaged)&_isSDArray; + callbacks[89] = (delegate* unmanaged)&_getArrayRank; + callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[92] = (delegate* unmanaged)&_canAccessClass; + callbacks[93] = (delegate* unmanaged)&_getFieldName; + callbacks[94] = (delegate* unmanaged)&_getFieldClass; + callbacks[95] = (delegate* unmanaged)&_getFieldType; + callbacks[96] = (delegate* unmanaged)&_getFieldOffset; + callbacks[97] = (delegate* unmanaged)&_getFieldInfo; + callbacks[98] = (delegate* unmanaged)&_isFieldStatic; + callbacks[99] = (delegate* unmanaged)&_getBoundaries; + callbacks[100] = (delegate* unmanaged)&_setBoundaries; + callbacks[101] = (delegate* unmanaged)&_getVars; + callbacks[102] = (delegate* unmanaged)&_setVars; + callbacks[103] = (delegate* unmanaged)&_reportRichMappings; + callbacks[104] = (delegate* unmanaged)&_allocateArray; + callbacks[105] = (delegate* unmanaged)&_freeArray; + callbacks[106] = (delegate* unmanaged)&_getArgNext; + callbacks[107] = (delegate* unmanaged)&_getArgType; + callbacks[108] = (delegate* unmanaged)&_getExactClasses; + callbacks[109] = (delegate* unmanaged)&_getArgClass; + callbacks[110] = (delegate* unmanaged)&_getHFAType; + callbacks[111] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[112] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[113] = (delegate* unmanaged)&_FilterException; + callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[116] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[117] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[118] = (delegate* unmanaged)&_getEEInfo; + callbacks[119] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[120] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[121] = (delegate* unmanaged)&_getMethodName; + callbacks[122] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[123] = (delegate* unmanaged)&_getMethodHash; + callbacks[124] = (delegate* unmanaged)&_findNameOfToken; + callbacks[125] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[126] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[127] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[128] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[129] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[130] = (delegate* unmanaged)&_getHelperFtn; + callbacks[131] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[132] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[133] = (delegate* unmanaged)&_getMethodSync; + callbacks[134] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[135] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[136] = (delegate* unmanaged)&_embedClassHandle; + callbacks[137] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[138] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[139] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[140] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[141] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[142] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[146] = (delegate* unmanaged)&_getCallInfo; + callbacks[147] = (delegate* unmanaged)&_canAccessFamily; + callbacks[148] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[149] = (delegate* unmanaged)&_getClassDomainID; + callbacks[150] = (delegate* unmanaged)&_getFieldAddress; + callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[152] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[153] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[154] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[155] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[156] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[157] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[158] = (delegate* unmanaged)&_addActiveDependency; + callbacks[159] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[160] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[161] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[162] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[163] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[164] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[165] = (delegate* unmanaged)&_allocMem; + callbacks[166] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[167] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[168] = (delegate* unmanaged)&_allocGCInfo; + callbacks[169] = (delegate* unmanaged)&_setEHcount; + callbacks[170] = (delegate* unmanaged)&_setEHinfo; + callbacks[171] = (delegate* unmanaged)&_logMsg; + callbacks[172] = (delegate* unmanaged)&_doAssert; + callbacks[173] = (delegate* unmanaged)&_reportFatalError; + callbacks[174] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[175] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[176] = (delegate* unmanaged)&_recordCallSite; + callbacks[177] = (delegate* unmanaged)&_recordRelocation; + callbacks[178] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[179] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[180] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 61f5fa42e2ec0..a8b9870f23e22 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -239,6 +239,7 @@ FUNCTIONS TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) + TypeCompareState isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls) CorInfoType getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet) bool satisfiesClassConstraints(CORINFO_CLASS_HANDLE cls) diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index 563a59c4339ef..b7a355a158fad 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -95,6 +95,7 @@ struct JitInterfaceCallbacks TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); CORINFO_CLASS_HANDLE (* mergeClasses)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); bool (* isMoreSpecificType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); + TypeCompareState (* isEnum)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); CORINFO_CLASS_HANDLE (* getParentType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); CorInfoType (* getChildType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet); bool (* satisfiesClassConstraints)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); @@ -1024,6 +1025,16 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual TypeCompareState isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) +{ + CorInfoExceptionClass* pException = nullptr; + TypeCompareState temp = _callbacks->isEnum(_thisHandle, &pException, cls, underlyingType); + if (pException != nullptr) throw pException; + return temp; +} + virtual CORINFO_CLASS_HANDLE getParentType( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index 2b1eb255951cc..791a7ceccd499 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -158,6 +158,7 @@ LWM(IsValidToken, DLD, DWORD) LWM(IsValueClass, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) LWM(IsMoreSpecificType, DLDL, DWORD) +LWM(IsEnum, DWORDLONG, DLD) LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD) LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue) LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 3afd927f7b416..47bdd811e19ef 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -5909,6 +5909,41 @@ bool MethodContext::repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return value != 0; } +void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType, TypeCompareState result) +{ + if (IsEnum == nullptr) + IsEnum = new LightWeightMap(); + + DWORDLONG key = CastHandle(cls); + + DLD value; + ZeroMemory(&value, sizeof(value)); + if (underlyingType != nullptr) + value.A = CastHandle(*underlyingType); + else + value.A = 0; + value.B = (DWORD)result; + + IsEnum->Add(key, value); + DEBUG_REC(dmpIsEnum(key, value)); +} +void MethodContext::dmpIsEnum(DWORDLONG key, DLD value) +{ + printf("IsEnum key cls-%016llX, value underlyingType-%016llX result-%u", key, value.A, value.B); +} +TypeCompareState MethodContext::repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) +{ + DWORDLONG key = CastHandle(cls); + + AssertMapAndKeyExist(IsEnum, key, ": key %016llX", key); + + DLD value = IsEnum->Get(key); + DEBUG_REP(dmpIsEnum(key, value)); + if (underlyingType != nullptr) + *underlyingType = (CORINFO_CLASS_HANDLE)value.A; + return (TypeCompareState)value.B; +} + void MethodContext::recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result) { if (GetCookieForPInvokeCalliSig == nullptr) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index e28f4ed09f044..2b7da8ac88e6d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -744,6 +744,10 @@ class MethodContext void dmpIsMoreSpecificType(DLDL key, DWORD value); bool repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); + void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType, TypeCompareState result); + void dmpIsEnum(DWORDLONG key, DLD value); + TypeCompareState repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); + void recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result); void dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value); LPVOID repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection); @@ -1149,6 +1153,7 @@ enum mcPackets Packet_GetObjectType = 199, Packet_IsObjectImmutable = 200, Packet_ExpandRawHandleIntrinsic = 201, + Packet_IsEnum = 202, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index cee845252fcfe..7d4d7b8d02556 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -968,6 +968,19 @@ bool interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA return temp; } +// Returns TypeCompareState::Must if cls is known to be an enum. +// For enums with known exact type returns the underlying +// type in underlyingType when the provided pointer is +// non-NULL. +// Returns TypeCompareState::May when a runtime check is required. +TypeCompareState interceptor_ICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) +{ + mc->cr->AddCall("isEnum"); + TypeCompareState temp = original_ICorJitInfo->isEnum(cls, underlyingType); + mc->recIsEnum(cls, underlyingType, temp); + return temp; +} + // Given a class handle, returns the Parent type. // For COMObjectType, it returns Class Handle of System.Object. // Returns 0 if System.Object is passed in. diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index 6769ddb62371e..4980108cce3ba 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -679,6 +679,14 @@ bool interceptor_ICJI::isMoreSpecificType( return original_ICorJitInfo->isMoreSpecificType(cls1, cls2); } +TypeCompareState interceptor_ICJI::isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) +{ + mcs->AddCall("isEnum"); + return original_ICorJitInfo->isEnum(cls, underlyingType); +} + CORINFO_CLASS_HANDLE interceptor_ICJI::getParentType( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index b3f34f8a5cb54..c487680466e84 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -595,6 +595,13 @@ bool interceptor_ICJI::isMoreSpecificType( return original_ICorJitInfo->isMoreSpecificType(cls1, cls2); } +TypeCompareState interceptor_ICJI::isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) +{ + return original_ICorJitInfo->isEnum(cls, underlyingType); +} + CORINFO_CLASS_HANDLE interceptor_ICJI::getParentType( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 92b42376ce04c..c0d12f4e06972 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -819,6 +819,17 @@ bool MyICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE return jitInstance->mc->repIsMoreSpecificType(cls1, cls2); } +// Returns TypeCompareState::Must if cls is known to be an enum. +// For enums with known exact type returns the underlying +// type in underlyingType when the provided pointer is +// non-NULL. +// Returns TypeCompareState::May when a runtime check is required. +TypeCompareState MyICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) +{ + jitInstance->mc->cr->AddCall("isEnum"); + return jitInstance->mc->repIsEnum(cls, underlyingType); +} + // Given a class handle, returns the Parent type. // For COMObjectType, it returns Class Handle of System.Object. // Returns 0 if System.Object is passed in. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c1606c893b98b..7bd522c5eb4c5 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4446,6 +4446,55 @@ bool CEEInfo::isMoreSpecificType( return result; } +/*********************************************************************/ +// Returns TypeCompareState::Must if cls is known to be an enum. +// For enums with known exact type returns the underlying +// type in underlyingType when the provided pointer is +// non-NULL. +// Returns TypeCompareState::May when a runtime check is required. +TypeCompareState CEEInfo::isEnum( + CORINFO_CLASS_HANDLE cls, + CORINFO_CLASS_HANDLE* underlyingType) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + TypeCompareState result = TypeCompareState::May; + + if (underlyingType != NULL) + { + *underlyingType = 0; + } + + JIT_TO_EE_TRANSITION(); + + TypeHandle th(cls); + + if (!th.IsNull() && !th.IsTypeDesc()) + { + if (th.AsMethodTable()->IsEnum()) + { + result = TypeCompareState::Must; + if (underlyingType != NULL) + { + CorElementType elemType = th.AsMethodTable()->GetInternalCorElementType(); + TypeHandle underlyingHandle(CoreLibBinder::GetElementType(elemType)); + *underlyingType = CORINFO_CLASS_HANDLE(underlyingHandle.AsPtr()); + } + } + else + { + result = TypeCompareState::MustNot; + } + } + + EE_TO_JIT_TRANSITION(); + return result; +} + /*********************************************************************/ // Given a class handle, returns the Parent type. // For COMObjectType, it returns Class Handle of System.Object. diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index d35f3a46c46bf..4824d6a33bf45 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -316,6 +316,7 @@ internal static string[] InternalGetNames(RuntimeType enumType) => // Get all of the names GetEnumInfo(enumType).Names; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Type GetUnderlyingType(Type enumType) { ArgumentNullException.ThrowIfNull(enumType); diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 7026a3f36d136..ac0a847992245 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -503,6 +503,7 @@ protected virtual TypeCode GetTypeCodeImpl() [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2085:UnrecognizedReflectionPattern", Justification = "The single instance field on enum types is never trimmed")] + [Intrinsic] public virtual Type GetEnumUnderlyingType() { if (!IsEnum) diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.GetEnumUnderlyingType.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.GetEnumUnderlyingType.cs new file mode 100644 index 0000000000000..93142921f1d73 --- /dev/null +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.GetEnumUnderlyingType.cs @@ -0,0 +1,111 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; + +public class GetEnumUnderlyingType +{ + public static void TestGetEnumUnderlyingType() + { + AssertEquals(typeof(sbyte), typeof(SByteEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(byte), typeof(ByteEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(short), typeof(ShortEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(ushort), typeof(UShortEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(int), typeof(IntEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(uint), typeof(UIntEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(long), typeof(LongEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(ulong), typeof(ULongEnum).GetEnumUnderlyingType()); + + AssertEquals(typeof(char), typeof(CharEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(bool), typeof(BoolEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(float), typeof(FloatEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(double), typeof(DoubleEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(nint), typeof(IntPtrEnum).GetEnumUnderlyingType()); + AssertEquals(typeof(nuint), typeof(UIntPtrEnum).GetEnumUnderlyingType()); + + AssertThrowsArgumentException(() => typeof(int).GetEnumUnderlyingType()); + AssertThrowsArgumentException(() => typeof(nint).GetEnumUnderlyingType()); + AssertThrowsArgumentException(() => typeof(Enum).GetEnumUnderlyingType()); + AssertThrowsArgumentException(() => typeof(object).GetEnumUnderlyingType()); + AssertThrowsNullReferenceException(() => ((Type)null).GetEnumUnderlyingType()); + + AssertEquals(typeof(sbyte), NoInline(typeof(SByteEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(byte), NoInline(typeof(ByteEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(short), NoInline(typeof(ShortEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(ushort), NoInline(typeof(UShortEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(int), NoInline(typeof(IntEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(uint), NoInline(typeof(UIntEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(long), NoInline(typeof(LongEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(ulong), NoInline(typeof(ULongEnum).GetEnumUnderlyingType())); + + AssertEquals(typeof(char), NoInline(typeof(CharEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(bool), NoInline(typeof(BoolEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(float), NoInline(typeof(FloatEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(double), NoInline(typeof(DoubleEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(nint), NoInline(typeof(IntPtrEnum).GetEnumUnderlyingType())); + AssertEquals(typeof(nuint), NoInline(typeof(UIntPtrEnum).GetEnumUnderlyingType())); + + AssertThrowsArgumentException(() => NoInline(typeof(int).GetEnumUnderlyingType())); + AssertThrowsArgumentException(() => NoInline(typeof(nint).GetEnumUnderlyingType())); + AssertThrowsArgumentException(() => NoInline(typeof(Enum).GetEnumUnderlyingType())); + AssertThrowsArgumentException(() => NoInline(typeof(object).GetEnumUnderlyingType())); + AssertThrowsNullReferenceException(() => NoInline(null).GetEnumUnderlyingType()); + + AssertThrowsArgumentException(() => typeof(GenericEnumClass<>).GetGenericArguments()[0].GetEnumUnderlyingType()); + } + + public enum SByteEnum : sbyte {} + public enum ByteEnum : byte {} + public enum ShortEnum : short {} + public enum UShortEnum : ushort {} + public enum IntEnum {} + public enum UIntEnum : uint {} + public enum LongEnum : long {} + public enum ULongEnum : ulong {} + + public class GenericEnumClass where T : Enum + { + public T field; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Type NoInline(Type type) => type; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void AssertEquals(Type expected, Type actual, [CallerLineNumber] int l = 0) + { + if (expected != actual) + throw new InvalidOperationException($"Invalid type, expected {expected.FullName}, got {actual.FullName} at line {l}"); + } + + private static void AssertThrowsArgumentException(Action a, [CallerLineNumber] int l = 0) + { + try + { + a(); + } + catch (ArgumentException) + { + return; + } + throw new InvalidOperationException($"Expected ArgumentException at line {l}"); + } + + private static void AssertThrowsNullReferenceException(Action a, [CallerLineNumber] int l = 0) + { + try + { + a(); + } + catch (NullReferenceException) + { + return; + } + throw new InvalidOperationException($"Expected NullReferenceException at line {l}"); + } +} diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs index 7b8d9fa6623a3..d5a99d7392fd4 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics.cs +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics.cs @@ -105,6 +105,7 @@ public static int Main(string[] args) ThrowsNRE(() => { _ = __reftype(default).IsValueType; }); TestIsAssignableFrom(); + TestIsAssignableTo(); IsFalse(typeof(byte).IsEnum); IsFalse(typeof(int).IsEnum); @@ -118,9 +119,17 @@ public static int Main(string[] args) IsFalse(typeof(GenericStruct).IsEnum); IsFalse(typeof(SimpleStruct).IsEnum); IsTrue (typeof(SimpleEnum).IsEnum); + IsTrue (typeof(CharEnum).IsEnum); + IsTrue (typeof(BoolEnum).IsEnum); + IsTrue (typeof(FloatEnum).IsEnum); + IsTrue (typeof(DoubleEnum).IsEnum); + IsTrue (typeof(IntPtrEnum).IsEnum); + IsTrue (typeof(UIntPtrEnum).IsEnum); IsTrue(typeof(GenericEnumClass<>).GetGenericArguments()[0].IsEnum); + GetEnumUnderlyingType.TestGetEnumUnderlyingType(); + return 100 + _errors; } diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.il b/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.il new file mode 100644 index 0000000000000..36f9f07dd8fdc --- /dev/null +++ b/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.il @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } + +.assembly TypeIntrinsicsEnums { } + +.class public auto ansi sealed CharEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname char value__ +} // end of class CharEnum + +.class public auto ansi sealed BoolEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname bool value__ +} // end of class BoolEnum + +.class public auto ansi sealed FloatEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float32 value__ +} // end of class FloatEnum + +.class public auto ansi sealed DoubleEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float64 value__ +} // end of class DoubleEnum + +.class public auto ansi sealed IntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native int value__ +} // end of class IntPtrEnum + +.class public auto ansi sealed UIntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native uint value__ +} // end of class UIntPtrEnum diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.ilproj b/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.ilproj new file mode 100644 index 0000000000000..05fbf28a4e307 --- /dev/null +++ b/src/tests/JIT/Intrinsics/TypeIntrinsicsEnums.ilproj @@ -0,0 +1,11 @@ + + + Library + true + BuildOnly + false + + + + + diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj b/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj index 9ee21d6e902b9..8a556ce073ac1 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics_r.csproj @@ -4,9 +4,13 @@ None + + + + diff --git a/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj b/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj index d752cddd2a06e..4b1c989578015 100644 --- a/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj +++ b/src/tests/JIT/Intrinsics/TypeIntrinsics_ro.csproj @@ -4,9 +4,13 @@ None True + + + + From a1291e759562c025465c797988901fe4792b436c Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 12:25:19 +0100 Subject: [PATCH 33/52] Fix formatting --- src/coreclr/jit/importercalls.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 87b0587a41345..d30a8d92149cc 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2876,9 +2876,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_RuntimeType_get_IsActualEnum: { CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; - TypeCompareState state = info.compCompHnd->isEnum(hClass, &hClassUnderlying); + TypeCompareState state = info.compCompHnd->isEnum(hClass, &hClassUnderlying); if (state == TypeCompareState::May || - (state == TypeCompareState::Must && hClassUnderlying == NO_CLASS_HANDLE)) + (state == TypeCompareState::Must && hClassUnderlying == NO_CLASS_HANDLE)) { retNode = NULL; break; @@ -2906,7 +2906,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, case NI_System_Type_GetEnumUnderlyingType: { - GenTree* type = impStackTop().val; + GenTree* type = impStackTop().val; CORINFO_CLASS_HANDLE hClassEnum = NO_CLASS_HANDLE; CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; if (gtIsTypeof(type, &hClassEnum) && @@ -2914,7 +2914,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, hClassUnderlying != NO_CLASS_HANDLE) { GenTree* handle = gtNewIconEmbClsHndNode(hClassUnderlying); - retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); + retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); impPopStack(); } break; From 2f17cdadac74132bc6219ac448a56fc8889e45fd Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 14:34:05 +0100 Subject: [PATCH 34/52] Apply suggestions --- src/coreclr/inc/jiteeversionguid.h | 10 +++++----- src/coreclr/jit/fgbasic.cpp | 1 - src/coreclr/jit/importercalls.cpp | 10 +++------- src/coreclr/jit/namedintrinsiclist.h | 1 - src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 8 +++++--- src/coreclr/vm/jitinterface.cpp | 10 ++++++---- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 90c5520ebfed6..eb38d31e152ee 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 2ed4cd12-48ed-4a0e-892e-d24d004a5e4c */ - 0x2ed4cd12, - 0x48ed, - 0x4a0e, - {0x89, 0x2e, 0xd2, 0x4d, 0x00, 0x4a, 0x5e, 0x4c} + constexpr GUID JITEEVersionIdentifier = { /* 592e86d5-88ba-4478-8381-64010f9fa1ba */ + 0x592e86d5, + 0x88ba, + 0x4478, + {0x83, 0x81, 0x64, 0x01, 0x0f, 0x9f, 0xa1, 0xba} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 176e5aaa570f0..27e6e652e1df3 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1163,7 +1163,6 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed break; // These are foldable if the first argument is a constant - case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: case NI_System_Type_GetEnumUnderlyingType: case NI_System_Type_get_IsValueType: diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index d30a8d92149cc..39381acc8c5ab 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2854,7 +2854,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, break; } - case NI_System_RuntimeType_get_IsActualEnum: case NI_System_Type_get_IsEnum: case NI_System_Type_get_IsValueType: case NI_System_Type_get_IsByRefLike: @@ -2873,12 +2872,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, switch (ni) { case NI_System_Type_get_IsEnum: - case NI_System_RuntimeType_get_IsActualEnum: { - CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; - TypeCompareState state = info.compCompHnd->isEnum(hClass, &hClassUnderlying); - if (state == TypeCompareState::May || - (state == TypeCompareState::Must && hClassUnderlying == NO_CLASS_HANDLE)) + TypeCompareState state = info.compCompHnd->isEnum(hClass, nullptr); + if (state == TypeCompareState::May) { retNode = NULL; break; @@ -7169,7 +7165,7 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { if (strcmp(methodName, "get_IsActualEnum") == 0) { - result = NI_System_RuntimeType_get_IsActualEnum; + result = NI_System_Type_get_IsEnum; } } else if (strcmp(className, "Type") == 0) diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 87d1884be3624..37af303c0ab68 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -60,7 +60,6 @@ enum NamedIntrinsic : unsigned short NI_System_GC_KeepAlive, NI_System_Threading_Thread_get_CurrentThread, NI_System_Threading_Thread_get_ManagedThreadId, - NI_System_RuntimeType_get_IsActualEnum, NI_System_Type_get_IsEnum, NI_System_Type_GetEnumUnderlyingType, NI_System_Type_get_IsValueType, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index dc4cb4460ec01..32c21d0990f6a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2753,18 +2753,20 @@ private bool isMoreSpecificType(CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUC private TypeCompareState isEnum(CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) { + Debug.Assert(cls != null); + if (underlyingType != null) { *underlyingType = null; } - if (cls == null) + TypeDesc type = HandleToObject(cls); + + if (type.IsGenericParameter) { return TypeCompareState.May; } - TypeDesc type = HandleToObject(cls); - if (type.IsEnum) { if (underlyingType != null) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7bd522c5eb4c5..499718332bb46 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4469,13 +4469,15 @@ TypeCompareState CEEInfo::isEnum( *underlyingType = 0; } - JIT_TO_EE_TRANSITION(); + JIT_TO_EE_TRANSITION_LEAF(); TypeHandle th(cls); - if (!th.IsNull() && !th.IsTypeDesc()) + _ASSERTE(!th.IsNull()); + + if (!th.IsGenericVariable()) { - if (th.AsMethodTable()->IsEnum()) + if (!th.IsTypeDesc() && th.AsMethodTable()->IsEnum()) { result = TypeCompareState::Must; if (underlyingType != NULL) @@ -4491,7 +4493,7 @@ TypeCompareState CEEInfo::isEnum( } } - EE_TO_JIT_TRANSITION(); + EE_TO_JIT_TRANSITION_LEAF(); return result; } From 3e1e52ee86d4cd75f564d19c61e33ad4d9f6fab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sun, 30 Oct 2022 14:35:04 +0100 Subject: [PATCH 35/52] Revert unnecessary whitespace --- src/coreclr/inc/jiteeversionguid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index eb38d31e152ee..0f6cecfa3ad9b 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,7 +43,7 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED - constexpr GUID JITEEVersionIdentifier = { /* 592e86d5-88ba-4478-8381-64010f9fa1ba */ +constexpr GUID JITEEVersionIdentifier = { /* 592e86d5-88ba-4478-8381-64010f9fa1ba */ 0x592e86d5, 0x88ba, 0x4478, From e519f0c9caa55e08aedd8c86ce8e2a779fd1c178 Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 15:36:10 +0100 Subject: [PATCH 36/52] Optimize GetTypeCode with IsKnownConstant --- .../System.Private.CoreLib/src/System/Type.cs | 22 +++++ .../opt/IsKnownConstant/TypeGetTypeCode.cs | 94 +++++++++++++++++++ .../IsKnownConstant/TypeGetTypeCode.csproj | 12 +++ .../IsKnownConstant/TypeGetTypeCodeEnums.il | 42 +++++++++ .../TypeGetTypeCodeEnums.ilproj | 11 +++ 5 files changed, 181 insertions(+) create mode 100644 src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs create mode 100644 src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.csproj create mode 100644 src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.il create mode 100644 src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.ilproj diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index ac0a847992245..9e96e8edd0cea 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -438,8 +438,30 @@ public static Type[] GetTypeArray(object[] args) return cls; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TypeCode GetTypeCode(Type? type) { + if (RuntimeHelpers.IsKnownConstant(type)) + { + if (type is RuntimeType rt && rt.IsActualEnum) + type = type.GetEnumUnderlyingType(); + if (type == typeof(sbyte)) + return TypeCode.SByte; + else if (type == typeof(byte)) + return TypeCode.Byte; + else if (type == typeof(short)) + return TypeCode.Int16; + else if (type == typeof(ushort)) + return TypeCode.UInt16; + else if (type == typeof(int)) + return TypeCode.Int32; + else if (type == typeof(uint)) + return TypeCode.UInt32; + else if (type == typeof(long)) + return TypeCode.Int64; + else if (type == typeof(ulong)) + return TypeCode.UInt64; + } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; } diff --git a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs new file mode 100644 index 0000000000000..dcaac1ac15263 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs @@ -0,0 +1,94 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +public class Program +{ + public static int Main() + { + AreSame(Type.GetTypeCode(null), TypeCode.Empty); + AreSame(Type.GetTypeCode(typeof(void*)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(nint)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(nuint)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(IntPtr)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(UIntPtr)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(bool)), TypeCode.Boolean); + AreSame(Type.GetTypeCode(typeof(char)), TypeCode.Char); + AreSame(Type.GetTypeCode(typeof(sbyte)), TypeCode.SByte); + AreSame(Type.GetTypeCode(typeof(byte)), TypeCode.Byte); + AreSame(Type.GetTypeCode(typeof(short)), TypeCode.Int16); + AreSame(Type.GetTypeCode(typeof(ushort)), TypeCode.UInt16); + AreSame(Type.GetTypeCode(typeof(int)), TypeCode.Int32); + AreSame(Type.GetTypeCode(typeof(uint)), TypeCode.UInt32); + AreSame(Type.GetTypeCode(typeof(long)), TypeCode.Int64); + AreSame(Type.GetTypeCode(typeof(ulong)), TypeCode.UInt64); + AreSame(Type.GetTypeCode(typeof(float)), TypeCode.Single); + AreSame(Type.GetTypeCode(typeof(double)), TypeCode.Double); + AreSame(Type.GetTypeCode(typeof(decimal)), TypeCode.Decimal); + AreSame(Type.GetTypeCode(typeof(string)), TypeCode.String); + AreSame(Type.GetTypeCode(typeof(object)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(DateTime)), TypeCode.DateTime); + + AreSame(Type.GetTypeCode(typeof(GenericEnumClass<>)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(GenericEnumClass)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(GenericEnumClass<>).GetGenericArguments()[0]), TypeCode.Object); + + AreSame(Type.GetTypeCode(typeof(SByteEnum)), TypeCode.SByte); + AreSame(Type.GetTypeCode(typeof(ByteEnum)), TypeCode.Byte); + AreSame(Type.GetTypeCode(typeof(ShortEnum)), TypeCode.Int16); + AreSame(Type.GetTypeCode(typeof(UShortEnum)), TypeCode.UInt16); + AreSame(Type.GetTypeCode(typeof(IntEnum)), TypeCode.Int32); + AreSame(Type.GetTypeCode(typeof(UIntEnum)), TypeCode.UInt32); + AreSame(Type.GetTypeCode(typeof(LongEnum)), TypeCode.Int64); + AreSame(Type.GetTypeCode(typeof(ULongEnum)), TypeCode.UInt64); + + AreSame(Type.GetTypeCode(typeof(CharEnum)), TypeCode.Char); + AreSame(Type.GetTypeCode(typeof(BoolEnum)), TypeCode.Boolean); + AreSame(Type.GetTypeCode(typeof(FloatEnum)), TypeCode.Single); + AreSame(Type.GetTypeCode(typeof(DoubleEnum)), TypeCode.Double); + AreSame(Type.GetTypeCode(typeof(IntPtrEnum)), TypeCode.Object); + AreSame(Type.GetTypeCode(typeof(UIntPtrEnum)), TypeCode.Object); + + AreSame(Type.GetTypeCode(NoInline(typeof(string))), TypeCode.String); + AreSame(Type.GetTypeCode(NoInline(typeof(int))), TypeCode.Int32); + AreSame(Type.GetTypeCode(NoInline(typeof(IntEnum))), TypeCode.Int32); + AreSame(Type.GetTypeCode(NoInline(typeof(CharEnum))), TypeCode.Char); + AreSame(Type.GetTypeCode(NoInline(typeof(IntPtrEnum))), TypeCode.Object); + + AreSame(Type.GetTypeCode(__reftype(__makeref(_varInt))), TypeCode.Int32); + AreSame(Type.GetTypeCode(__reftype(__makeref(_varObject))), TypeCode.Object); + + return 100; + } + + private static int _varInt = 42; + private static object _varObject = new object(); + + public enum SByteEnum : sbyte {} + public enum ByteEnum : byte {} + public enum ShortEnum : short {} + public enum UShortEnum : ushort {} + public enum IntEnum {} + public enum UIntEnum : uint {} + public enum LongEnum : long {} + public enum ULongEnum : ulong {} + + public class GenericEnumClass where T : Enum + { + public T field; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Type NoInline(Type type) => type; + + [MethodImpl(MethodImplOptions.NoInlining)] + static void AreSame(TypeCode a, TypeCode b, [CallerLineNumber] int line = 0) + { + if (a != b) + { + throw new InvalidOperationException($"Invalid TypeCode, expected {b}, got {a} at line {l}"); + } + } +} diff --git a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.csproj b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.csproj new file mode 100644 index 0000000000000..5d3631a5de7f5 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.csproj @@ -0,0 +1,12 @@ + + + Exe + True + + + + + + + + diff --git a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.il b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.il new file mode 100644 index 0000000000000..6a46fa0efec69 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.il @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) } + +.assembly TypeGetTypeCodeEnums { } + +.class public auto ansi sealed CharEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname char value__ +} // end of class CharEnum + +.class public auto ansi sealed BoolEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname bool value__ +} // end of class BoolEnum + +.class public auto ansi sealed FloatEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float32 value__ +} // end of class FloatEnum + +.class public auto ansi sealed DoubleEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname float64 value__ +} // end of class DoubleEnum + +.class public auto ansi sealed IntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native int value__ +} // end of class IntPtrEnum + +.class public auto ansi sealed UIntPtrEnum + extends [System.Runtime]System.Enum +{ + .field public specialname rtspecialname native uint value__ +} // end of class UIntPtrEnum diff --git a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.ilproj b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.ilproj new file mode 100644 index 0000000000000..05fbf28a4e307 --- /dev/null +++ b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCodeEnums.ilproj @@ -0,0 +1,11 @@ + + + Library + true + BuildOnly + false + + + + + From 6d5e30872e0dfcbbd4e2351fe2bdc488bd2ec858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sun, 30 Oct 2022 16:39:06 +0100 Subject: [PATCH 37/52] Fix typo --- src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs index dcaac1ac15263..d27b6630120d4 100644 --- a/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs +++ b/src/tests/JIT/opt/IsKnownConstant/TypeGetTypeCode.cs @@ -88,7 +88,7 @@ static void AreSame(TypeCode a, TypeCode b, [CallerLineNumber] int line = 0) { if (a != b) { - throw new InvalidOperationException($"Invalid TypeCode, expected {b}, got {a} at line {l}"); + throw new InvalidOperationException($"Invalid TypeCode, expected {b}, got {a} at line {line}"); } } } From 9c70c8f52bd885942807b194ad1701ce85407b2e Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 21:11:45 +0100 Subject: [PATCH 38/52] Change the code to make the inliner happy --- .../System.Private.CoreLib/src/System/Type.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 9e96e8edd0cea..b5b7cf5bb573d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -443,23 +443,24 @@ public static TypeCode GetTypeCode(Type? type) { if (RuntimeHelpers.IsKnownConstant(type)) { - if (type is RuntimeType rt && rt.IsActualEnum) - type = type.GetEnumUnderlyingType(); - if (type == typeof(sbyte)) + Type? underlyingType = type; + if (type is RuntimeType && ((RuntimeType)type).IsActualEnum) + underlyingType = type.GetEnumUnderlyingType(); + if (underlyingType == typeof(sbyte)) return TypeCode.SByte; - else if (type == typeof(byte)) + else if (underlyingType == typeof(byte)) return TypeCode.Byte; - else if (type == typeof(short)) + else if (underlyingType == typeof(short)) return TypeCode.Int16; - else if (type == typeof(ushort)) + else if (underlyingType == typeof(ushort)) return TypeCode.UInt16; - else if (type == typeof(int)) + else if (underlyingType == typeof(int)) return TypeCode.Int32; - else if (type == typeof(uint)) + else if (underlyingType == typeof(uint)) return TypeCode.UInt32; - else if (type == typeof(long)) + else if (underlyingType == typeof(long)) return TypeCode.Int64; - else if (type == typeof(ulong)) + else if (underlyingType == typeof(ulong)) return TypeCode.UInt64; } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; From 40a349aa6156a66d5eda1512f588a639ae55a421 Mon Sep 17 00:00:00 2001 From: petris Date: Sun, 30 Oct 2022 23:25:43 +0100 Subject: [PATCH 39/52] Handle all types in GetTypeCode --- .../System.Private.CoreLib/src/System/Type.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index b5b7cf5bb573d..dcac33c95431b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -446,7 +446,9 @@ public static TypeCode GetTypeCode(Type? type) Type? underlyingType = type; if (type is RuntimeType && ((RuntimeType)type).IsActualEnum) underlyingType = type.GetEnumUnderlyingType(); - if (underlyingType == typeof(sbyte)) + if (underlyingType == null) + return TypeCode.Empty; + else if (underlyingType == typeof(sbyte)) return TypeCode.SByte; else if (underlyingType == typeof(byte)) return TypeCode.Byte; @@ -462,6 +464,24 @@ public static TypeCode GetTypeCode(Type? type) return TypeCode.Int64; else if (underlyingType == typeof(ulong)) return TypeCode.UInt64; + else if (underlyingType == typeof(bool)) + return TypeCode.Boolean; + else if (underlyingType == typeof(char)) + return TypeCode.Char; + else if (underlyingType == typeof(float)) + return TypeCode.Single; + else if (underlyingType == typeof(double)) + return TypeCode.Double; + else if (underlyingType == typeof(decimal)) + return TypeCode.Decimal; + else if (underlyingType == typeof(DateTime)) + return TypeCode.DateTime; + else if (underlyingType == typeof(string)) + return TypeCode.String; + else if (underlyingType == typeof(DBNull)) + return TypeCode.DBNull; + else + return TypeCode.Object; } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; } From 846e57cdebb761d607217b9e61fce5336722218a Mon Sep 17 00:00:00 2001 From: petris Date: Mon, 31 Oct 2022 11:48:49 +0100 Subject: [PATCH 40/52] Check for custom types --- src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs | 1 + src/libraries/System.Private.CoreLib/src/System/Type.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index d4b45f21bc9d7..edd3c6a7cc53a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -268,6 +268,7 @@ protected override TypeCode GetTypeCodeImpl() return typeCode; CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this); + // keep in sync with Type.cs switch (corElementType) { case CorElementType.ELEMENT_TYPE_BOOLEAN: diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index dcac33c95431b..e176d7f84f141 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -443,6 +443,7 @@ public static TypeCode GetTypeCode(Type? type) { if (RuntimeHelpers.IsKnownConstant(type)) { + // keep in sync with RuntimeType.cs Type? underlyingType = type; if (type is RuntimeType && ((RuntimeType)type).IsActualEnum) underlyingType = type.GetEnumUnderlyingType(); @@ -480,7 +481,7 @@ public static TypeCode GetTypeCode(Type? type) return TypeCode.String; else if (underlyingType == typeof(DBNull)) return TypeCode.DBNull; - else + else if (underlyingType.GetType() == typeof(RuntimeType)) return TypeCode.Object; } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; From 159f1478088d200c322932db184d3dce6f96ae0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Mon, 31 Oct 2022 17:20:41 +0100 Subject: [PATCH 41/52] Apply suggestions from code review Co-authored-by: Andy Ayers --- src/coreclr/jit/importercalls.cpp | 6 +++--- .../superpmi/superpmi-shim-collector/icorjitinfo.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 39381acc8c5ab..31c5f04ee9199 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2905,9 +2905,9 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTree* type = impStackTop().val; CORINFO_CLASS_HANDLE hClassEnum = NO_CLASS_HANDLE; CORINFO_CLASS_HANDLE hClassUnderlying = NO_CLASS_HANDLE; - if (gtIsTypeof(type, &hClassEnum) && - info.compCompHnd->isEnum(hClassEnum, &hClassUnderlying) == TypeCompareState::Must && - hClassUnderlying != NO_CLASS_HANDLE) + if (gtIsTypeof(type, &hClassEnum) && (hClassEnum != NO_CLASS_HANDLE) && + (info.compCompHnd->isEnum(hClassEnum, &hClassUnderlying) == TypeCompareState::Must) && + (hClassUnderlying != NO_CLASS_HANDLE)) { GenTree* handle = gtNewIconEmbClsHndNode(hClassUnderlying); retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 7d4d7b8d02556..20b7d7b6138e3 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -976,8 +976,13 @@ bool interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA TypeCompareState interceptor_ICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) { mc->cr->AddCall("isEnum"); - TypeCompareState temp = original_ICorJitInfo->isEnum(cls, underlyingType); - mc->recIsEnum(cls, underlyingType, temp); + CORINFO_CLASS_HANDLE tempUnderlyingType = NO_CLASS_HANDLE; + TypeCompareState temp = original_ICorJitInfo->isEnum(cls, &tempUnderlyingType); + mc->recIsEnum(cls, tempUnderlyingType, temp); + if (underlyingType != nullptr) + { + *underlyingType = tempUnderlyingType; + } return temp; } From c0d9deaad9e4c4ce78ce12fbda44539771636695 Mon Sep 17 00:00:00 2001 From: petris Date: Mon, 31 Oct 2022 19:27:43 +0100 Subject: [PATCH 42/52] Fix build, do suggested changes --- src/coreclr/jit/importercalls.cpp | 4 +- .../superpmi-shared/methodcontext.cpp | 2 +- .../superpmi-shim-collector/icorjitinfo.cpp | 6 +- src/coreclr/vm/jitinterface.cpp | 6 +- .../Concurrent/ConcurrentDictionary.cs | 89 +++++++-------- .../Collections/Generic/EqualityComparer.cs | 2 +- .../src/System/RuntimeType.cs | 105 ++++++++---------- .../System.Private.CoreLib/src/System/Type.cs | 43 +------ .../Converters/Value/EnumConverter.cs | 20 ++-- 9 files changed, 103 insertions(+), 174 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 31c5f04ee9199..60e729451692b 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2876,7 +2876,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, TypeCompareState state = info.compCompHnd->isEnum(hClass, nullptr); if (state == TypeCompareState::May) { - retNode = NULL; + retNode = nullptr; break; } retNode = gtNewIconNode(state == TypeCompareState::Must ? 1 : 0); @@ -2892,7 +2892,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, default: NO_WAY("Intrinsic not supported in this path."); } - if (retNode != NULL) + if (retNode != nullptr) { impPopStack(); // drop CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE call } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 47bdd811e19ef..1fce04a032251 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -5921,7 +5921,7 @@ void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* un if (underlyingType != nullptr) value.A = CastHandle(*underlyingType); else - value.A = 0; + value.A = nullptr; value.B = (DWORD)result; IsEnum->Add(key, value); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 20b7d7b6138e3..927edab0e676c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -976,12 +976,12 @@ bool interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLA TypeCompareState interceptor_ICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType) { mc->cr->AddCall("isEnum"); - CORINFO_CLASS_HANDLE tempUnderlyingType = NO_CLASS_HANDLE; - TypeCompareState temp = original_ICorJitInfo->isEnum(cls, &tempUnderlyingType); + CORINFO_CLASS_HANDLE tempUnderlyingType = nullptr; + TypeCompareState temp = original_ICorJitInfo->isEnum(cls, &tempUnderlyingType); mc->recIsEnum(cls, tempUnderlyingType, temp); if (underlyingType != nullptr) { - *underlyingType = tempUnderlyingType; + *underlyingType = tempUnderlyingType; } return temp; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 499718332bb46..ac4701738b270 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4464,9 +4464,9 @@ TypeCompareState CEEInfo::isEnum( TypeCompareState result = TypeCompareState::May; - if (underlyingType != NULL) + if (underlyingType != nullptr) { - *underlyingType = 0; + *underlyingType = nullptr; } JIT_TO_EE_TRANSITION_LEAF(); @@ -4480,7 +4480,7 @@ TypeCompareState CEEInfo::isEnum( if (!th.IsTypeDesc() && th.AsMethodTable()->IsEnum()) { result = TypeCompareState::Must; - if (underlyingType != NULL) + if (underlyingType != nullptr) { CorElementType elemType = th.AsMethodTable()->GetInternalCorElementType(); TypeHandle underlyingHandle(CoreLibBinder::GetElementType(elemType)); diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs index 8ad537cde4785..f133d0b3f05a9 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs @@ -555,11 +555,7 @@ nullableHashcode is null || { if (valueComparer.Equals(node._value, comparisonValue)) { - // Do the reference type check up front to handle many cases of shared generics. - // If TValue is a value type then the field's value here can be baked in. Otherwise, - // for the remaining shared generic cases the field access here would disqualify inlining, - // so the following check cannot be factored out of TryAddInternal/TryUpdateInternal. - if (!typeof(TValue).IsValueType || ConcurrentDictionaryTypeProps.IsWriteAtomic) + if (IsWriteAtomic()) { node._value = newValue; } @@ -898,11 +894,7 @@ nullableHashcode is null || // be written atomically, since lock-free reads may be happening concurrently. if (updateIfExists) { - // Do the reference type check up front to handle many cases of shared generics. - // If TValue is a value type then the field's value here can be baked in. Otherwise, - // for the remaining shared generic cases the field access here would disqualify inlining, - // so the following check cannot be factored out of TryAddInternal/TryUpdateInternal. - if (!typeof(TValue).IsValueType || ConcurrentDictionaryTypeProps.IsWriteAtomic) + if (IsWriteAtomic()) { node._value = value; } @@ -2132,6 +2124,42 @@ private ReadOnlyCollection GetValues() } } + /// Whether T's type can be written atomically (i.e., with no danger of torn reads). + private static bool IsWriteAtomic() + { + // Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without + // the risk of tearing. See https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf + + if (!typeof(T).IsValueType || + typeof(T) == typeof(IntPtr) || + typeof(T) == typeof(UIntPtr)) + { + return true; + } + + switch (Type.GetTypeCode(typeof(T))) + { + case TypeCode.Boolean: + case TypeCode.Byte: + case TypeCode.Char: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.SByte: + case TypeCode.Single: + case TypeCode.UInt16: + case TypeCode.UInt32: + return true; + + case TypeCode.Double: + case TypeCode.Int64: + case TypeCode.UInt64: + return IntPtr.Size == 8; + + default: + return false; + } + } + /// /// A node in a singly-linked list representing a particular hash table bucket. /// @@ -2236,47 +2264,6 @@ private sealed class DictionaryEnumerator : IDictionaryEnumerator } } - internal static class ConcurrentDictionaryTypeProps - { - /// Whether T's type can be written atomically (i.e., with no danger of torn reads). - internal static readonly bool IsWriteAtomic = IsWriteAtomicPrivate(); - - private static bool IsWriteAtomicPrivate() - { - // Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without - // the risk of tearing. See https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf - - if (!typeof(T).IsValueType || - typeof(T) == typeof(IntPtr) || - typeof(T) == typeof(UIntPtr)) - { - return true; - } - - switch (Type.GetTypeCode(typeof(T))) - { - case TypeCode.Boolean: - case TypeCode.Byte: - case TypeCode.Char: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.SByte: - case TypeCode.Single: - case TypeCode.UInt16: - case TypeCode.UInt32: - return true; - - case TypeCode.Double: - case TypeCode.Int64: - case TypeCode.UInt64: - return IntPtr.Size == 8; - - default: - return false; - } - } - } - internal sealed class IDictionaryDebugView where TKey : notnull { private readonly IDictionary _dictionary; diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs index fbee608bbf480..aedbfa953bf88 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs @@ -243,7 +243,7 @@ private EnumEqualityComparer(SerializationInfo information, StreamingContext con public void GetObjectData(SerializationInfo info, StreamingContext context) { // For back-compat we need to serialize the comparers for enums with underlying types other than int as ObjectEqualityComparer - if (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T))) != TypeCode.Int32) + if (Type.GetTypeCode(typeof(T)) != TypeCode.Int32) { info.SetType(typeof(ObjectEqualityComparer)); } diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index edd3c6a7cc53a..6cf0faa1b1fb1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -267,72 +267,55 @@ protected override TypeCode GetTypeCodeImpl() if (typeCode != TypeCode.Empty) return typeCode; - CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this); - // keep in sync with Type.cs - switch (corElementType) - { - case CorElementType.ELEMENT_TYPE_BOOLEAN: - typeCode = TypeCode.Boolean; break; - case CorElementType.ELEMENT_TYPE_CHAR: - typeCode = TypeCode.Char; break; - case CorElementType.ELEMENT_TYPE_I1: - typeCode = TypeCode.SByte; break; - case CorElementType.ELEMENT_TYPE_U1: - typeCode = TypeCode.Byte; break; - case CorElementType.ELEMENT_TYPE_I2: - typeCode = TypeCode.Int16; break; - case CorElementType.ELEMENT_TYPE_U2: - typeCode = TypeCode.UInt16; break; - case CorElementType.ELEMENT_TYPE_I4: - typeCode = TypeCode.Int32; break; - case CorElementType.ELEMENT_TYPE_U4: - typeCode = TypeCode.UInt32; break; - case CorElementType.ELEMENT_TYPE_I8: - typeCode = TypeCode.Int64; break; - case CorElementType.ELEMENT_TYPE_U8: - typeCode = TypeCode.UInt64; break; - case CorElementType.ELEMENT_TYPE_R4: - typeCode = TypeCode.Single; break; - case CorElementType.ELEMENT_TYPE_R8: - typeCode = TypeCode.Double; break; -#if !CORECLR - case CorElementType.ELEMENT_TYPE_STRING: - typeCode = TypeCode.String; break; -#endif - case CorElementType.ELEMENT_TYPE_VALUETYPE: - if (ReferenceEquals(this, typeof(decimal))) - typeCode = TypeCode.Decimal; - else if (ReferenceEquals(this, typeof(DateTime))) - typeCode = TypeCode.DateTime; - else if (IsActualEnum) - typeCode = GetTypeCode(Enum.InternalGetUnderlyingType(this)); - else - typeCode = TypeCode.Object; - break; - default: -#if CORECLR - // GetSignatureCorElementType returns E_T_CLASS for E_T_STRING - if (ReferenceEquals(this, typeof(string))) - { - typeCode = TypeCode.String; - break; - } -#endif - if (ReferenceEquals(this, typeof(DBNull))) - { - typeCode = TypeCode.DBNull; - break; - } - - typeCode = TypeCode.Object; - break; - } - + typeCode = GetTypeCodeInternal(this); Cache.TypeCode = typeCode; return typeCode; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static TypeCode GetTypeCodeInternal(RuntimeType type) + { + RuntimeType underlyingType = type; + if (type.IsActualEnum) + underlyingType = type.GetEnumUnderlyingType(); + + if (underlyingType == typeof(sbyte)) + return TypeCode.SByte; + else if (underlyingType == typeof(byte)) + return TypeCode.Byte; + else if (underlyingType == typeof(short)) + return TypeCode.Int16; + else if (underlyingType == typeof(ushort)) + return TypeCode.UInt16; + else if (underlyingType == typeof(int)) + return TypeCode.Int32; + else if (underlyingType == typeof(uint)) + return TypeCode.UInt32; + else if (underlyingType == typeof(long)) + return TypeCode.Int64; + else if (underlyingType == typeof(ulong)) + return TypeCode.UInt64; + else if (underlyingType == typeof(bool)) + return TypeCode.Boolean; + else if (underlyingType == typeof(char)) + return TypeCode.Char; + else if (underlyingType == typeof(float)) + return TypeCode.Single; + else if (underlyingType == typeof(double)) + return TypeCode.Double; + else if (underlyingType == typeof(decimal)) + return TypeCode.Decimal; + else if (underlyingType == typeof(DateTime)) + return TypeCode.DateTime; + else if (underlyingType == typeof(string)) + return TypeCode.String; + else if (underlyingType == typeof(DBNull)) + return TypeCode.DBNull; + else + return TypeCode.Object; + } + protected override bool HasElementTypeImpl() => RuntimeTypeHandle.HasElementType(this); protected override bool IsArrayImpl() => RuntimeTypeHandle.IsArray(this); diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index e176d7f84f141..0c45bd4a1ce6b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -441,48 +441,9 @@ public static Type[] GetTypeArray(object[] args) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TypeCode GetTypeCode(Type? type) { - if (RuntimeHelpers.IsKnownConstant(type)) + if (RuntimeHelpers.IsKnownConstant(type) && type is RuntimeType) { - // keep in sync with RuntimeType.cs - Type? underlyingType = type; - if (type is RuntimeType && ((RuntimeType)type).IsActualEnum) - underlyingType = type.GetEnumUnderlyingType(); - if (underlyingType == null) - return TypeCode.Empty; - else if (underlyingType == typeof(sbyte)) - return TypeCode.SByte; - else if (underlyingType == typeof(byte)) - return TypeCode.Byte; - else if (underlyingType == typeof(short)) - return TypeCode.Int16; - else if (underlyingType == typeof(ushort)) - return TypeCode.UInt16; - else if (underlyingType == typeof(int)) - return TypeCode.Int32; - else if (underlyingType == typeof(uint)) - return TypeCode.UInt32; - else if (underlyingType == typeof(long)) - return TypeCode.Int64; - else if (underlyingType == typeof(ulong)) - return TypeCode.UInt64; - else if (underlyingType == typeof(bool)) - return TypeCode.Boolean; - else if (underlyingType == typeof(char)) - return TypeCode.Char; - else if (underlyingType == typeof(float)) - return TypeCode.Single; - else if (underlyingType == typeof(double)) - return TypeCode.Double; - else if (underlyingType == typeof(decimal)) - return TypeCode.Decimal; - else if (underlyingType == typeof(DateTime)) - return TypeCode.DateTime; - else if (underlyingType == typeof(string)) - return TypeCode.String; - else if (underlyingType == typeof(DBNull)) - return TypeCode.DBNull; - else if (underlyingType.GetType() == typeof(RuntimeType)) - return TypeCode.Object; + return RuntimeType.GetTypeCodeInternal((RuntimeType)type); } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index 7b002db36f83b..5edf07543a2a8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -13,13 +13,8 @@ namespace System.Text.Json.Serialization.Converters internal sealed class EnumConverter : JsonPrimitiveConverter where T : struct, Enum { - private static readonly TypeCode s_enumTypeCode = Type.GetTypeCode(typeof(T)); - private static readonly char[] s_specialChars = new[] { ',', ' ' }; - // Odd type codes are conveniently signed types (for enum backing types). - private static readonly bool s_isSignedEnum = ((int)s_enumTypeCode % 2) == 1; - private const string ValueSeparator = ", "; private readonly EnumConverterOptions _converterOptions; @@ -40,7 +35,10 @@ internal sealed class EnumConverter : JsonPrimitiveConverter // This is used to prevent flooding the cache due to exponential bitwise combinations of flags. // Since multiple threads can add to the cache, a few more values might be added. - private const int NameCacheSizeSoftLimit = 64; + private const int NameCacheSizeSoftLimit = 64;- + + // Odd type codes are conveniently signed types (for enum backing types). + private static bool IsSignedEnum => ((int)Type.GetTypeCode(typeof(T)) % 2) == 1; public override bool CanConvert(Type type) { @@ -130,7 +128,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return default; } - switch (s_enumTypeCode) + switch (Type.GetTypeCode(typeof(T))) { // Switch cases ordered by expected frequency @@ -233,7 +231,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions ThrowHelper.ThrowJsonException(); } - switch (s_enumTypeCode) + switch (Type.GetTypeCode(typeof(T))) { case TypeCode.Int32: writer.WriteNumberValue(Unsafe.As(ref value)); @@ -320,7 +318,7 @@ internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, J return; } - switch (s_enumTypeCode) + switch (Type.GetTypeCode(typeof(T))) { case TypeCode.Int32: writer.WritePropertyName(Unsafe.As(ref value)); @@ -440,7 +438,7 @@ private T ReadEnumUsingNamingPolicy(string? enumString) private static ulong ConvertToUInt64(object value) { Debug.Assert(value is T); - ulong result = s_enumTypeCode switch + ulong result = Type.GetTypeCode(typeof(T)) switch { TypeCode.Int32 => (ulong)(int)value, TypeCode.UInt32 => (uint)value, @@ -466,7 +464,7 @@ private static bool IsValidIdentifier(string value) // so we'll just pick the first valid one and check for a negative sign // if needed. return (value[0] >= 'A' && - (!s_isSignedEnum || !value.StartsWith(NumberFormatInfo.CurrentInfo.NegativeSign))); + (!IsSignedEnum || !value.StartsWith(NumberFormatInfo.CurrentInfo.NegativeSign))); } private static string FormatJsonName(string value, JsonNamingPolicy? namingPolicy) From b8be7f2cb328f666b210119cdcc74a279e07cda2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Mon, 31 Oct 2022 19:30:50 +0100 Subject: [PATCH 43/52] Remove accidental edit --- .../Text/Json/Serialization/Converters/Value/EnumConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index 5edf07543a2a8..ff4f76c05062d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -35,7 +35,7 @@ internal sealed class EnumConverter : JsonPrimitiveConverter // This is used to prevent flooding the cache due to exponential bitwise combinations of flags. // Since multiple threads can add to the cache, a few more values might be added. - private const int NameCacheSizeSoftLimit = 64;- + private const int NameCacheSizeSoftLimit = 64; // Odd type codes are conveniently signed types (for enum backing types). private static bool IsSignedEnum => ((int)Type.GetTypeCode(typeof(T)) % 2) == 1; From 7664920a29eda9d5beaa15176f00fdbca35ff00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:51:25 +0100 Subject: [PATCH 44/52] Fix build --- src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 6cf0faa1b1fb1..92e34970fbe1a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -278,7 +278,7 @@ internal static TypeCode GetTypeCodeInternal(RuntimeType type) { RuntimeType underlyingType = type; if (type.IsActualEnum) - underlyingType = type.GetEnumUnderlyingType(); + underlyingType = (RuntimeType)type.GetEnumUnderlyingType(); if (underlyingType == typeof(sbyte)) return TypeCode.SByte; From 30afabcf699d92b4e361c7e8feb7aa02db08a175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Mon, 31 Oct 2022 21:11:58 +0100 Subject: [PATCH 45/52] Fix build --- src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 1fce04a032251..47bdd811e19ef 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -5921,7 +5921,7 @@ void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* un if (underlyingType != nullptr) value.A = CastHandle(*underlyingType); else - value.A = nullptr; + value.A = 0; value.B = (DWORD)result; IsEnum->Add(key, value); From 3e14c6ec24ff61322cffb0e5da13ecdf015b9dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Mon, 31 Oct 2022 21:18:38 +0100 Subject: [PATCH 46/52] Fix build --- .../tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 927edab0e676c..02710124b444d 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -978,7 +978,7 @@ TypeCompareState interceptor_ICJI::isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLAS mc->cr->AddCall("isEnum"); CORINFO_CLASS_HANDLE tempUnderlyingType = nullptr; TypeCompareState temp = original_ICorJitInfo->isEnum(cls, &tempUnderlyingType); - mc->recIsEnum(cls, tempUnderlyingType, temp); + mc->recIsEnum(cls, &tempUnderlyingType, temp); if (underlyingType != nullptr) { *underlyingType = tempUnderlyingType; From d57b8aedc0b147fd5d51343de382cbdc83a9f7b0 Mon Sep 17 00:00:00 2001 From: petris Date: Tue, 1 Nov 2022 02:20:52 +0100 Subject: [PATCH 47/52] Fix NativeAOT build --- .../src/System/RuntimeType.cs | 45 +------------------ .../System.Private.CoreLib/src/System/Type.cs | 45 ++++++++++++++++++- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 92e34970fbe1a..7472df80e998e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -267,55 +267,12 @@ protected override TypeCode GetTypeCodeImpl() if (typeCode != TypeCode.Empty) return typeCode; - typeCode = GetTypeCodeInternal(this); + typeCode = Type.GetRuntimeTypeCode(this); Cache.TypeCode = typeCode; return typeCode; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static TypeCode GetTypeCodeInternal(RuntimeType type) - { - RuntimeType underlyingType = type; - if (type.IsActualEnum) - underlyingType = (RuntimeType)type.GetEnumUnderlyingType(); - - if (underlyingType == typeof(sbyte)) - return TypeCode.SByte; - else if (underlyingType == typeof(byte)) - return TypeCode.Byte; - else if (underlyingType == typeof(short)) - return TypeCode.Int16; - else if (underlyingType == typeof(ushort)) - return TypeCode.UInt16; - else if (underlyingType == typeof(int)) - return TypeCode.Int32; - else if (underlyingType == typeof(uint)) - return TypeCode.UInt32; - else if (underlyingType == typeof(long)) - return TypeCode.Int64; - else if (underlyingType == typeof(ulong)) - return TypeCode.UInt64; - else if (underlyingType == typeof(bool)) - return TypeCode.Boolean; - else if (underlyingType == typeof(char)) - return TypeCode.Char; - else if (underlyingType == typeof(float)) - return TypeCode.Single; - else if (underlyingType == typeof(double)) - return TypeCode.Double; - else if (underlyingType == typeof(decimal)) - return TypeCode.Decimal; - else if (underlyingType == typeof(DateTime)) - return TypeCode.DateTime; - else if (underlyingType == typeof(string)) - return TypeCode.String; - else if (underlyingType == typeof(DBNull)) - return TypeCode.DBNull; - else - return TypeCode.Object; - } - protected override bool HasElementTypeImpl() => RuntimeTypeHandle.HasElementType(this); protected override bool IsArrayImpl() => RuntimeTypeHandle.IsArray(this); diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 0c45bd4a1ce6b..0ab6e955e37d9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -443,11 +443,54 @@ public static TypeCode GetTypeCode(Type? type) { if (RuntimeHelpers.IsKnownConstant(type) && type is RuntimeType) { - return RuntimeType.GetTypeCodeInternal((RuntimeType)type); + return GetRuntimeTypeCode((RuntimeType)type); } return type?.GetTypeCodeImpl() ?? TypeCode.Empty; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static TypeCode GetRuntimeTypeCode(RuntimeType type) + { + RuntimeType underlyingType = type; + if (type.IsActualEnum) + underlyingType = (RuntimeType)type.GetEnumUnderlyingType(); + + if (underlyingType == typeof(sbyte)) + return TypeCode.SByte; + else if (underlyingType == typeof(byte)) + return TypeCode.Byte; + else if (underlyingType == typeof(short)) + return TypeCode.Int16; + else if (underlyingType == typeof(ushort)) + return TypeCode.UInt16; + else if (underlyingType == typeof(int)) + return TypeCode.Int32; + else if (underlyingType == typeof(uint)) + return TypeCode.UInt32; + else if (underlyingType == typeof(long)) + return TypeCode.Int64; + else if (underlyingType == typeof(ulong)) + return TypeCode.UInt64; + else if (underlyingType == typeof(bool)) + return TypeCode.Boolean; + else if (underlyingType == typeof(char)) + return TypeCode.Char; + else if (underlyingType == typeof(float)) + return TypeCode.Single; + else if (underlyingType == typeof(double)) + return TypeCode.Double; + else if (underlyingType == typeof(decimal)) + return TypeCode.Decimal; + else if (underlyingType == typeof(DateTime)) + return TypeCode.DateTime; + else if (underlyingType == typeof(string)) + return TypeCode.String; + else if (underlyingType == typeof(DBNull)) + return TypeCode.DBNull; + else + return TypeCode.Object; + } + protected virtual TypeCode GetTypeCodeImpl() { Type systemType = UnderlyingSystemType; From d2d72dff504604ba9d97376f5dae2dea0696ac3e Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 3 Nov 2022 02:20:49 +0100 Subject: [PATCH 48/52] Remove merge leftovers --- src/coreclr/inc/jiteeversionguid.h.orig | 65 - .../CorInfoImpl_generated.cs.orig | 2912 ----------------- .../superpmi-shared/methodcontext.h.orig | 1169 ------- 3 files changed, 4146 deletions(-) delete mode 100644 src/coreclr/inc/jiteeversionguid.h.orig delete mode 100644 src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs.orig delete mode 100644 src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h.orig diff --git a/src/coreclr/inc/jiteeversionguid.h.orig b/src/coreclr/inc/jiteeversionguid.h.orig deleted file mode 100644 index eae0bed26ebf9..0000000000000 --- a/src/coreclr/inc/jiteeversionguid.h.orig +++ /dev/null @@ -1,65 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -// -// #JITEEVersionIdentifier -// -// This GUID represents the version of the JIT/EE interface. Any time the interface between the JIT and -// the EE changes (by adding or removing methods to any interface shared between them), this GUID should -// be changed. This is the identifier verified by ICorJitCompiler::getVersionIdentifier(). -// -// You can use "uuidgen.exe -s" to generate this value. -// -// Note that this file is parsed by some tools, namely superpmi.py, so make sure the first line is exactly -// of the form: -// -// constexpr GUID JITEEVersionIdentifier = { /* 1776ab48-edfa-49be-a11f-ec216b28174c */ -// -// (without the leading slashes or spaces). -// -// See docs/project/updating-jitinterface.md for details -// -// **** NOTE TO INTEGRATORS: -// -// If there is a merge conflict here, because the version changed in two different places, you must -// create a **NEW** GUID, not simply choose one or the other! -// -// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -// -////////////////////////////////////////////////////////////////////////////////////////////////////////// -// - -#ifndef GUID_DEFINED -typedef struct _GUID { - uint32_t Data1; // NOTE: diff from Win32, for LP64 - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[ 8 ]; -} GUID; -typedef const GUID *LPCGUID; -#define GUID_DEFINED -#endif // !GUID_DEFINED - -<<<<<<< HEAD -constexpr GUID JITEEVersionIdentifier = { /* 592e86d5-88ba-4478-8381-64010f9fa1ba */ - 0x592e86d5, - 0x88ba, - 0x4478, - {0x83, 0x81, 0x64, 0x01, 0x0f, 0x9f, 0xa1, 0xba} -======= -constexpr GUID JITEEVersionIdentifier = { /* 77b6df16-d27f-4118-9dfd-d8073ff20fb6 */ - 0x77b6df16, - 0xd27f, - 0x4118, - {0x9d, 0xfd, 0xd8, 0x7, 0x3f, 0xf2, 0xf, 0xb6} ->>>>>>> original/main - }; - -////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// END JITEEVersionIdentifier -// -////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs.orig b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs.orig deleted file mode 100644 index 87c5fbac4cc9a..0000000000000 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs.orig +++ /dev/null @@ -1,2912 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// DO NOT EDIT THIS FILE! IT IS AUTOGENERATED -// To regenerate run the gen script in src/coreclr/tools/Common/JitInterface/ThunkGenerator -// and follow the instructions in docs/project/updating-jitinterface.md - -using System; -using System.Runtime.InteropServices; - -namespace Internal.JitInterface -{ - internal unsafe partial class CorInfoImpl - { - [UnmanagedCallersOnly] - private static byte _isIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn) - { - var _this = GetThis(thisHandle); - try - { - return _this.isIntrinsic(ftn) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getMethodAttribs(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodAttribs(ftn); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _setMethodAttribs(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, CorInfoMethodRuntimeFlags attribs) - { - var _this = GetThis(thisHandle); - try - { - _this.setMethodAttribs(ftn, attribs); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getMethodSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_STRUCT_* memberParent) - { - var _this = GetThis(thisHandle); - try - { - _this.getMethodSig(ftn, sig, memberParent); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _getMethodInfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, CORINFO_METHOD_INFO* info) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodInfo(ftn, info) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoInline _canInline(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.canInline(callerHnd, calleeHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _beginInlining(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd) - { - var _this = GetThis(thisHandle); - try - { - _this.beginInlining(inlinerHnd, inlineeHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _reportInliningDecision(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd, CorInfoInline inlineResult, byte* reason) - { - var _this = GetThis(thisHandle); - try - { - _this.reportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _canTailCall(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* declaredCalleeHnd, CORINFO_METHOD_STRUCT_* exactCalleeHnd, byte fIsTailPrefix) - { - var _this = GetThis(thisHandle); - try - { - return _this.canTailCall(callerHnd, declaredCalleeHnd, exactCalleeHnd, fIsTailPrefix != 0) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _reportTailCallDecision(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* calleeHnd, byte fIsTailPrefix, CorInfoTailCall tailCallResult, byte* reason) - { - var _this = GetThis(thisHandle); - try - { - _this.reportTailCallDecision(callerHnd, calleeHnd, fIsTailPrefix != 0, tailCallResult, reason); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getEHinfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint EHnumber, CORINFO_EH_CLAUSE* clause) - { - var _this = GetThis(thisHandle); - try - { - _this.getEHinfo(ftn, EHnumber, ref *clause); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getMethodClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodClass(method); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_MODULE_STRUCT_* _getMethodModule(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodModule(method); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getMethodVTableOffset(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, uint* offsetOfIndirection, uint* offsetAfterIndirection, bool* isRelative) - { - var _this = GetThis(thisHandle); - try - { - _this.getMethodVTableOffset(method, ref *offsetOfIndirection, ref *offsetAfterIndirection, ref *isRelative); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _resolveVirtualMethod(IntPtr thisHandle, IntPtr* ppException, CORINFO_DEVIRTUALIZATION_INFO* info) - { - var _this = GetThis(thisHandle); - try - { - return _this.resolveVirtualMethod(info) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_METHOD_STRUCT_* _getUnboxedEntry(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, bool* requiresInstMethodTableArg) - { - var _this = GetThis(thisHandle); - try - { - return _this.getUnboxedEntry(ftn, ref *requiresInstMethodTableArg); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getDefaultComparerClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType) - { - var _this = GetThis(thisHandle); - try - { - return _this.getDefaultComparerClass(elemType); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getDefaultEqualityComparerClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* elemType) - { - var _this = GetThis(thisHandle); - try - { - return _this.getDefaultEqualityComparerClass(elemType); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _expandRawHandleIntrinsic(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult) - { - var _this = GetThis(thisHandle); - try - { - _this.expandRawHandleIntrinsic(ref *pResolvedToken, ref *pResult); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _isIntrinsicType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* classHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.isIntrinsicType(classHnd) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoCallConvExtension _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) - { - var _this = GetThis(thisHandle); - try - { - return _this.getUnmanagedCallConv(method, callSiteSig, ref *pSuppressGCTransition); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _pInvokeMarshalingRequired(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig) - { - var _this = GetThis(thisHandle); - try - { - return _this.pInvokeMarshalingRequired(method, callSiteSig) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _satisfiesMethodConstraints(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* parent, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - return _this.satisfiesMethodConstraints(parent, method) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isCompatibleDelegate(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* objCls, CORINFO_CLASS_STRUCT_* methodParentCls, CORINFO_METHOD_STRUCT_* method, CORINFO_CLASS_STRUCT_* delegateCls, bool* pfIsOpenDelegate) - { - var _this = GetThis(thisHandle); - try - { - return _this.isCompatibleDelegate(objCls, methodParentCls, method, delegateCls, ref *pfIsOpenDelegate) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _methodMustBeLoadedBeforeCodeIsRun(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - _this.methodMustBeLoadedBeforeCodeIsRun(method); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_METHOD_STRUCT_* _mapMethodDeclToMethodImpl(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - return _this.mapMethodDeclToMethodImpl(method); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getGSCookie(IntPtr thisHandle, IntPtr* ppException, IntPtr* pCookieVal, IntPtr** ppCookieVal) - { - var _this = GetThis(thisHandle); - try - { - _this.getGSCookie(pCookieVal, ppCookieVal); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _setPatchpointInfo(IntPtr thisHandle, IntPtr* ppException, PatchpointInfo* patchpointInfo) - { - var _this = GetThis(thisHandle); - try - { - _this.setPatchpointInfo(patchpointInfo); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static PatchpointInfo* _getOSRInfo(IntPtr thisHandle, IntPtr* ppException, uint* ilOffset) - { - var _this = GetThis(thisHandle); - try - { - return _this.getOSRInfo(ref *ilOffset); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _resolveToken(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken) - { - var _this = GetThis(thisHandle); - try - { - _this.resolveToken(ref *pResolvedToken); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _tryResolveToken(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken) - { - var _this = GetThis(thisHandle); - try - { - return _this.tryResolveToken(ref *pResolvedToken) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _findSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEXT_STRUCT* context, CORINFO_SIG_INFO* sig) - { - var _this = GetThis(thisHandle); - try - { - _this.findSig(module, sigTOK, context, sig); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _findCallSiteSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint methTOK, CORINFO_CONTEXT_STRUCT* context, CORINFO_SIG_INFO* sig) - { - var _this = GetThis(thisHandle); - try - { - _this.findCallSiteSig(module, methTOK, context, sig); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getTokenTypeAsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTokenTypeAsHandle(ref *pResolvedToken); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isValidToken(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint metaTOK) - { - var _this = GetThis(thisHandle); - try - { - return _this.isValidToken(module, metaTOK) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isValidStringRef(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint metaTOK) - { - var _this = GetThis(thisHandle); - try - { - return _this.isValidStringRef(module, metaTOK) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _getStringLiteral(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, uint metaTOK, char* buffer, int bufferSize, int startIndex) - { - var _this = GetThis(thisHandle); - try - { - return _this.getStringLiteral(module, metaTOK, buffer, bufferSize, startIndex); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static UIntPtr _printObjectDescription(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* handle, byte* buffer, UIntPtr bufferSize, UIntPtr* pRequiredBufferSize) - { - var _this = GetThis(thisHandle); - try - { - return _this.printObjectDescription(handle, buffer, bufferSize, pRequiredBufferSize); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoType _asCorInfoType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.asCorInfoType(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getClassName(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassName(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getClassNameFromMetadata(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, byte** namespaceName) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassNameFromMetadata(cls, namespaceName); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getTypeInstantiationArgument(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, uint index) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTypeInstantiationArgument(cls, index); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _appendClassName(IntPtr thisHandle, IntPtr* ppException, char** ppBuf, int* pnBufLen, CORINFO_CLASS_STRUCT_* cls, byte fNamespace, byte fFullInst, byte fAssembly) - { - var _this = GetThis(thisHandle); - try - { - return _this.appendClassName(ppBuf, ref *pnBufLen, cls, fNamespace != 0, fFullInst != 0, fAssembly != 0); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isValueClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.isValueClass(cls) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoInlineTypeCheck _canInlineTypeCheck(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CorInfoInlineTypeCheckSource source) - { - var _this = GetThis(thisHandle); - try - { - return _this.canInlineTypeCheck(cls, source); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassAttribs(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassAttribs(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_MODULE_STRUCT_* _getClassModule(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassModule(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_ASSEMBLY_STRUCT_* _getModuleAssembly(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* mod) - { - var _this = GetThis(thisHandle); - try - { - return _this.getModuleAssembly(mod); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getAssemblyName(IntPtr thisHandle, IntPtr* ppException, CORINFO_ASSEMBLY_STRUCT_* assem) - { - var _this = GetThis(thisHandle); - try - { - return _this.getAssemblyName(assem); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void* _LongLifetimeMalloc(IntPtr thisHandle, IntPtr* ppException, UIntPtr sz) - { - var _this = GetThis(thisHandle); - try - { - return _this.LongLifetimeMalloc(sz); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _LongLifetimeFree(IntPtr thisHandle, IntPtr* ppException, void* obj) - { - var _this = GetThis(thisHandle); - try - { - _this.LongLifetimeFree(obj); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static UIntPtr _getClassModuleIdForStatics(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CORINFO_MODULE_STRUCT_** pModule, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassModuleIdForStatics(cls, pModule, ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassSize(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassSize(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getHeapClassSize(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getHeapClassSize(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _canAllocateOnStack(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.canAllocateOnStack(cls) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassAlignmentRequirement(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, byte fDoubleAlignHint) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassAlignmentRequirement(cls, fDoubleAlignHint != 0); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassGClayout(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, byte* gcPtrs) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassGClayout(cls, gcPtrs); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassNumInstanceFields(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassNumInstanceFields(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_FIELD_STRUCT_* _getFieldInClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* clsHnd, int num) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldInClass(clsHnd, num); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _checkMethodModifier(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* hMethod, byte* modifier, byte fOptional) - { - var _this = GetThis(thisHandle); - try - { - return _this.checkMethodModifier(hMethod, modifier, fOptional != 0) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getNewHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, bool* pHasSideEffects) - { - var _this = GetThis(thisHandle); - try - { - return _this.getNewHelper(ref *pResolvedToken, callerHandle, ref *pHasSideEffects); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getNewArrHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* arrayCls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getNewArrHelper(arrayCls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getCastingHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fThrowing) - { - var _this = GetThis(thisHandle); - try - { - return _this.getCastingHelper(ref *pResolvedToken, fThrowing != 0); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getSharedCCtorHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* clsHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.getSharedCCtorHelper(clsHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getTypeForBox(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTypeForBox(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getBoxHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getBoxHelper(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getUnBoxHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getUnBoxHelper(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_OBJECT_STRUCT_* _getRuntimeTypePointer(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getRuntimeTypePointer(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isObjectImmutable(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objPtr) - { - var _this = GetThis(thisHandle); - try - { - return _this.isObjectImmutable(objPtr) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getObjectType(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objPtr) - { - var _this = GetThis(thisHandle); - try - { - return _this.getObjectType(objPtr); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _getReadyToRunHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP* pLookup) - { - var _this = GetThis(thisHandle); - try - { - return _this.getReadyToRunHelper(ref *pResolvedToken, ref *pGenericLookupKind, id, ref *pLookup) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getReadyToRunDelegateCtorHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pTargetMethod, mdToken targetConstraint, CORINFO_CLASS_STRUCT_* delegateType, CORINFO_LOOKUP* pLookup) - { - var _this = GetThis(thisHandle); - try - { - _this.getReadyToRunDelegateCtorHelper(ref *pTargetMethod, targetConstraint, delegateType, ref *pLookup); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte* _getHelperName(IntPtr thisHandle, IntPtr* ppException, CorInfoHelpFunc helpFunc) - { - var _this = GetThis(thisHandle); - try - { - return _this.getHelperName(helpFunc); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoInitClassResult _initClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, CORINFO_METHOD_STRUCT_* method, CORINFO_CONTEXT_STRUCT* context) - { - var _this = GetThis(thisHandle); - try - { - return _this.initClass(field, method, context); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _classMustBeLoadedBeforeCodeIsRun(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - _this.classMustBeLoadedBeforeCodeIsRun(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getBuiltinClass(IntPtr thisHandle, IntPtr* ppException, CorInfoClassId classId) - { - var _this = GetThis(thisHandle); - try - { - return _this.getBuiltinClass(classId); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoType _getTypeForPrimitiveValueClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTypeForPrimitiveValueClass(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoType _getTypeForPrimitiveNumericClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTypeForPrimitiveNumericClass(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _canCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* child, CORINFO_CLASS_STRUCT_* parent) - { - var _this = GetThis(thisHandle); - try - { - return _this.canCast(child, parent) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _areTypesEquivalent(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.areTypesEquivalent(cls1, cls2) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static TypeCompareState _compareTypesForCast(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* fromClass, CORINFO_CLASS_STRUCT_* toClass) - { - var _this = GetThis(thisHandle); - try - { - return _this.compareTypesForCast(fromClass, toClass); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static TypeCompareState _compareTypesForEquality(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.compareTypesForEquality(cls1, cls2); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _mergeClasses(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.mergeClasses(cls1, cls2); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isMoreSpecificType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls1, CORINFO_CLASS_STRUCT_* cls2) - { - var _this = GetThis(thisHandle); - try - { - return _this.isMoreSpecificType(cls1, cls2) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static TypeCompareState _isEnum(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType) - { - var _this = GetThis(thisHandle); - try - { - return _this.isEnum(cls, underlyingType); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getParentType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getParentType(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoType _getChildType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* clsHnd, CORINFO_CLASS_STRUCT_** clsRet) - { - var _this = GetThis(thisHandle); - try - { - return _this.getChildType(clsHnd, clsRet); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _satisfiesClassConstraints(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.satisfiesClassConstraints(cls) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isSDArray(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.isSDArray(cls) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getArrayRank(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArrayRank(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoArrayIntrinsic _getArrayIntrinsicID(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArrayIntrinsicID(ftn); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void* _getArrayInitializationData(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, uint size) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArrayInitializationData(field, size); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoIsAccessAllowedResult _canAccessClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_HELPER_DESC* pAccessHelper) - { - var _this = GetThis(thisHandle); - try - { - return _this.canAccessClass(ref *pResolvedToken, callerHandle, ref *pAccessHelper); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getFieldName(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* ftn, byte** moduleName) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldName(ftn, moduleName); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getFieldClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldClass(field); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoType _getFieldType(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, CORINFO_CLASS_STRUCT_** structType, CORINFO_CLASS_STRUCT_* memberParent) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldType(field, structType, memberParent); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getFieldOffset(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldOffset(field); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getFieldInfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_ACCESS_FLAGS flags, CORINFO_FIELD_INFO* pResult) - { - var _this = GetThis(thisHandle); - try - { - _this.getFieldInfo(ref *pResolvedToken, callerHandle, flags, pResult); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _isFieldStatic(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* fldHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.isFieldStatic(fldHnd) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _getArrayOrStringLength(IntPtr thisHandle, IntPtr* ppException, CORINFO_OBJECT_STRUCT_* objHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArrayOrStringLength(objHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getBoundaries(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint* cILOffsets, uint** pILOffsets, BoundaryTypes* implicitBoundaries) - { - var _this = GetThis(thisHandle); - try - { - _this.getBoundaries(ftn, ref *cILOffsets, ref *pILOffsets, implicitBoundaries); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _setBoundaries(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint cMap, OffsetMapping* pMap) - { - var _this = GetThis(thisHandle); - try - { - _this.setBoundaries(ftn, cMap, pMap); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getVars(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint* cVars, ILVarInfo** vars, bool* extendOthers) - { - var _this = GetThis(thisHandle); - try - { - _this.getVars(ftn, ref *cVars, vars, ref *extendOthers); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _setVars(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, uint cVars, NativeVarInfo* vars) - { - var _this = GetThis(thisHandle); - try - { - _this.setVars(ftn, cVars, vars); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _reportRichMappings(IntPtr thisHandle, IntPtr* ppException, InlineTreeNode* inlineTreeNodes, uint numInlineTreeNodes, RichOffsetMapping* mappings, uint numMappings) - { - var _this = GetThis(thisHandle); - try - { - _this.reportRichMappings(inlineTreeNodes, numInlineTreeNodes, mappings, numMappings); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void* _allocateArray(IntPtr thisHandle, IntPtr* ppException, UIntPtr cBytes) - { - var _this = GetThis(thisHandle); - try - { - return _this.allocateArray(cBytes); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _freeArray(IntPtr thisHandle, IntPtr* ppException, void* array) - { - var _this = GetThis(thisHandle); - try - { - _this.freeArray(array); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_ARG_LIST_STRUCT_* _getArgNext(IntPtr thisHandle, IntPtr* ppException, CORINFO_ARG_LIST_STRUCT_* args) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArgNext(args); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoTypeWithMod _getArgType(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArgType(sig, args, vcTypeRet); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _getExactClasses(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* baseType, int maxExactClasses, CORINFO_CLASS_STRUCT_** exactClsRet) - { - var _this = GetThis(thisHandle); - try - { - return _this.getExactClasses(baseType, maxExactClasses, exactClsRet); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getArgClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArgClass(sig, args); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHFAElemType _getHFAType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* hClass) - { - var _this = GetThis(thisHandle); - try - { - return _this.getHFAType(hClass); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static HRESULT _GetErrorHRESULT(IntPtr thisHandle, IntPtr* ppException, _EXCEPTION_POINTERS* pExceptionPointers) - { - var _this = GetThis(thisHandle); - try - { - return _this.GetErrorHRESULT(pExceptionPointers); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _GetErrorMessage(IntPtr thisHandle, IntPtr* ppException, char* buffer, uint bufferLength) - { - var _this = GetThis(thisHandle); - try - { - return _this.GetErrorMessage(buffer, bufferLength); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _FilterException(IntPtr thisHandle, IntPtr* ppException, _EXCEPTION_POINTERS* pExceptionPointers) - { - var _this = GetThis(thisHandle); - try - { - return _this.FilterException(pExceptionPointers); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _ThrowExceptionForJitResult(IntPtr thisHandle, IntPtr* ppException, HRESULT result) - { - var _this = GetThis(thisHandle); - try - { - _this.ThrowExceptionForJitResult(result); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _ThrowExceptionForHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_HELPER_DESC* throwHelper) - { - var _this = GetThis(thisHandle); - try - { - _this.ThrowExceptionForHelper(ref *throwHelper); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _runWithErrorTrap(IntPtr thisHandle, IntPtr* ppException, void* function, void* parameter) - { - var _this = GetThis(thisHandle); - try - { - return _this.runWithErrorTrap(function, parameter) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _runWithSPMIErrorTrap(IntPtr thisHandle, IntPtr* ppException, void* function, void* parameter) - { - var _this = GetThis(thisHandle); - try - { - return _this.runWithSPMIErrorTrap(function, parameter) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getEEInfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_EE_INFO* pEEInfoOut) - { - var _this = GetThis(thisHandle); - try - { - _this.getEEInfo(ref *pEEInfoOut); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static char* _getJitTimeLogFilename(IntPtr thisHandle, IntPtr* ppException) - { - var _this = GetThis(thisHandle); - try - { - return _this.getJitTimeLogFilename(); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static mdToken _getMethodDefFromMethod(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* hMethod) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodDefFromMethod(hMethod); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getMethodName(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, byte** moduleName) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodName(ftn, moduleName); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte* _getMethodNameFromMetadata(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, byte** className, byte** namespaceName, byte** enclosingClassName) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodNameFromMetadata(ftn, className, namespaceName, enclosingClassName); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getMethodHash(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodHash(ftn); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static UIntPtr _findNameOfToken(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* moduleHandle, mdToken token, byte* szFQName, UIntPtr FQNameCapacity) - { - var _this = GetThis(thisHandle); - try - { - return _this.findNameOfToken(moduleHandle, token, szFQName, FQNameCapacity); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _getSystemVAmd64PassStructInRegisterDescriptor(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr) - { - var _this = GetThis(thisHandle); - try - { - return _this.getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getLoongArch64PassStructInRegisterFlags(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* structHnd) - { - var _this = GetThis(thisHandle); - try - { - return _this.getLoongArch64PassStructInRegisterFlags(structHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getThreadTLSIndex(ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void* _getInlinedCallFrameVptr(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getInlinedCallFrameVptr(ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int* _getAddrOfCaptureThreadGlobal(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getAddrOfCaptureThreadGlobal(ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void* _getHelperFtn(IntPtr thisHandle, IntPtr* ppException, CorInfoHelpFunc ftnNum, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getHelperFtn(ftnNum, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _getFunctionEntryPoint(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, CORINFO_CONST_LOOKUP* pResult, CORINFO_ACCESS_FLAGS accessFlags) - { - var _this = GetThis(thisHandle); - try - { - _this.getFunctionEntryPoint(ftn, ref *pResult, accessFlags); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getFunctionFixedEntryPoint(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, byte isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult) - { - var _this = GetThis(thisHandle); - try - { - _this.getFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer != 0, ref *pResult); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void* _getMethodSync(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodSync(ftn, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CorInfoHelpFunc _getLazyStringLiteralHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* handle) - { - var _this = GetThis(thisHandle); - try - { - return _this.getLazyStringLiteralHelper(handle); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_MODULE_STRUCT_* _embedModuleHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* handle, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.embedModuleHandle(handle, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _embedClassHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* handle, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.embedClassHandle(handle, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_METHOD_STRUCT_* _embedMethodHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* handle, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.embedMethodHandle(handle, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_FIELD_STRUCT_* _embedFieldHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* handle, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.embedFieldHandle(handle, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _embedGenericHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte fEmbedParent, CORINFO_GENERICHANDLE_RESULT* pResult) - { - var _this = GetThis(thisHandle); - try - { - _this.embedGenericHandle(ref *pResolvedToken, fEmbedParent != 0, ref *pResult); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getLocationOfThisType(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* context, CORINFO_LOOKUP_KIND* pLookupKind) - { - var _this = GetThis(thisHandle); - try - { - _this.getLocationOfThisType(context, ref *pLookupKind); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getAddressOfPInvokeTarget(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_CONST_LOOKUP* pLookup) - { - var _this = GetThis(thisHandle); - try - { - _this.getAddressOfPInvokeTarget(method, ref *pLookup); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void* _GetCookieForPInvokeCalliSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* szMetaSig, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.GetCookieForPInvokeCalliSig(szMetaSig, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _canGetCookieForPInvokeCalliSig(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* szMetaSig) - { - var _this = GetThis(thisHandle); - try - { - return _this.canGetCookieForPInvokeCalliSig(szMetaSig) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_JUST_MY_CODE_HANDLE_* _getJustMyCodeHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_JUST_MY_CODE_HANDLE_** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getJustMyCodeHandle(method, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _GetProfilingHandle(IntPtr thisHandle, IntPtr* ppException, bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles) - { - var _this = GetThis(thisHandle); - try - { - _this.GetProfilingHandle(ref *pbHookFunction, ref *pProfilerHandle, ref *pbIndirectedHandles); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _getCallInfo(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, CORINFO_CALLINFO_FLAGS flags, CORINFO_CALL_INFO* pResult) - { - var _this = GetThis(thisHandle); - try - { - _this.getCallInfo(ref *pResolvedToken, pConstrainedResolvedToken, callerHandle, flags, pResult); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _canAccessFamily(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* hCaller, CORINFO_CLASS_STRUCT_* hInstanceType) - { - var _this = GetThis(thisHandle); - try - { - return _this.canAccessFamily(hCaller, hInstanceType) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _isRIDClassDomainID(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.isRIDClassDomainID(cls) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getClassDomainID(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getClassDomainID(cls, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void* _getFieldAddress(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldAddress(field, ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _getReadonlyStaticFieldValue(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* buffer, int bufferSize, byte ignoreMovableObjects) - { - var _this = GetThis(thisHandle); - try - { - return _this.getReadonlyStaticFieldValue(field, buffer, bufferSize, ignoreMovableObjects != 0) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static CORINFO_CLASS_STRUCT_* _getStaticFieldCurrentClass(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, byte* pIsSpeculative) - { - var _this = GetThis(thisHandle); - try - { - return _this.getStaticFieldCurrentClass(field, pIsSpeculative); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static IntPtr _getVarArgsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* pSig, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getVarArgsHandle(pSig, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _canGetVarArgsHandle(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* pSig) - { - var _this = GetThis(thisHandle); - try - { - return _this.canGetVarArgsHandle(pSig) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static InfoAccessType _constructStringLiteral(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* module, mdToken metaTok, void** ppValue) - { - var _this = GetThis(thisHandle); - try - { - return _this.constructStringLiteral(module, metaTok, ref *ppValue); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static InfoAccessType _emptyStringLiteral(IntPtr thisHandle, IntPtr* ppException, void** ppValue) - { - var _this = GetThis(thisHandle); - try - { - return _this.emptyStringLiteral(ref *ppValue); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getFieldThreadLocalStoreID(IntPtr thisHandle, IntPtr* ppException, CORINFO_FIELD_STRUCT_* field, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getFieldThreadLocalStoreID(field, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _addActiveDependency(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* moduleFrom, CORINFO_MODULE_STRUCT_* moduleTo) - { - var _this = GetThis(thisHandle); - try - { - _this.addActiveDependency(moduleFrom, moduleTo); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static CORINFO_METHOD_STRUCT_* _GetDelegateCtor(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* methHnd, CORINFO_CLASS_STRUCT_* clsHnd, CORINFO_METHOD_STRUCT_* targetMethodHnd, DelegateCtorArgs* pCtorData) - { - var _this = GetThis(thisHandle); - try - { - return _this.GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, ref *pCtorData); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _MethodCompileComplete(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* methHnd) - { - var _this = GetThis(thisHandle); - try - { - _this.MethodCompileComplete(methHnd); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _getTailCallHelpers(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* callToken, CORINFO_SIG_INFO* sig, CORINFO_GET_TAILCALL_HELPERS_FLAGS flags, CORINFO_TAILCALL_HELPERS* pResult) - { - var _this = GetThis(thisHandle); - try - { - return _this.getTailCallHelpers(ref *callToken, sig, flags, ref *pResult) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _convertPInvokeCalliToCall(IntPtr thisHandle, IntPtr* ppException, CORINFO_RESOLVED_TOKEN* pResolvedToken, byte mustConvert) - { - var _this = GetThis(thisHandle); - try - { - return _this.convertPInvokeCalliToCall(ref *pResolvedToken, mustConvert != 0) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static byte _notifyInstructionSetUsage(IntPtr thisHandle, IntPtr* ppException, InstructionSet instructionSet, byte supportEnabled) - { - var _this = GetThis(thisHandle); - try - { - return _this.notifyInstructionSetUsage(instructionSet, supportEnabled != 0) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _updateEntryPointForTailCall(IntPtr thisHandle, IntPtr* ppException, CORINFO_CONST_LOOKUP* entryPoint) - { - var _this = GetThis(thisHandle); - try - { - _this.updateEntryPointForTailCall(ref *entryPoint); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _allocMem(IntPtr thisHandle, IntPtr* ppException, AllocMemArgs* pArgs) - { - var _this = GetThis(thisHandle); - try - { - _this.allocMem(ref *pArgs); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _reserveUnwindInfo(IntPtr thisHandle, IntPtr* ppException, byte isFunclet, byte isColdCode, uint unwindSize) - { - var _this = GetThis(thisHandle); - try - { - _this.reserveUnwindInfo(isFunclet != 0, isColdCode != 0, unwindSize); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _allocUnwindInfo(IntPtr thisHandle, IntPtr* ppException, byte* pHotCode, byte* pColdCode, uint startOffset, uint endOffset, uint unwindSize, byte* pUnwindBlock, CorJitFuncKind funcKind) - { - var _this = GetThis(thisHandle); - try - { - _this.allocUnwindInfo(pHotCode, pColdCode, startOffset, endOffset, unwindSize, pUnwindBlock, funcKind); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void* _allocGCInfo(IntPtr thisHandle, IntPtr* ppException, UIntPtr size) - { - var _this = GetThis(thisHandle); - try - { - return _this.allocGCInfo(size); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _setEHcount(IntPtr thisHandle, IntPtr* ppException, uint cEH) - { - var _this = GetThis(thisHandle); - try - { - _this.setEHcount(cEH); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _setEHinfo(IntPtr thisHandle, IntPtr* ppException, uint EHnumber, CORINFO_EH_CLAUSE* clause) - { - var _this = GetThis(thisHandle); - try - { - _this.setEHinfo(EHnumber, ref *clause); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static byte _logMsg(IntPtr thisHandle, IntPtr* ppException, uint level, byte* fmt, IntPtr args) - { - var _this = GetThis(thisHandle); - try - { - return _this.logMsg(level, fmt, args) ? (byte)1 : (byte)0; - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static int _doAssert(IntPtr thisHandle, IntPtr* ppException, byte* szFile, int iLine, byte* szExpr) - { - var _this = GetThis(thisHandle); - try - { - return _this.doAssert(szFile, iLine, szExpr); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _reportFatalError(IntPtr thisHandle, IntPtr* ppException, CorJitResult result) - { - var _this = GetThis(thisHandle); - try - { - _this.reportFatalError(result); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static HRESULT _getPgoInstrumentationResults(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema** pSchema, uint* pCountSchemaItems, byte** pInstrumentationData, PgoSource* pgoSource) - { - var _this = GetThis(thisHandle); - try - { - return _this.getPgoInstrumentationResults(ftnHnd, ref *pSchema, ref *pCountSchemaItems, pInstrumentationData, ref *pgoSource); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static HRESULT _allocPgoInstrumentationBySchema(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema* pSchema, uint countSchemaItems, byte** pInstrumentationData) - { - var _this = GetThis(thisHandle); - try - { - return _this.allocPgoInstrumentationBySchema(ftnHnd, pSchema, countSchemaItems, pInstrumentationData); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static void _recordCallSite(IntPtr thisHandle, IntPtr* ppException, uint instrOffset, CORINFO_SIG_INFO* callSig, CORINFO_METHOD_STRUCT_* methodHandle) - { - var _this = GetThis(thisHandle); - try - { - _this.recordCallSite(instrOffset, callSig, methodHandle); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static void _recordRelocation(IntPtr thisHandle, IntPtr* ppException, void* location, void* locationRW, void* target, ushort fRelocType, ushort slotNum, int addlDelta) - { - var _this = GetThis(thisHandle); - try - { - _this.recordRelocation(location, locationRW, target, fRelocType, slotNum, addlDelta); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - } - } - - [UnmanagedCallersOnly] - private static ushort _getRelocTypeHint(IntPtr thisHandle, IntPtr* ppException, void* target) - { - var _this = GetThis(thisHandle); - try - { - return _this.getRelocTypeHint(target); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getExpectedTargetArchitecture(IntPtr thisHandle, IntPtr* ppException) - { - var _this = GetThis(thisHandle); - try - { - return _this.getExpectedTargetArchitecture(); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - [UnmanagedCallersOnly] - private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_FLAGS* flags, uint sizeInBytes) - { - var _this = GetThis(thisHandle); - try - { - return _this.getJitFlags(ref *flags, sizeInBytes); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - - - private static IntPtr GetUnmanagedCallbacks() - { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 181); - - callbacks[0] = (delegate* unmanaged)&_isIntrinsic; - callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; - callbacks[2] = (delegate* unmanaged)&_setMethodAttribs; - callbacks[3] = (delegate* unmanaged)&_getMethodSig; - callbacks[4] = (delegate* unmanaged)&_getMethodInfo; - callbacks[5] = (delegate* unmanaged)&_canInline; - callbacks[6] = (delegate* unmanaged)&_beginInlining; - callbacks[7] = (delegate* unmanaged)&_reportInliningDecision; - callbacks[8] = (delegate* unmanaged)&_canTailCall; - callbacks[9] = (delegate* unmanaged)&_reportTailCallDecision; - callbacks[10] = (delegate* unmanaged)&_getEHinfo; - callbacks[11] = (delegate* unmanaged)&_getMethodClass; - callbacks[12] = (delegate* unmanaged)&_getMethodModule; - callbacks[13] = (delegate* unmanaged)&_getMethodVTableOffset; - callbacks[14] = (delegate* unmanaged)&_resolveVirtualMethod; - callbacks[15] = (delegate* unmanaged)&_getUnboxedEntry; - callbacks[16] = (delegate* unmanaged)&_getDefaultComparerClass; - callbacks[17] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; - callbacks[18] = (delegate* unmanaged)&_expandRawHandleIntrinsic; - callbacks[19] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[20] = (delegate* unmanaged)&_getUnmanagedCallConv; - callbacks[21] = (delegate* unmanaged)&_pInvokeMarshalingRequired; - callbacks[22] = (delegate* unmanaged)&_satisfiesMethodConstraints; - callbacks[23] = (delegate* unmanaged)&_isCompatibleDelegate; - callbacks[24] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; - callbacks[25] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; - callbacks[26] = (delegate* unmanaged)&_getGSCookie; - callbacks[27] = (delegate* unmanaged)&_setPatchpointInfo; - callbacks[28] = (delegate* unmanaged)&_getOSRInfo; - callbacks[29] = (delegate* unmanaged)&_resolveToken; - callbacks[30] = (delegate* unmanaged)&_tryResolveToken; - callbacks[31] = (delegate* unmanaged)&_findSig; - callbacks[32] = (delegate* unmanaged)&_findCallSiteSig; - callbacks[33] = (delegate* unmanaged)&_getTokenTypeAsHandle; - callbacks[34] = (delegate* unmanaged)&_isValidToken; - callbacks[35] = (delegate* unmanaged)&_isValidStringRef; - callbacks[36] = (delegate* unmanaged)&_getStringLiteral; - callbacks[37] = (delegate* unmanaged)&_printObjectDescription; - callbacks[38] = (delegate* unmanaged)&_asCorInfoType; - callbacks[39] = (delegate* unmanaged)&_getClassName; - callbacks[40] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[41] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[42] = (delegate* unmanaged)&_appendClassName; - callbacks[43] = (delegate* unmanaged)&_isValueClass; - callbacks[44] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[45] = (delegate* unmanaged)&_getClassAttribs; - callbacks[46] = (delegate* unmanaged)&_getClassModule; - callbacks[47] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[48] = (delegate* unmanaged)&_getAssemblyName; - callbacks[49] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[50] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[51] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[52] = (delegate* unmanaged)&_getClassSize; - callbacks[53] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[54] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[55] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[56] = (delegate* unmanaged)&_getClassGClayout; - callbacks[57] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[58] = (delegate* unmanaged)&_getFieldInClass; - callbacks[59] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[60] = (delegate* unmanaged)&_getNewHelper; - callbacks[61] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[62] = (delegate* unmanaged)&_getCastingHelper; - callbacks[63] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[64] = (delegate* unmanaged)&_getTypeForBox; - callbacks[65] = (delegate* unmanaged)&_getBoxHelper; - callbacks[66] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[67] = (delegate* unmanaged)&_getRuntimeTypePointer; - callbacks[68] = (delegate* unmanaged)&_isObjectImmutable; - callbacks[69] = (delegate* unmanaged)&_getObjectType; - callbacks[70] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[71] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[72] = (delegate* unmanaged)&_getHelperName; - callbacks[73] = (delegate* unmanaged)&_initClass; - callbacks[74] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[75] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[76] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[77] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[78] = (delegate* unmanaged)&_canCast; - callbacks[79] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[80] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[82] = (delegate* unmanaged)&_mergeClasses; - callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; -<<<<<<< HEAD - callbacks[84] = (delegate* unmanaged)&_isEnum; - callbacks[85] = (delegate* unmanaged)&_getParentType; - callbacks[86] = (delegate* unmanaged)&_getChildType; - callbacks[87] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[88] = (delegate* unmanaged)&_isSDArray; - callbacks[89] = (delegate* unmanaged)&_getArrayRank; - callbacks[90] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[91] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[92] = (delegate* unmanaged)&_canAccessClass; - callbacks[93] = (delegate* unmanaged)&_getFieldName; - callbacks[94] = (delegate* unmanaged)&_getFieldClass; - callbacks[95] = (delegate* unmanaged)&_getFieldType; - callbacks[96] = (delegate* unmanaged)&_getFieldOffset; - callbacks[97] = (delegate* unmanaged)&_getFieldInfo; - callbacks[98] = (delegate* unmanaged)&_isFieldStatic; -======= - callbacks[84] = (delegate* unmanaged)&_getParentType; - callbacks[85] = (delegate* unmanaged)&_getChildType; - callbacks[86] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[87] = (delegate* unmanaged)&_isSDArray; - callbacks[88] = (delegate* unmanaged)&_getArrayRank; - callbacks[89] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[90] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[91] = (delegate* unmanaged)&_canAccessClass; - callbacks[92] = (delegate* unmanaged)&_getFieldName; - callbacks[93] = (delegate* unmanaged)&_getFieldClass; - callbacks[94] = (delegate* unmanaged)&_getFieldType; - callbacks[95] = (delegate* unmanaged)&_getFieldOffset; - callbacks[96] = (delegate* unmanaged)&_getFieldInfo; - callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; ->>>>>>> original/main - callbacks[99] = (delegate* unmanaged)&_getBoundaries; - callbacks[100] = (delegate* unmanaged)&_setBoundaries; - callbacks[101] = (delegate* unmanaged)&_getVars; - callbacks[102] = (delegate* unmanaged)&_setVars; - callbacks[103] = (delegate* unmanaged)&_reportRichMappings; - callbacks[104] = (delegate* unmanaged)&_allocateArray; - callbacks[105] = (delegate* unmanaged)&_freeArray; - callbacks[106] = (delegate* unmanaged)&_getArgNext; - callbacks[107] = (delegate* unmanaged)&_getArgType; - callbacks[108] = (delegate* unmanaged)&_getExactClasses; - callbacks[109] = (delegate* unmanaged)&_getArgClass; - callbacks[110] = (delegate* unmanaged)&_getHFAType; - callbacks[111] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[112] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[113] = (delegate* unmanaged)&_FilterException; - callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[116] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[117] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[118] = (delegate* unmanaged)&_getEEInfo; - callbacks[119] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[120] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[121] = (delegate* unmanaged)&_getMethodName; - callbacks[122] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[123] = (delegate* unmanaged)&_getMethodHash; - callbacks[124] = (delegate* unmanaged)&_findNameOfToken; - callbacks[125] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[126] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[127] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[128] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[129] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[130] = (delegate* unmanaged)&_getHelperFtn; - callbacks[131] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[132] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[133] = (delegate* unmanaged)&_getMethodSync; - callbacks[134] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[135] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[136] = (delegate* unmanaged)&_embedClassHandle; - callbacks[137] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[138] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[139] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[140] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[141] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[142] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[146] = (delegate* unmanaged)&_getCallInfo; - callbacks[147] = (delegate* unmanaged)&_canAccessFamily; - callbacks[148] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[149] = (delegate* unmanaged)&_getClassDomainID; - callbacks[150] = (delegate* unmanaged)&_getFieldAddress; -<<<<<<< HEAD - callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; -======= - callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; ->>>>>>> original/main - callbacks[152] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[153] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[154] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[155] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[156] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[157] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[158] = (delegate* unmanaged)&_addActiveDependency; - callbacks[159] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[160] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[161] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[162] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[163] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[164] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[165] = (delegate* unmanaged)&_allocMem; - callbacks[166] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[167] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[168] = (delegate* unmanaged)&_allocGCInfo; - callbacks[169] = (delegate* unmanaged)&_setEHcount; - callbacks[170] = (delegate* unmanaged)&_setEHinfo; - callbacks[171] = (delegate* unmanaged)&_logMsg; - callbacks[172] = (delegate* unmanaged)&_doAssert; - callbacks[173] = (delegate* unmanaged)&_reportFatalError; - callbacks[174] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[175] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[176] = (delegate* unmanaged)&_recordCallSite; - callbacks[177] = (delegate* unmanaged)&_recordRelocation; - callbacks[178] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[179] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[180] = (delegate* unmanaged)&_getJitFlags; - - return (IntPtr)callbacks; - } - } -} diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h.orig b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h.orig deleted file mode 100644 index fcf30c2d4ab33..0000000000000 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h.orig +++ /dev/null @@ -1,1169 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -//---------------------------------------------------------- -// MethodContext.h - Primary structure to store all the EE-JIT details required to replay creation of a method -// CompileResult contains the stuff generated by a compilation -//---------------------------------------------------------- -#ifndef _MethodContext -#define _MethodContext - -#include "runtimedetails.h" -#include "compileresult.h" -#include "lightweightmap.h" -#include "errorhandling.h" -#include "hash.h" -#include "agnostic.h" - -extern bool g_debugRec; -extern bool g_debugRep; - -#if 0 -// Enable these to get verbose logging during record or playback. -#define DEBUG_REC(x) \ - if (g_debugRec) { \ - printf("rec"); \ - x; \ - printf("\n"); \ - } - -#define DEBUG_REP(x) \ - if (g_debugRep) { \ - printf("rep"); \ - x; \ - printf("\n"); \ - } -#else -#define DEBUG_REC(x) -#define DEBUG_REP(x) -#endif - -// Helper function for dumping. -const char* toString(CorInfoType cit); - -#define METHOD_IDENTITY_INFO_SIZE 0x10000 // We assume that the METHOD_IDENTITY_INFO_SIZE will not exceed 64KB -#define METHOD_IDENTITY_INFO_NON_NAME_RESERVE 0x400 // Reserve 1KB of METHOD_IDENTITY_INFO_SIZE for everything except for the method name. - -// Special "jit flags" for noting some method context features - -enum EXTRA_JIT_FLAGS -{ - HAS_PGO = 63, - HAS_EDGE_PROFILE = 62, - HAS_CLASS_PROFILE = 61, - HAS_LIKELY_CLASS = 60, - HAS_STATIC_PROFILE = 59, - HAS_DYNAMIC_PROFILE = 58, - HAS_METHOD_PROFILE = 57, - HAS_LIKELY_METHOD = 56, -}; - -// Asserts to catch changes in corjit flags definitions. - -static_assert((int)EXTRA_JIT_FLAGS::HAS_PGO == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED36, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_EDGE_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED35, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_CLASS_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED34, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_LIKELY_CLASS == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED33, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_STATIC_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED32, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_DYNAMIC_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED31, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_METHOD_PROFILE == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED30, "Jit Flags Mismatch"); -static_assert((int)EXTRA_JIT_FLAGS::HAS_LIKELY_METHOD == (int)CORJIT_FLAGS::CorJitFlag::CORJIT_FLAG_UNUSED29, "Jit Flags Mismatch"); - -class MethodContext -{ - friend class CompileResult; - -public: - MethodContext(); - -private: - void MethodInitHelper(unsigned char* buff, unsigned int totalLen); - void MethodInitHelperFile(HANDLE hFile); - - bool Initialize(int mcIndex, unsigned char* buff, DWORD size); - bool Initialize(int mcIndex, HANDLE hFile); - - int dumpMD5HashToBuffer(BYTE* pBuffer, int bufLen, char* buff, int len); - -public: - static bool Initialize(int mcIndex, unsigned char* buff, DWORD size, /* OUT */ MethodContext** ppmc); - static bool Initialize(int mcIndex, HANDLE hFile, /* OUT */ MethodContext** ppmc); - ~MethodContext(); - void Destroy(); - - void setIgnoreStoredConfig() - { - ignoreStoredConfig = true; - } - - bool Equal(MethodContext* other); - unsigned int saveToFile(HANDLE hFile); - unsigned int calculateFileSize(); - unsigned int calculateRawFileSize(); - - // dumpToConsole: If mcNumber is not -1, display the method context number before the dumped info. - // If simple is `true`, don't display the function name/arguments in the header. - void dumpToConsole(int mcNumber = -1, bool simple = false); - - int dumpStatToBuffer(char* buff, int len); - static int dumpStatTitleToBuffer(char* buff, int len); - int methodSize; - - int dumpMethodIdentityInfoToBuffer(char* buff, int len, bool ignoreMethodName = false, CORINFO_METHOD_INFO* optInfo = nullptr, unsigned optFlags = 0); - int dumpMethodMD5HashToBuffer(char* buff, int len, bool ignoreMethodName = false, CORINFO_METHOD_INFO* optInfo = nullptr, unsigned optFlags = 0); - - bool hasPgoData(bool& hasEdgeProfile, bool& hasClassProfile, bool& hasMethodProfile, bool& hasLikelyClass, bool& hasLikelyMethod, ICorJitInfo::PgoSource& pgoSource); - - void recGlobalContext(const MethodContext& other); - - void recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags, CORINFO_OS os); - void dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value); - void repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags, CORINFO_OS* os); - - void recGetMethodClass(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle); - void dmpGetMethodClass(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetMethodClass(CORINFO_METHOD_HANDLE methodHandle); - - void recGetMethodModule(CORINFO_METHOD_HANDLE methodHandle, CORINFO_MODULE_HANDLE moduleHandle); - void dmpGetMethodModule(DWORDLONG key, DWORDLONG value); - CORINFO_MODULE_HANDLE repGetMethodModule(CORINFO_METHOD_HANDLE methodHandle); - - void recGetClassAttribs(CORINFO_CLASS_HANDLE classHandle, DWORD attribs); - void dmpGetClassAttribs(DWORDLONG key, DWORD value); - DWORD repGetClassAttribs(CORINFO_CLASS_HANDLE classHandle); - - void recIsIntrinsic(CORINFO_METHOD_HANDLE ftn, bool result); - void dmpIsIntrinsic(DWORDLONG key, DWORD value); - bool repIsIntrinsic(CORINFO_METHOD_HANDLE ftn); - - void recGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle, DWORD attribs); - void dmpGetMethodAttribs(DWORDLONG key, DWORD value); - DWORD repGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle); - - void recGetClassModule(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE mod); - void dmpGetClassModule(DWORDLONG key, DWORDLONG value); - CORINFO_MODULE_HANDLE repGetClassModule(CORINFO_CLASS_HANDLE cls); - - void recGetModuleAssembly(CORINFO_MODULE_HANDLE mod, CORINFO_ASSEMBLY_HANDLE assem); - void dmpGetModuleAssembly(DWORDLONG key, DWORDLONG value); - CORINFO_ASSEMBLY_HANDLE repGetModuleAssembly(CORINFO_MODULE_HANDLE mod); - - void recGetAssemblyName(CORINFO_ASSEMBLY_HANDLE assem, const char* assemblyName); - void dmpGetAssemblyName(DWORDLONG key, DWORD value); - const char* repGetAssemblyName(CORINFO_ASSEMBLY_HANDLE assem); - - void recGetVars(CORINFO_METHOD_HANDLE ftn, ULONG32* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers); - void dmpGetVars(DWORDLONG key, const Agnostic_GetVars& value); - void repGetVars(CORINFO_METHOD_HANDLE ftn, ULONG32* cVars, ICorDebugInfo::ILVarInfo** vars, bool* extendOthers); - - void recGetBoundaries(CORINFO_METHOD_HANDLE ftn, - unsigned int* cILOffsets, - uint32_t** pILOffsets, - ICorDebugInfo::BoundaryTypes* implicitBoundaries); - void dmpGetBoundaries(DWORDLONG key, const Agnostic_GetBoundaries& value); - void repGetBoundaries(CORINFO_METHOD_HANDLE ftn, - unsigned int* cILOffsets, - uint32_t** pILOffsets, - ICorDebugInfo::BoundaryTypes* implicitBoundaries); - - void recInitClass(CORINFO_FIELD_HANDLE field, - CORINFO_METHOD_HANDLE method, - CORINFO_CONTEXT_HANDLE context, - CorInfoInitClassResult result); - void dmpInitClass(const Agnostic_InitClass& key, DWORD value); - CorInfoInitClassResult repInitClass(CORINFO_FIELD_HANDLE field, - CORINFO_METHOD_HANDLE method, - CORINFO_CONTEXT_HANDLE context); - - void recGetMethodName(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName); - void dmpGetMethodName(DLD key, DD value); - const char* repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName); - - void recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, - char* methodname, - const char** moduleName, - const char** namespaceName, - const char** enclosingClassName); - void dmpGetMethodNameFromMetadata(Agnostic_CORINFO_METHODNAME_TOKENin key, Agnostic_CORINFO_METHODNAME_TOKENout value); - const char* repGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, - const char** className, - const char** namespaceName, - const char** enclosingClassName); - - void recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DWORD result); - void dmpGetJitFlags(DWORD key, DD value); - DWORD repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes); - - void recGetJitTimeLogFilename(LPCWSTR tempFileName); - void dmpGetJitTimeLogFilename(DWORD key, DWORD value); - LPCWSTR repGetJitTimeLogFilename(); - - void recCanInline(CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - CorInfoInline response, - DWORD exceptionCode); - void dmpCanInline(DLDL key, const Agnostic_CanInline& value); - CorInfoInline repCanInline(CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - DWORD* exceptionCode); - - void recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode); - void dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const ResolveTokenValue& value); - void repResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD* exceptionCode); - - void recTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool success); - void dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const TryResolveTokenValue& value); - bool repTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken); - - void recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_CALLINFO_FLAGS flags, - CORINFO_CALL_INFO* pResult, - DWORD exceptionCode); - void dmpGetCallInfo(const Agnostic_GetCallInfo& key, const Agnostic_CORINFO_CALL_INFO& value); - void repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_CALLINFO_FLAGS flags, - CORINFO_CALL_INFO* pResult, - DWORD* exceptionCode); - void repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CALL_INFO* pResult); - - void recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result); - void dmpAsCorInfoType(DWORDLONG key, DWORD value); - CorInfoType repAsCorInfoType(CORINFO_CLASS_HANDLE cls); - - void recIsValueClass(CORINFO_CLASS_HANDLE cls, bool result); - void dmpIsValueClass(DWORDLONG key, DWORD value); - bool repIsValueClass(CORINFO_CLASS_HANDLE cls); - - void recGetClassSize(CORINFO_CLASS_HANDLE cls, unsigned result); - void dmpGetClassSize(DWORDLONG key, DWORD val); - unsigned repGetClassSize(CORINFO_CLASS_HANDLE cls); - - void recGetHeapClassSize(CORINFO_CLASS_HANDLE cls, unsigned result); - void dmpGetHeapClassSize(DWORDLONG key, DWORD val); - unsigned repGetHeapClassSize(CORINFO_CLASS_HANDLE cls); - - void recCanAllocateOnStack(CORINFO_CLASS_HANDLE cls, bool result); - void dmpCanAllocateOnStack(DWORDLONG key, DWORD val); - bool repCanAllocateOnStack(CORINFO_CLASS_HANDLE cls); - - void recGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls, unsigned result); - void dmpGetClassNumInstanceFields(DWORDLONG key, DWORD value); - unsigned repGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls); - - void recGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls, CorInfoHelpFunc result); - void dmpGetNewArrHelper(DWORDLONG key, DWORD value); - CorInfoHelpFunc repGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls); - - void recGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd, CorInfoHelpFunc result); - void dmpGetSharedCCtorHelper(DWORDLONG key, DWORD value); - CorInfoHelpFunc repGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd); - - void recGetTypeForBox(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); - void dmpGetTypeForBox(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetTypeForBox(CORINFO_CLASS_HANDLE cls); - - void recGetBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result); - void dmpGetBoxHelper(DWORDLONG key, DWORD value); - CorInfoHelpFunc repGetBoxHelper(CORINFO_CLASS_HANDLE cls); - - void recGetBuiltinClass(CorInfoClassId classId, CORINFO_CLASS_HANDLE result); - void dmpGetBuiltinClass(DWORD key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetBuiltinClass(CorInfoClassId classId); - - void recGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls, CorInfoType result); - void dmpGetTypeForPrimitiveValueClass(DWORDLONG key, DWORD value); - CorInfoType repGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls); - - void recGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls, CorInfoType result); - void dmpGetTypeForPrimitiveNumericClass(DWORDLONG key, DWORD value); - CorInfoType repGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls); - - void recGetParentType(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); - void dmpGetParentType(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetParentType(CORINFO_CLASS_HANDLE cls); - - void recIsSDArray(CORINFO_CLASS_HANDLE cls, bool result); - void dmpIsSDArray(DWORDLONG key, DWORD value); - bool repIsSDArray(CORINFO_CLASS_HANDLE cls); - - void recExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult); - void dmpExpandRawHandleIntrinsic(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const Agnostic_CORINFO_GENERICHANDLE_RESULT& result); - void repExpandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_GENERICHANDLE_RESULT* pResult); - - void recIsIntrinsicType(CORINFO_CLASS_HANDLE cls, bool result); - void dmpIsIntrinsicType(DWORDLONG key, DWORD value); - bool repIsIntrinsicType(CORINFO_CLASS_HANDLE cls); - - void recGetFieldClass(CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE result); - void dmpGetFieldClass(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetFieldClass(CORINFO_FIELD_HANDLE field); - - void recGetFieldOffset(CORINFO_FIELD_HANDLE field, unsigned result); - void dmpGetFieldOffset(DWORDLONG key, DWORD value); - unsigned repGetFieldOffset(CORINFO_FIELD_HANDLE field); - - void recGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle, CorInfoHelpFunc result); - void dmpGetLazyStringLiteralHelper(DWORDLONG key, DWORD value); - CorInfoHelpFunc repGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle); - - void recGetUnBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result); - void dmpGetUnBoxHelper(DWORDLONG key, DWORD value); - CorInfoHelpFunc repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls); - - void recGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls, CORINFO_OBJECT_HANDLE result); - void dmpGetRuntimeTypePointer(DWORDLONG key, DWORDLONG value); - CORINFO_OBJECT_HANDLE repGetRuntimeTypePointer(CORINFO_CLASS_HANDLE cls); - - void recIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr, bool result); - void dmpIsObjectImmutable(DWORDLONG key, DWORD value); - bool repIsObjectImmutable(CORINFO_OBJECT_HANDLE objPtr); - - void recGetObjectType(CORINFO_OBJECT_HANDLE objPtr, CORINFO_CLASS_HANDLE result); - void dmpGetObjectType(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetObjectType(CORINFO_OBJECT_HANDLE objPtr); - - void recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_LOOKUP_KIND* pGenericLookupKind, - CorInfoHelpFunc id, - CORINFO_CONST_LOOKUP* pLookup, - bool result); - void dmpGetReadyToRunHelper(GetReadyToRunHelper_TOKENin key, GetReadyToRunHelper_TOKENout value); - bool repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_LOOKUP_KIND* pGenericLookupKind, - CorInfoHelpFunc id, - CORINFO_CONST_LOOKUP* pLookup); - - void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, - mdToken targetConstraint, - CORINFO_CLASS_HANDLE delegateType, - CORINFO_LOOKUP* pLookup); - void dmpGetReadyToRunDelegateCtorHelper(GetReadyToRunDelegateCtorHelper_TOKENIn key, - Agnostic_CORINFO_LOOKUP pLookup); - void repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, - mdToken targetConstraint, - CORINFO_CLASS_HANDLE delegateType, - CORINFO_LOOKUP* pLookup); - - void recGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection, void* result); - void dmpGetHelperFtn(DWORD key, DLDL value); - void* repGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection); - bool fndGetHelperFtn(void* functionAddress, CorInfoHelpFunc* pResult); - - void recGetJustMyCodeHandle(CORINFO_METHOD_HANDLE method, - CORINFO_JUST_MY_CODE_HANDLE** ppIndirection, - CORINFO_JUST_MY_CODE_HANDLE result); - void dmpGetJustMyCodeHandle(DWORDLONG key, DLDL value); - CORINFO_JUST_MY_CODE_HANDLE repGetJustMyCodeHandle(CORINFO_METHOD_HANDLE method, - CORINFO_JUST_MY_CODE_HANDLE** ppIndirection); - - void recGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, - CORINFO_CONST_LOOKUP* pResult, - CORINFO_ACCESS_FLAGS accessFlags); - void dmpGetFunctionEntryPoint(DLD key, DLD value); - void repGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, - CORINFO_CONST_LOOKUP* pResult, - CORINFO_ACCESS_FLAGS accessFlags); - bool fndGetFunctionEntryPoint(DLD value, CORINFO_METHOD_HANDLE* pResult); - - void recConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void* ppValue, InfoAccessType result); - void dmpConstructStringLiteral(DLD key, DLD value); - InfoAccessType repConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue); - - void recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert, bool result); - void dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value); - bool repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert); - - void recEmptyStringLiteral(void** ppValue, InfoAccessType result); - void dmpEmptyStringLiteral(DWORD key, DLD value); - InfoAccessType repEmptyStringLiteral(void** ppValue); - - void recGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - CorInfoTypeWithMod result, - DWORD exception); - void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value); - CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - DWORD* exception); - - void recGetExactClasses(CORINFO_CLASS_HANDLE baseType, - int maxExactClasses, - CORINFO_CLASS_HANDLE* exactClsRet, - int result); - void dmpGetExactClasses(DLD key, DLD value); - int repGetExactClasses(CORINFO_CLASS_HANDLE baseType, - int maxExactClasses, - CORINFO_CLASS_HANDLE* exactClsRet); - - void recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result); - void dmpGetArgNext(DWORDLONG key, DWORDLONG value); - CORINFO_ARG_LIST_HANDLE repGetArgNext(CORINFO_ARG_LIST_HANDLE args); - - void recGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent); - void dmpGetMethodSig(DLDL key, const Agnostic_CORINFO_SIG_INFO& value); - void repGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent); - - void recGetArgClass(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE result, - DWORD exceptionCode); - void dmpGetArgClass(const Agnostic_GetArgClass_Key& key, const Agnostic_GetArgClass_Value& value); - CORINFO_CLASS_HANDLE repGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, DWORD* exceptionCode); - - void recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoHFAElemType result); - void dmpGetHFAType(DWORDLONG key, DWORD value); - CorInfoHFAElemType repGetHFAType(CORINFO_CLASS_HANDLE clsHnd); - - void recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, bool result, DWORD exceptionCode); - void dmpGetMethodInfo(DWORDLONG key, const Agnostic_GetMethodInfo& value); - bool repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, DWORD* exceptionCode); - - void recGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - bool* pHasSideEffects, - CorInfoHelpFunc result); - void dmpGetNewHelper(const Agnostic_GetNewHelper& key, DD value); - CorInfoHelpFunc repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, bool * pHasSideEffects); - - void recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, - bool fEmbedParent, - CORINFO_GENERICHANDLE_RESULT* pResult); - void dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& key, - const Agnostic_CORINFO_GENERICHANDLE_RESULT& value); - void repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, - bool fEmbedParent, - CORINFO_GENERICHANDLE_RESULT* pResult); - - void recGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause); - void dmpGetEHinfo(DLD key, const Agnostic_CORINFO_EH_CLAUSE& value); - void repGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause); - - void recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, - unsigned* offsetOfIndirection, - unsigned* offsetAfterIndirection, - bool* isRelative); - void dmpGetMethodVTableOffset(DWORDLONG key, DDD value); - void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, - unsigned* offsetOfIndirection, - unsigned* offsetAfterIndirection, - bool* isRelative); - - void recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info, bool returnValue); - void dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethodKey& key, const Agnostic_ResolveVirtualMethodResult& value); - bool repResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info); - - void recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg, CORINFO_METHOD_HANDLE result); - void dmpGetUnboxedEntry(DWORDLONG key, DLD value); - CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); - - void recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); - void dmpGetDefaultComparerClass(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls); - - void recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); - void dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls); - - void recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CLASS_HANDLE result); - void dmpGetTokenTypeAsHandle(const GetTokenTypeAsHandleValue& key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken); - - void recGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_ACCESS_FLAGS flags, - CORINFO_FIELD_INFO* pResult); - void dmpGetFieldInfo(const Agnostic_GetFieldInfo& key, const Agnostic_CORINFO_FIELD_INFO& value); - void repGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_ACCESS_FLAGS flags, - CORINFO_FIELD_INFO* pResult); - - void recEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection, CORINFO_METHOD_HANDLE result); - void dmpEmbedMethodHandle(DWORDLONG key, DLDL value); - CORINFO_METHOD_HANDLE repEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection); - - void recGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection, void* result, CorInfoType cit); - void dmpGetFieldAddress(DWORDLONG key, const Agnostic_GetFieldAddress& value); - void* repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection); - - void recGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects, bool result); - void dmpGetReadonlyStaticFieldValue(DLDD key, DD value); - bool repGetReadonlyStaticFieldValue(CORINFO_FIELD_HANDLE field, uint8_t* buffer, int bufferSize, bool ignoreMovableObjects); - - void recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool isSpeculative, CORINFO_CLASS_HANDLE result); - void dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value); - CORINFO_CLASS_HANDLE repGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative); - - void recGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs, unsigned len, unsigned result); - void dmpGetClassGClayout(DWORDLONG key, const Agnostic_GetClassGClayout& value); - unsigned repGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs); - - void recGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, bool fDoubleAlignHint, unsigned result); - void dmpGetClassAlignmentRequirement(DLD key, DWORD value); - unsigned repGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, bool fDoubleAlignHint); - - void recCanAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_HELPER_DESC* pAccessHelper, - CorInfoIsAccessAllowedResult result); - void dmpCanAccessClass(const Agnostic_CanAccessClassIn& key, const Agnostic_CanAccessClassOut& value); - CorInfoIsAccessAllowedResult repCanAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_HELPER_DESC* pAccessHelper); - - void recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result); - void dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value); - CorInfoHelpFunc repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing); - - void recEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection, CORINFO_MODULE_HANDLE result); - void dmpEmbedModuleHandle(DWORDLONG key, DLDL value); - CORINFO_MODULE_HANDLE repEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection); - - void recEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection, CORINFO_CLASS_HANDLE result); - void dmpEmbedClassHandle(DWORDLONG key, DLDL value); - CORINFO_CLASS_HANDLE repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection); - - void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result); - void dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value); - bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); - - void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result, bool suppressGCTransitionResult); - void dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value); - CorInfoCallConvExtension repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); - - void recFindSig(CORINFO_MODULE_HANDLE module, - unsigned sigTOK, - CORINFO_CONTEXT_HANDLE context, - CORINFO_SIG_INFO* sig); - void dmpFindSig(const Agnostic_FindSig& key, const Agnostic_CORINFO_SIG_INFO& value); - void repFindSig(CORINFO_MODULE_HANDLE module, - unsigned sigTOK, - CORINFO_CONTEXT_HANDLE context, - CORINFO_SIG_INFO* sig); - - void recGetEEInfo(CORINFO_EE_INFO* pEEInfoOut); - void dmpGetEEInfo(DWORD key, const Agnostic_CORINFO_EE_INFO& value); - void repGetEEInfo(CORINFO_EE_INFO* pEEInfoOut); - - void recGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal); - void dmpGetGSCookie(DWORD key, DLDL value); - void repGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal); - - void recGetOSRInfo(PatchpointInfo* patchpointInfo, unsigned* ilOffset); - void dmpGetOSRInfo(DWORD key, const Agnostic_GetOSRInfo& value); - PatchpointInfo* repGetOSRInfo(unsigned* ilOffset); - - void recGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, - CORINFO_MODULE_HANDLE* pModule, - void** ppIndirection, - size_t result); - void dmpGetClassModuleIdForStatics(DWORDLONG key, const Agnostic_GetClassModuleIdForStatics& value); - size_t repGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, - CORINFO_MODULE_HANDLE* pModule, - void** ppIndirection); - - void recGetThreadTLSIndex(void** ppIndirection, DWORD result); - void dmpGetThreadTLSIndex(DWORD key, DLD value); - DWORD repGetThreadTLSIndex(void** ppIndirection); - - void recGetInlinedCallFrameVptr(void** ppIndirection, const void* result); - void dmpGetInlinedCallFrameVptr(DWORD key, DLDL value); - const void* repGetInlinedCallFrameVptr(void** ppIndirection); - - void recGetAddrOfCaptureThreadGlobal(void** ppIndirection, int32_t* result); - void dmpGetAddrOfCaptureThreadGlobal(DWORD key, DLDL value); - int32_t* repGetAddrOfCaptureThreadGlobal(void** ppIndirection); - - void recGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection, unsigned result); - void dmpGetClassDomainID(DWORDLONG key, DLD value); - unsigned repGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection); - - void recGetLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* result); - void dmpGetLocationOfThisType(DWORDLONG key, const Agnostic_CORINFO_LOOKUP_KIND& value); - void repGetLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* pLookupKind); - - void recGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd, - CORINFO_CLASS_HANDLE clsHnd, - CORINFO_METHOD_HANDLE targetMethodHnd, - DelegateCtorArgs* pCtorData, - CORINFO_METHOD_HANDLE result); - void dmpGetDelegateCtor(const Agnostic_GetDelegateCtorIn& key, const Agnostic_GetDelegateCtorOut& value); - CORINFO_METHOD_HANDLE repGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd, - CORINFO_CLASS_HANDLE clsHnd, - CORINFO_METHOD_HANDLE targetMethodHnd, - DelegateCtorArgs* pCtorData); - - void recGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult); - void dmpGetFunctionFixedEntryPoint(DWORDLONG key, const Agnostic_CORINFO_CONST_LOOKUP& value); - void repGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult); - - void recGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num, CORINFO_FIELD_HANDLE result); - void dmpGetFieldInClass(DLD key, DWORDLONG value); - CORINFO_FIELD_HANDLE repGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num); - - void recGetFieldType(CORINFO_FIELD_HANDLE field, - CORINFO_CLASS_HANDLE* structType, - CORINFO_CLASS_HANDLE memberParent, - CorInfoType result); - void dmpGetFieldType(DLDL key, DLD value); - CorInfoType repGetFieldType(CORINFO_FIELD_HANDLE field, - CORINFO_CLASS_HANDLE* structType, - CORINFO_CLASS_HANDLE memberParent); - - void recGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName, const char* result); - void dmpGetFieldName(DWORDLONG key, DD value); - const char* repGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName); - - void recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, - CorInfoInlineTypeCheckSource source, - CorInfoInlineTypeCheck result); - void dmpCanInlineTypeCheck(DLD key, DWORD value); - CorInfoInlineTypeCheck repCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, CorInfoInlineTypeCheckSource source); - - void recSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method, bool result); - void dmpSatisfiesMethodConstraints(DLDL key, DWORD value); - bool repSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method); - - void recIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result); - void dmpIsValidStringRef(DLD key, DWORD value); - bool repIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK); - - void recGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex, int length); - void dmpGetStringLiteral(DLDDD key, DD value); - int repGetStringLiteral(CORINFO_MODULE_HANDLE module, unsigned metaTOK, char16_t* buffer, int bufferSize, int startIndex); - - void recPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize, size_t bytesWritten); - void dmpPrintObjectDescription(DLDL key, Agnostic_PrintObjectDescriptionResult value); - size_t repPrintObjectDescription(CORINFO_OBJECT_HANDLE handle, char* buffer, size_t bufferSize, size_t* pRequiredBufferSize); - - void recGetHelperName(CorInfoHelpFunc funcNum, const char* result); - void dmpGetHelperName(DWORD key, DWORD value); - const char* repGetHelperName(CorInfoHelpFunc funcNum); - - void recCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent, bool result); - void dmpCanCast(DLDL key, DWORD value); - bool repCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent); - - void recGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet, CorInfoType result); - void dmpGetChildType(DWORDLONG key, DLD value); - CorInfoType repGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet); - - void recGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size, void* result); - void dmpGetArrayInitializationData(DLD key, DWORDLONG value); - void* repGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size); - - void recFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers, int result); - void dmpFilterException(DWORD key, DWORD value); - int repFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers); - - void recGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); - void dmpGetAddressOfPInvokeTarget(DWORDLONG key, DLD value); - void repGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup); - - void recSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls, bool result); - void dmpSatisfiesClassConstraints(DWORDLONG key, DWORD value); - bool repSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls); - - void recGetMethodHash(CORINFO_METHOD_HANDLE ftn, unsigned result); - void dmpGetMethodHash(DWORDLONG key, DWORD value); - unsigned repGetMethodHash(CORINFO_METHOD_HANDLE ftn); - - void recCanTailCall(CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE declaredCalleeHnd, - CORINFO_METHOD_HANDLE exactCalleeHnd, - bool fIsTailPrefix, - bool result); - void dmpCanTailCall(const Agnostic_CanTailCall& key, DWORD value); - bool repCanTailCall(CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE declaredCalleeHnd, - CORINFO_METHOD_HANDLE exactCalleeHnd, - bool fIsTailPrefix); - - void recIsCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, - CORINFO_CLASS_HANDLE methodParentCls, - CORINFO_METHOD_HANDLE method, - CORINFO_CLASS_HANDLE delegateCls, - bool* pfIsOpenDelegate, - bool result); - void dmpIsCompatibleDelegate(const Agnostic_IsCompatibleDelegate& key, DD value); - bool repIsCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, - CORINFO_CLASS_HANDLE methodParentCls, - CORINFO_METHOD_HANDLE method, - CORINFO_CLASS_HANDLE delegateCls, - bool* pfIsOpenDelegate); - - void recIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, CORINFO_METHOD_HANDLE calleeHnd, bool result); - void dmpIsDelegateCreationAllowed(DLDL key, DWORD value); - bool repIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, CORINFO_METHOD_HANDLE calleeHnd); - - void recFindCallSiteSig(CORINFO_MODULE_HANDLE module, - unsigned methTOK, - CORINFO_CONTEXT_HANDLE context, - CORINFO_SIG_INFO* sig); - void dmpFindCallSiteSig(const Agnostic_FindCallSiteSig& key, const Agnostic_CORINFO_SIG_INFO& value); - void repFindCallSiteSig(CORINFO_MODULE_HANDLE module, - unsigned methTOK, - CORINFO_CONTEXT_HANDLE context, - CORINFO_SIG_INFO* sig); - - void recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result); - void dmpGetMethodSync(DWORDLONG key, DLDL value); - void* repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection); - - void recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result); - void dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value); - CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection); - - void recCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig, bool result); - void dmpCanGetVarArgsHandle(const CanGetVarArgsHandleValue& key, DWORD value); - bool repCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig); - - void recGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection, DWORD result); - void dmpGetFieldThreadLocalStoreID(DWORDLONG key, DLD value); - DWORD repGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection); - - void recAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData, HRESULT result); - void dmpAllocPgoInstrumentationBySchema(DWORDLONG key, const Agnostic_AllocPgoInstrumentationBySchema& value); - HRESULT repAllocPgoInstrumentationBySchema(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema* pSchema, UINT32 countSchemaItems, BYTE** pInstrumentationData); - - void recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource, HRESULT result); - void dmpGetPgoInstrumentationResults(DWORDLONG key, const Agnostic_GetPgoInstrumentationResults& value); - HRESULT repGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd, ICorJitInfo::PgoInstrumentationSchema** pSchema, UINT32* pCountSchemaItems, BYTE** pInstrumentationData, ICorJitInfo::PgoSource* pPgoSource); - - void recMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, CORINFO_CLASS_HANDLE result); - void dmpMergeClasses(DLDL key, DWORDLONG value); - CORINFO_CLASS_HANDLE repMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - - void recIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result); - void dmpIsMoreSpecificType(DLDL key, DWORD value); - bool repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - - void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType, TypeCompareState result); - void dmpIsEnum(DWORDLONG key, DLD value); - TypeCompareState repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType); - - void recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result); - void dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value); - LPVOID repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection); - - void recCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, bool result); - void dmpCanGetCookieForPInvokeCalliSig(const CanGetCookieForPInvokeCalliSigValue& key, DWORD value); - bool repCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig); - - void recCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType, bool result); - void dmpCanAccessFamily(DLDL key, DWORD value); - bool repCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType); - - void recErrorList(const char* error); - void dmpErrorList(DWORD key, DWORD value); - - void recGetProfilingHandle(bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles); - void dmpGetProfilingHandle(DWORD key, const Agnostic_GetProfilingHandle& value); - void repGetProfilingHandle(bool* pbHookFunction, void** pProfilerHandle, bool* pbIndirectedHandles); - - void recEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection, CORINFO_FIELD_HANDLE result); - void dmpEmbedFieldHandle(DWORDLONG key, DLDL value); - CORINFO_FIELD_HANDLE repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection); - - void recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, bool result); - void dmpAreTypesEquivalent(DLDL key, DWORD value); - bool repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - - void recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass, TypeCompareState result); - void dmpCompareTypesForCast(DLDL key, DWORD value); - TypeCompareState repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass); - - void recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, TypeCompareState result); - void dmpCompareTypesForEquality(DLDL key, DWORD value); - TypeCompareState repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2); - - void recFindNameOfToken( - CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity, size_t result); - void dmpFindNameOfToken(DLD key, DLD value); - size_t repFindNameOfToken(CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity); - - void recGetSystemVAmd64PassStructInRegisterDescriptor( - CORINFO_CLASS_HANDLE structHnd, - SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr, - bool result); - void dmpGetSystemVAmd64PassStructInRegisterDescriptor( - DWORDLONG key, const Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor& value); - bool repGetSystemVAmd64PassStructInRegisterDescriptor( - CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); - - void recGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value); - void dmpGetLoongArch64PassStructInRegisterFlags(DWORDLONG key, DWORD value); - DWORD repGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd); - - void recGetRelocTypeHint(void* target, WORD result); - void dmpGetRelocTypeHint(DWORDLONG key, DWORD value); - WORD repGetRelocTypeHint(void* target); - - void recGetExpectedTargetArchitecture(DWORD result); - void dmpGetExpectedTargetArchitecture(DWORD key, DWORD result); - DWORD repGetExpectedTargetArchitecture(); - - void recDoesFieldBelongToClass(CORINFO_FIELD_HANDLE fld, CORINFO_CLASS_HANDLE cls, bool result); - void dmpDoesFieldBelongToClass(DLDL key, bool value); - bool repDoesFieldBelongToClass(CORINFO_FIELD_HANDLE fld, CORINFO_CLASS_HANDLE cls); - - void recIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result); - void dmpIsValidToken(DLD key, DWORD value); - bool repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK); - - void recGetClassName(CORINFO_CLASS_HANDLE cls, const char* result); - void dmpGetClassName(DWORDLONG key, DWORD value); - const char* repGetClassName(CORINFO_CLASS_HANDLE cls); - - void recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, char* className, const char** namespaceName); - void dmpGetClassNameFromMetadata(DLD key, DD value); - const char* repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName); - - void recGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index, CORINFO_CLASS_HANDLE result); - void dmpGetTypeInstantiationArgument(DLD key, DWORDLONG value); - CORINFO_CLASS_HANDLE repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index); - - void recAppendClassName(int nBufLenIn, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly, - int nLenOut, - const char16_t* result); - void dmpAppendClassName(const Agnostic_AppendClassNameIn& key, const Agnostic_AppendClassNameOut& value); - int repAppendClassName(char16_t** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - bool fNamespace, - bool fFullInst, - bool fAssembly); - - void recGetTailCallHelpers( - CORINFO_RESOLVED_TOKEN* callToken, - CORINFO_SIG_INFO* sig, - CORINFO_GET_TAILCALL_HELPERS_FLAGS flags, - CORINFO_TAILCALL_HELPERS* pResult); - void dmpGetTailCallHelpers(const Agnostic_GetTailCallHelpers& key, const Agnostic_CORINFO_TAILCALL_HELPERS& value); - bool repGetTailCallHelpers( - CORINFO_RESOLVED_TOKEN* callToken, - CORINFO_SIG_INFO* sig, - CORINFO_GET_TAILCALL_HELPERS_FLAGS flags, - CORINFO_TAILCALL_HELPERS* pResult); - - void recUpdateEntryPointForTailCall(const CORINFO_CONST_LOOKUP& origEntryPoint, const CORINFO_CONST_LOOKUP& newEntryPoint); - void dmpUpdateEntryPointForTailCall(const Agnostic_CORINFO_CONST_LOOKUP& origEntryPoint, const Agnostic_CORINFO_CONST_LOOKUP& newEntryPoint); - void repUpdateEntryPointForTailCall(CORINFO_CONST_LOOKUP* entryPoint); - - void recGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod, mdMethodDef result); - void dmpGetMethodDefFromMethod(DWORDLONG key, DWORD value); - mdMethodDef repGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod); - - void recCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, bool fOptional, bool result); - void dmpCheckMethodModifier(const Agnostic_CheckMethodModifier& key, DWORD value); - bool repCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, bool fOptional); - - void recGetArrayRank(CORINFO_CLASS_HANDLE cls, unsigned result); - void dmpGetArrayRank(DWORDLONG key, DWORD value); - unsigned repGetArrayRank(CORINFO_CLASS_HANDLE cls); - - void recGetArrayIntrinsicID(CORINFO_METHOD_HANDLE hMethod, CorInfoArrayIntrinsic result); - void dmpGetArrayIntrinsicID(DWORDLONG key, DWORD value); - CorInfoArrayIntrinsic repGetArrayIntrinsicID(CORINFO_METHOD_HANDLE hMethod); - - void recIsFieldStatic(CORINFO_FIELD_HANDLE fhld, bool result); - void dmpIsFieldStatic(DWORDLONG key, DWORD value); - bool repIsFieldStatic(CORINFO_FIELD_HANDLE fhld); - - void recGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd, int result); - void dmpGetArrayOrStringLength(DWORDLONG key, DWORD value); - int repGetArrayOrStringLength(CORINFO_OBJECT_HANDLE objHnd); - - void recGetIntConfigValue(const WCHAR* name, int defaultValue, int result); - void dmpGetIntConfigValue(const Agnostic_ConfigIntInfo& key, int value); - int repGetIntConfigValue(const WCHAR* name, int defaultValue); - - void recGetStringConfigValue(const WCHAR* name, const WCHAR* result); - void dmpGetStringConfigValue(DWORD nameIndex, DWORD result); - const WCHAR* repGetStringConfigValue(const WCHAR* name); - - void dmpSigInstHandleMap(DWORD key, DWORDLONG value); - - struct Environment - { - Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr) - { - } - - LightWeightMap* getIntConfigValue; - LightWeightMap* getStingConfigValue; - }; - - Environment cloneEnvironment(); - - bool WasEnvironmentChanged(const Environment& prevEnv); - - CompileResult* cr; - CompileResult* originalCR; - int index; - bool ignoreStoredConfig; - -private: - bool IsEnvironmentHeaderEqual(const Environment& prevEnv); - bool IsEnvironmentContentEqual(const Environment& prevEnv); - - template - static bool AreLWMHeadersEqual(LightWeightMap* prev, LightWeightMap* curr); - static bool IsIntConfigContentEqual(LightWeightMap* prev, - LightWeightMap* curr); - static bool IsStringContentEqual(LightWeightMap* prev, LightWeightMap* curr); - -#define LWM(map, key, value) LightWeightMap* map; -#define DENSELWM(map, value) DenseLightWeightMap* map; -#include "lwmlist.h" - - // MD5 hasher - static Hash m_hash; - - // Scheme for jit time temporary allocations - struct DeletionNode - { - DeletionNode* pNext; - }; - DeletionNode *nodesToDelete = nullptr; - - void* AllocJitTempBuffer(size_t size) - { - DeletionNode *pDeletionNode = (DeletionNode *)malloc(sizeof(DeletionNode) + size); - pDeletionNode->pNext = this->nodesToDelete; - this->nodesToDelete = pDeletionNode; - return pDeletionNode + 1; - } - - void FreeTempAllocations() - { - while (nodesToDelete != nullptr) - { - DeletionNode *next = nodesToDelete->pNext; - free(nodesToDelete); - nodesToDelete = next; - } - } -}; - -enum mcPackets -{ - Packet_AreTypesEquivalent = 1, - Packet_AsCorInfoType = 2, - Packet_CanAccessClass = 3, - Packet_CanAccessFamily = 4, - Packet_CanCast = 5, - Packet_CanGetCookieForPInvokeCalliSig = 7, - Packet_CanGetVarArgsHandle = 8, - Packet_CanInline = 9, - //Packet_CanInlineTypeCheckWithObjectVTable = 10, - //Packet_CanSkipMethodVerification = 11, - Packet_CanTailCall = 12, - //Retired4 = 13, - //Retired3 = 14, - Packet_ConstructStringLiteral = 15, - Packet_EmbedClassHandle = 16, - Packet_EmbedFieldHandle = 17, - Packet_EmbedGenericHandle = 18, - Packet_EmbedMethodHandle = 19, - Packet_EmbedModuleHandle = 20, - Packet_EmptyStringLiteral = 21, - Packet_ErrorList = 22, - Packet_FindCallSiteSig = 23, - //Retired7 = 24, - Packet_FindSig = 25, - Packet_GetAddressOfPInvokeFixup = 26, - Packet_GetAddrOfCaptureThreadGlobal = 27, - //Retired1 = 28, - Packet_GetArgNext = 29, - //Retired2 = 30, - Packet_GetArrayInitializationData = 31, - Packet_GetArrayRank = 32, - //Packet_GetMethodBlockCounts = 33, - Packet_GetBoundaries = 34, - Packet_GetBoxHelper = 35, - Packet_GetBuiltinClass = 36, - Packet_GetCallInfo = 37, - Packet_GetCastingHelper = 38, - Packet_GetChildType = 39, - Packet_GetClassAlignmentRequirement = 40, - Packet_GetClassAttribs = 41, - Packet_GetClassDomainID = 42, - Packet_GetClassGClayout = 43, - Packet_GetClassModuleIdForStatics = 44, - Packet_GetClassName = 45, - Packet_GetClassNumInstanceFields = 46, - Packet_GetClassSize = 47, - Packet_GetCookieForPInvokeCalliSig = 48, - Packet_GetDelegateCtor = 49, - Packet_GetEEInfo = 50, - Packet_GetEHinfo = 51, - Packet_GetFieldAddress = 52, - Packet_GetFieldClass = 53, - Packet_GetFieldInClass = 54, - Packet_GetFieldInfo = 55, - Packet_GetFieldName = 56, - Packet_GetFieldOffset = 57, - Packet_GetFieldThreadLocalStoreID = 58, - Packet_GetFieldType = 59, - Packet_GetFunctionEntryPoint = 60, - Packet_GetFunctionFixedEntryPoint = 61, - Packet_GetGSCookie = 62, - Packet_GetHelperFtn = 63, - Packet_GetHelperName = 64, - Packet_GetInlinedCallFrameVptr = 65, - Packet_GetArrayIntrinsicID = 66, - Packet_GetJitTimeLogFilename = 67, - Packet_GetJustMyCodeHandle = 68, - Packet_GetLocationOfThisType = 69, - Packet_GetMethodAttribs = 70, - Packet_GetMethodClass = 71, - Packet_GetMethodDefFromMethod = 72, - Packet_GetMethodHash = 73, - Packet_GetMethodInfo = 74, - Packet_GetMethodName = 75, - Packet_GetMethodSig = 76, - Packet_GetMethodSync = 77, - Packet_GetMethodVTableOffset = 78, - Packet_GetNewArrHelper = 79, - Packet_GetNewHelper = 80, - Packet_GetParentType = 81, - //Packet_GetPInvokeUnmanagedTarget = 82, - Packet_GetProfilingHandle = 83, - Packet_GetRelocTypeHint = 84, - //Packet_GetSecurityPrologHelper = 85, - Packet_GetSharedCCtorHelper = 86, - //Packet_GetTailCallCopyArgsThunk = 87, - Packet_GetThreadTLSIndex = 88, - Packet_GetTokenTypeAsHandle = 89, - Packet_GetTypeForBox = 90, - Packet_GetTypeForPrimitiveValueClass = 91, - Packet_GetUnBoxHelper = 92, - Packet_GetUnmanagedCallConv = 94, - Packet_GetVarArgsHandle = 95, - Packet_GetVars = 96, - Packet_InitClass = 97, - //Packet_InitConstraintsForVerification = 98, - Packet_IsCompatibleDelegate = 99, - //Packet_IsInstantiationOfVerifiedGeneric = 100, - Packet_IsSDArray = 101, - //Packet_IsStructRequiringStackAllocRetBuf = 102, - Packet_IsValidStringRef = 103, - //Retired6 = 104, - Packet_IsValueClass = 105, - //Packet_IsWriteBarrierHelperRequired = 106, - Packet_MergeClasses = 107, - Packet_PInvokeMarshalingRequired = 108, - Packet_ResolveToken = 109, - Packet_SatisfiesClassConstraints = 110, - Packet_SatisfiesMethodConstraints = 111, - Packet_DoesFieldBelongToClass = 112, - PacketCR_AddressMap = 113, - PacketCR_AllocGCInfo = 114, - PacketCR_AllocMem = 115, - PacketCR_CallLog = 116, - PacketCR_ClassMustBeLoadedBeforeCodeIsRun = 117, - PacketCR_CompileMethod = 118, - PacketCR_MessageLog = 119, - PacketCR_MethodMustBeLoadedBeforeCodeIsRun = 120, - PacketCR_ProcessName = 121, - PacketCR_RecordRelocation = 122, - PacketCR_ReportFatalError = 123, - PacketCR_ReportInliningDecision = 124, - PacketCR_ReportTailCallDecision = 125, - PacketCR_SetBoundaries = 126, - PacketCR_SetEHcount = 127, - PacketCR_SetEHinfo = 128, - PacketCR_SetMethodAttribs = 129, - PacketCR_SetVars = 130, - //Packet_AllocMethodBlockCounts = 131, - PacketCR_AllocUnwindInfo = 132, - PacketCR_ReserveUnwindInfo = 133, - Packet_FilterException = 134, - //Packet_HandleException = 135, - //Retired9 = 136, - Packet_IsFieldStatic = 137, - PacketCR_AssertLog = 138, - Packet_GetArgClass = 139, - Packet_GetArgType = 140, - //Retired5 = 141, - Packet_CheckMethodModifier = 142, - Packet_CompileMethod = 143, - Packet_IsValidToken = 144, - Packet_FindNameOfToken = 145, - //PacketCR_RecordCallSite = 146, - Packet_GetLazyStringLiteralHelper = 147, - Packet_IsIntrinsicType = 148, - Packet_AppendClassName = 149, - Packet_GetReadyToRunHelper = 150, - Packet_GetIntConfigValue = 151, - Packet_GetStringConfigValue = 152, - Packet_GetAddressOfPInvokeTarget = 153, - Packet_GetJitFlags = 154, - Packet_IsDelegateCreationAllowed = 155, - Packet_GetSystemVAmd64PassStructInRegisterDescriptor = 156, - Packet_GetReadyToRunDelegateCtorHelper = 157, - Packet_TryResolveToken = 158, - Packet_GetHFAType = 159, - Packet_ResolveVirtualMethod = 160, - Packet_GetMethodNameFromMetadata = 161, - Packet_GetDefaultEqualityComparerClass = 162, - Packet_CompareTypesForCast = 163, - Packet_CompareTypesForEquality = 164, - Packet_GetUnboxedEntry = 165, - Packet_GetClassNameFromMetadata = 166, - Packet_GetTypeInstantiationArgument = 167, - Packet_GetTypeForPrimitiveNumericClass = 168, - Packet_ConvertPInvokeCalliToCall = 169, - Packet_GetHeapClassSize = 170, - Packet_CanAllocateOnStack = 171, - Packet_GetStaticFieldCurrentClass = 172, - Packet_CanInlineTypeCheck = 173, - Packet_IsMoreSpecificType = 174, - Packet_GetStringLiteral = 175, - PacketCR_SetPatchpointInfo = 176, - Packet_GetOSRInfo = 177, - Packet_GetTailCallHelpers = 178, - PacketCR_RecordCallSiteWithSignature = 179, - PacketCR_RecordCallSiteWithoutSignature = 180, - Packet_GetMethodModule = 181, - //Retired10 = 182, - Packet_GetExpectedTargetArchitecture = 183, - Packet_SigInstHandleMap = 184, - PacketCR_CrSigInstHandleMap = 185, - Packet_AllocPgoInstrumentationBySchema = 186, - Packet_GetPgoInstrumentationResults = 187, - Packet_GetDefaultComparerClass = 188, - Packet_GetClassModule = 189, - Packet_GetModuleAssembly = 190, - Packet_GetAssemblyName = 191, - Packet_IsIntrinsic = 192, - Packet_UpdateEntryPointForTailCall = 193, - Packet_GetLoongArch64PassStructInRegisterFlags = 194, - Packet_GetExactClasses = 195, - Packet_GetRuntimeTypePointer = 196, - Packet_PrintObjectDescription = 197, - Packet_GetReadonlyStaticFieldValue = 198, - Packet_GetObjectType = 199, - Packet_IsObjectImmutable = 200, - Packet_ExpandRawHandleIntrinsic = 201, -<<<<<<< HEAD - Packet_IsEnum = 202, -======= - Packet_GetArrayOrStringLength = 202, ->>>>>>> original/main -}; - -void SetDebugDumpVariables(); - -#endif // _MethodContext From c1b3bf22d1bfaae518f47b9c38b175fdcfc5fa02 Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 3 Nov 2022 02:39:52 +0100 Subject: [PATCH 49/52] Fix generated files --- .../JitInterface/CorInfoImpl_generated.cs | 189 ++++++++---------- 1 file changed, 84 insertions(+), 105 deletions(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 87c5fbac4cc9a..40218af44e79a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -2700,7 +2700,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 181); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 182); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2786,7 +2786,6 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[81] = (delegate* unmanaged)&_compareTypesForEquality; callbacks[82] = (delegate* unmanaged)&_mergeClasses; callbacks[83] = (delegate* unmanaged)&_isMoreSpecificType; -<<<<<<< HEAD callbacks[84] = (delegate* unmanaged)&_isEnum; callbacks[85] = (delegate* unmanaged)&_getParentType; callbacks[86] = (delegate* unmanaged)&_getChildType; @@ -2802,109 +2801,89 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[96] = (delegate* unmanaged)&_getFieldOffset; callbacks[97] = (delegate* unmanaged)&_getFieldInfo; callbacks[98] = (delegate* unmanaged)&_isFieldStatic; -======= - callbacks[84] = (delegate* unmanaged)&_getParentType; - callbacks[85] = (delegate* unmanaged)&_getChildType; - callbacks[86] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[87] = (delegate* unmanaged)&_isSDArray; - callbacks[88] = (delegate* unmanaged)&_getArrayRank; - callbacks[89] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[90] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[91] = (delegate* unmanaged)&_canAccessClass; - callbacks[92] = (delegate* unmanaged)&_getFieldName; - callbacks[93] = (delegate* unmanaged)&_getFieldClass; - callbacks[94] = (delegate* unmanaged)&_getFieldType; - callbacks[95] = (delegate* unmanaged)&_getFieldOffset; - callbacks[96] = (delegate* unmanaged)&_getFieldInfo; - callbacks[97] = (delegate* unmanaged)&_isFieldStatic; - callbacks[98] = (delegate* unmanaged)&_getArrayOrStringLength; ->>>>>>> original/main - callbacks[99] = (delegate* unmanaged)&_getBoundaries; - callbacks[100] = (delegate* unmanaged)&_setBoundaries; - callbacks[101] = (delegate* unmanaged)&_getVars; - callbacks[102] = (delegate* unmanaged)&_setVars; - callbacks[103] = (delegate* unmanaged)&_reportRichMappings; - callbacks[104] = (delegate* unmanaged)&_allocateArray; - callbacks[105] = (delegate* unmanaged)&_freeArray; - callbacks[106] = (delegate* unmanaged)&_getArgNext; - callbacks[107] = (delegate* unmanaged)&_getArgType; - callbacks[108] = (delegate* unmanaged)&_getExactClasses; - callbacks[109] = (delegate* unmanaged)&_getArgClass; - callbacks[110] = (delegate* unmanaged)&_getHFAType; - callbacks[111] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[112] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[113] = (delegate* unmanaged)&_FilterException; - callbacks[114] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[116] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[117] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[118] = (delegate* unmanaged)&_getEEInfo; - callbacks[119] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[120] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[121] = (delegate* unmanaged)&_getMethodName; - callbacks[122] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[123] = (delegate* unmanaged)&_getMethodHash; - callbacks[124] = (delegate* unmanaged)&_findNameOfToken; - callbacks[125] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[126] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[127] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[128] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[129] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[130] = (delegate* unmanaged)&_getHelperFtn; - callbacks[131] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[132] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[133] = (delegate* unmanaged)&_getMethodSync; - callbacks[134] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[135] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[136] = (delegate* unmanaged)&_embedClassHandle; - callbacks[137] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[138] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[139] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[140] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[141] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[142] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[146] = (delegate* unmanaged)&_getCallInfo; - callbacks[147] = (delegate* unmanaged)&_canAccessFamily; - callbacks[148] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[149] = (delegate* unmanaged)&_getClassDomainID; - callbacks[150] = (delegate* unmanaged)&_getFieldAddress; -<<<<<<< HEAD - callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; -======= - callbacks[151] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; ->>>>>>> original/main - callbacks[152] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[153] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[154] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[155] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[156] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[157] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[158] = (delegate* unmanaged)&_addActiveDependency; - callbacks[159] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[160] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[161] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[162] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[163] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[164] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[165] = (delegate* unmanaged)&_allocMem; - callbacks[166] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[167] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[168] = (delegate* unmanaged)&_allocGCInfo; - callbacks[169] = (delegate* unmanaged)&_setEHcount; - callbacks[170] = (delegate* unmanaged)&_setEHinfo; - callbacks[171] = (delegate* unmanaged)&_logMsg; - callbacks[172] = (delegate* unmanaged)&_doAssert; - callbacks[173] = (delegate* unmanaged)&_reportFatalError; - callbacks[174] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[175] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[176] = (delegate* unmanaged)&_recordCallSite; - callbacks[177] = (delegate* unmanaged)&_recordRelocation; - callbacks[178] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[179] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[180] = (delegate* unmanaged)&_getJitFlags; + callbacks[99] = (delegate* unmanaged)&_getArrayOrStringLength; + callbacks[100] = (delegate* unmanaged)&_getBoundaries; + callbacks[101] = (delegate* unmanaged)&_setBoundaries; + callbacks[102] = (delegate* unmanaged)&_getVars; + callbacks[103] = (delegate* unmanaged)&_setVars; + callbacks[104] = (delegate* unmanaged)&_reportRichMappings; + callbacks[105] = (delegate* unmanaged)&_allocateArray; + callbacks[106] = (delegate* unmanaged)&_freeArray; + callbacks[107] = (delegate* unmanaged)&_getArgNext; + callbacks[108] = (delegate* unmanaged)&_getArgType; + callbacks[109] = (delegate* unmanaged)&_getExactClasses; + callbacks[110] = (delegate* unmanaged)&_getArgClass; + callbacks[111] = (delegate* unmanaged)&_getHFAType; + callbacks[112] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[113] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[114] = (delegate* unmanaged)&_FilterException; + callbacks[115] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[116] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[117] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[118] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[119] = (delegate* unmanaged)&_getEEInfo; + callbacks[120] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[121] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[122] = (delegate* unmanaged)&_getMethodName; + callbacks[123] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[124] = (delegate* unmanaged)&_getMethodHash; + callbacks[125] = (delegate* unmanaged)&_findNameOfToken; + callbacks[126] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[127] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[128] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[129] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[130] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[131] = (delegate* unmanaged)&_getHelperFtn; + callbacks[132] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[133] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[134] = (delegate* unmanaged)&_getMethodSync; + callbacks[135] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[136] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[137] = (delegate* unmanaged)&_embedClassHandle; + callbacks[138] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[139] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[140] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[141] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[142] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[143] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[144] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[145] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[146] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[147] = (delegate* unmanaged)&_getCallInfo; + callbacks[148] = (delegate* unmanaged)&_canAccessFamily; + callbacks[149] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[150] = (delegate* unmanaged)&_getClassDomainID; + callbacks[151] = (delegate* unmanaged)&_getFieldAddress; + callbacks[152] = (delegate* unmanaged)&_getReadonlyStaticFieldValue; + callbacks[153] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[154] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[155] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[156] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[157] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[158] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[159] = (delegate* unmanaged)&_addActiveDependency; + callbacks[160] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[161] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[162] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[163] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[164] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[165] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[166] = (delegate* unmanaged)&_allocMem; + callbacks[167] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[168] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[169] = (delegate* unmanaged)&_allocGCInfo; + callbacks[170] = (delegate* unmanaged)&_setEHcount; + callbacks[171] = (delegate* unmanaged)&_setEHinfo; + callbacks[172] = (delegate* unmanaged)&_logMsg; + callbacks[173] = (delegate* unmanaged)&_doAssert; + callbacks[174] = (delegate* unmanaged)&_reportFatalError; + callbacks[175] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[176] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[177] = (delegate* unmanaged)&_recordCallSite; + callbacks[178] = (delegate* unmanaged)&_recordRelocation; + callbacks[179] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[180] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[181] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } From 64def5346afff624a77a7d3571777c887a6d89fd Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 10 Nov 2022 16:00:47 +0100 Subject: [PATCH 50/52] Revert changes in non CoreCLR specific code --- .../Concurrent/ConcurrentDictionary.cs | 89 +++++++++++-------- .../Converters/Value/EnumConverter.cs | 20 +++-- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs index f133d0b3f05a9..8ad537cde4785 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs @@ -555,7 +555,11 @@ nullableHashcode is null || { if (valueComparer.Equals(node._value, comparisonValue)) { - if (IsWriteAtomic()) + // Do the reference type check up front to handle many cases of shared generics. + // If TValue is a value type then the field's value here can be baked in. Otherwise, + // for the remaining shared generic cases the field access here would disqualify inlining, + // so the following check cannot be factored out of TryAddInternal/TryUpdateInternal. + if (!typeof(TValue).IsValueType || ConcurrentDictionaryTypeProps.IsWriteAtomic) { node._value = newValue; } @@ -894,7 +898,11 @@ nullableHashcode is null || // be written atomically, since lock-free reads may be happening concurrently. if (updateIfExists) { - if (IsWriteAtomic()) + // Do the reference type check up front to handle many cases of shared generics. + // If TValue is a value type then the field's value here can be baked in. Otherwise, + // for the remaining shared generic cases the field access here would disqualify inlining, + // so the following check cannot be factored out of TryAddInternal/TryUpdateInternal. + if (!typeof(TValue).IsValueType || ConcurrentDictionaryTypeProps.IsWriteAtomic) { node._value = value; } @@ -2124,42 +2132,6 @@ private ReadOnlyCollection GetValues() } } - /// Whether T's type can be written atomically (i.e., with no danger of torn reads). - private static bool IsWriteAtomic() - { - // Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without - // the risk of tearing. See https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf - - if (!typeof(T).IsValueType || - typeof(T) == typeof(IntPtr) || - typeof(T) == typeof(UIntPtr)) - { - return true; - } - - switch (Type.GetTypeCode(typeof(T))) - { - case TypeCode.Boolean: - case TypeCode.Byte: - case TypeCode.Char: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.SByte: - case TypeCode.Single: - case TypeCode.UInt16: - case TypeCode.UInt32: - return true; - - case TypeCode.Double: - case TypeCode.Int64: - case TypeCode.UInt64: - return IntPtr.Size == 8; - - default: - return false; - } - } - /// /// A node in a singly-linked list representing a particular hash table bucket. /// @@ -2264,6 +2236,47 @@ private sealed class DictionaryEnumerator : IDictionaryEnumerator } } + internal static class ConcurrentDictionaryTypeProps + { + /// Whether T's type can be written atomically (i.e., with no danger of torn reads). + internal static readonly bool IsWriteAtomic = IsWriteAtomicPrivate(); + + private static bool IsWriteAtomicPrivate() + { + // Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without + // the risk of tearing. See https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf + + if (!typeof(T).IsValueType || + typeof(T) == typeof(IntPtr) || + typeof(T) == typeof(UIntPtr)) + { + return true; + } + + switch (Type.GetTypeCode(typeof(T))) + { + case TypeCode.Boolean: + case TypeCode.Byte: + case TypeCode.Char: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.SByte: + case TypeCode.Single: + case TypeCode.UInt16: + case TypeCode.UInt32: + return true; + + case TypeCode.Double: + case TypeCode.Int64: + case TypeCode.UInt64: + return IntPtr.Size == 8; + + default: + return false; + } + } + } + internal sealed class IDictionaryDebugView where TKey : notnull { private readonly IDictionary _dictionary; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index ff4f76c05062d..e9b01aaf3d27f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -13,8 +13,13 @@ namespace System.Text.Json.Serialization.Converters internal sealed class EnumConverter : JsonPrimitiveConverter where T : struct, Enum { + private static readonly TypeCode s_enumTypeCode = Type.GetTypeCode(typeof(T)); + private static readonly char[] s_specialChars = new[] { ',', ' ' }; + // Odd type codes are conveniently signed types (for enum backing types). + private static readonly bool s_isSignedEnum = ((int)s_enumTypeCode % 2) == 1; + private const string ValueSeparator = ", "; private readonly EnumConverterOptions _converterOptions; @@ -37,9 +42,6 @@ internal sealed class EnumConverter : JsonPrimitiveConverter // Since multiple threads can add to the cache, a few more values might be added. private const int NameCacheSizeSoftLimit = 64; - // Odd type codes are conveniently signed types (for enum backing types). - private static bool IsSignedEnum => ((int)Type.GetTypeCode(typeof(T)) % 2) == 1; - public override bool CanConvert(Type type) { return type.IsEnum; @@ -128,7 +130,7 @@ public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerial return default; } - switch (Type.GetTypeCode(typeof(T))) + switch (s_enumTypeCode) { // Switch cases ordered by expected frequency @@ -231,7 +233,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions ThrowHelper.ThrowJsonException(); } - switch (Type.GetTypeCode(typeof(T))) + switch (s_enumTypeCode) { case TypeCode.Int32: writer.WriteNumberValue(Unsafe.As(ref value)); @@ -318,7 +320,7 @@ internal override void WriteAsPropertyNameCore(Utf8JsonWriter writer, T value, J return; } - switch (Type.GetTypeCode(typeof(T))) + switch (s_enumTypeCode) { case TypeCode.Int32: writer.WritePropertyName(Unsafe.As(ref value)); @@ -376,7 +378,7 @@ private static bool TryParseEnumCore(ref Utf8JsonReader reader, JsonSerializerOp return success; } #else - private static bool TryParseEnumCore(string? enumString, JsonSerializerOptions options, out T value) + private static bool TryParseEnumCore(string? enumString, JsonSerializerOptions _, out T value) { // Try parsing case sensitive first bool success = Enum.TryParse(enumString, out T result) || Enum.TryParse(enumString, ignoreCase: true, out result); @@ -438,7 +440,7 @@ private T ReadEnumUsingNamingPolicy(string? enumString) private static ulong ConvertToUInt64(object value) { Debug.Assert(value is T); - ulong result = Type.GetTypeCode(typeof(T)) switch + ulong result = s_enumTypeCode switch { TypeCode.Int32 => (ulong)(int)value, TypeCode.UInt32 => (uint)value, @@ -464,7 +466,7 @@ private static bool IsValidIdentifier(string value) // so we'll just pick the first valid one and check for a negative sign // if needed. return (value[0] >= 'A' && - (!IsSignedEnum || !value.StartsWith(NumberFormatInfo.CurrentInfo.NegativeSign))); + (!s_isSignedEnum || !value.StartsWith(NumberFormatInfo.CurrentInfo.NegativeSign))); } private static string FormatJsonName(string value, JsonNamingPolicy? namingPolicy) From 28561ac7d37b443bf1368be27733b0ea72b30740 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 10 Nov 2022 10:39:39 -0800 Subject: [PATCH 51/52] Update src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs --- .../Text/Json/Serialization/Converters/Value/EnumConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs index e9b01aaf3d27f..7b002db36f83b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverter.cs @@ -378,7 +378,7 @@ private static bool TryParseEnumCore(ref Utf8JsonReader reader, JsonSerializerOp return success; } #else - private static bool TryParseEnumCore(string? enumString, JsonSerializerOptions _, out T value) + private static bool TryParseEnumCore(string? enumString, JsonSerializerOptions options, out T value) { // Try parsing case sensitive first bool success = Enum.TryParse(enumString, out T result) || Enum.TryParse(enumString, ignoreCase: true, out result); From 9f108e9586a73156789ae014c61016558d44f852 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 10 Nov 2022 10:40:40 -0800 Subject: [PATCH 52/52] Update src/libraries/System.Private.CoreLib/src/System/Enum.cs --- src/libraries/System.Private.CoreLib/src/System/Enum.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index 4824d6a33bf45..d35f3a46c46bf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -316,7 +316,6 @@ internal static string[] InternalGetNames(RuntimeType enumType) => // Get all of the names GetEnumInfo(enumType).Names; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Type GetUnderlyingType(Type enumType) { ArgumentNullException.ThrowIfNull(enumType);