Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ internal static unsafe class CastHelpers
return ChkCastClassSpecial(toTypeHnd, obj);
}

// Optimized helper for classes. Assumes that the trivial cases
// has been taken care of by the inlined check
[DebuggerHidden]
[StackTraceHidden]
[DebuggerStepThrough]
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,10 @@ enum CorInfoHelpFunc
// the right helper to use

CORINFO_HELP_ISINSTANCEOFINTERFACE, // Optimized helper for interfaces
CORINFO_HELP_ISINSTANCEOFARRAY, // Optimized helper for arrays
CORINFO_HELP_ISINSTANCEOFCLASS, // Optimized helper for classes
CORINFO_HELP_ISINSTANCEOFANY, // Slow helper for any type

CORINFO_HELP_CHKCASTINTERFACE,
CORINFO_HELP_CHKCASTARRAY,
CORINFO_HELP_CHKCASTCLASS,
CORINFO_HELP_CHKCASTANY,
CORINFO_HELP_CHKCASTCLASS_SPECIAL, // Optimized helper for classes. Assumes that the trivial cases
Expand Down Expand Up @@ -858,6 +856,7 @@ enum CorInfoFlag
CORINFO_FLG_ARRAY = 0x00080000, // class is an array class (initialized differently)
CORINFO_FLG_OVERLAPPING_FIELDS = 0x00100000, // struct or class has fields that overlap (aka union)
CORINFO_FLG_INTERFACE = 0x00200000, // it is an interface
CORINFO_FLG_TYPE_EQUIVALENCE = 0x00400000, // this type participates in type equivalence
CORINFO_FLG_CONTAINS_GC_PTR = 0x01000000, // does the class contain a gc ptr ?
CORINFO_FLG_DELEGATE = 0x02000000, // is this a subclass of delegate or multicast delegate ?
CORINFO_FLG_INDEXABLE_FIELDS = 0x04000000, // struct fields may be accessed via indexing (used for inline arrays)
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED

constexpr GUID JITEEVersionIdentifier = { /* a20effd6-2cd4-4657-8d2f-1d3e5d7eeab9 */
0xa20effd6,
0x2cd4,
0x4657,
{0x8d, 0x2f, 0x1d, 0x3e, 0x5d, 0x7e, 0xea, 0xb9}
constexpr GUID JITEEVersionIdentifier = { /* 2c447f91-74be-4f02-a836-0cfd35224a1d */
0x2c447f91,
0x74be,
0x4f02,
{0xa8, 0x36, 0x0c, 0xfd, 0x35, 0x22, 0x4a, 0x1d}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,9 @@

// Casting helpers
DYNAMICJITHELPER(CORINFO_HELP_ISINSTANCEOFINTERFACE, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_ISINSTANCEOFARRAY, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_ISINSTANCEOFCLASS, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_ISINSTANCEOFANY, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_CHKCASTINTERFACE, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_CHKCASTARRAY, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_CHKCASTCLASS, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_CHKCASTANY, NULL, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_CHKCASTCLASS_SPECIAL, NULL, CORINFO_HELP_SIG_REG_ONLY)
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2171,7 +2171,6 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
// Also note The CASTCLASS helpers won't appear in predicates as they throw on failure.
// So the helper list here is smaller than the one in optAssertionProp_Call.
if ((call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFINTERFACE)) ||
(call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFARRAY)) ||
(call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS)) ||
(call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY)))
{
Expand Down Expand Up @@ -4483,11 +4482,9 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
else if (!optLocalAssertionProp && (call->gtCallType == CT_HELPER))
{
if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFINTERFACE) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFARRAY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTINTERFACE) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTARRAY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTANY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS_SPECIAL))
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18316,11 +18316,9 @@ CORINFO_CLASS_HANDLE Compiler::gtGetHelperCallClassHandle(GenTreeCall* call, boo

case CORINFO_HELP_CHKCASTCLASS:
case CORINFO_HELP_CHKCASTANY:
case CORINFO_HELP_CHKCASTARRAY:
case CORINFO_HELP_CHKCASTINTERFACE:
case CORINFO_HELP_CHKCASTCLASS_SPECIAL:
case CORINFO_HELP_ISINSTANCEOFINTERFACE:
case CORINFO_HELP_ISINSTANCEOFARRAY:
case CORINFO_HELP_ISINSTANCEOFCLASS:
case CORINFO_HELP_ISINSTANCEOFANY:
{
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5469,8 +5469,8 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
}
else if (isCastClass)
{
// Jit can only inline expand CHKCASTCLASS and CHKCASTARRAY helpers.
canExpandInline = (helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTARRAY);
// Jit can always inline expand CHKCASTCLASS
canExpandInline = (helper == CORINFO_HELP_CHKCASTCLASS);

// For ChkCastAny we ignore cases where the class is known to be abstract or is an interface.
if (helper == CORINFO_HELP_CHKCASTANY)
Expand All @@ -5480,7 +5480,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
canExpandInline = !isAbstract;
}
}
else if ((helper == CORINFO_HELP_ISINSTANCEOFCLASS) || (helper == CORINFO_HELP_ISINSTANCEOFARRAY))
else if ((helper == CORINFO_HELP_ISINSTANCEOFCLASS) || (helper == CORINFO_HELP_ISINSTANCEOFANY))
{
// If the class is exact, the jit can expand the IsInst check inline.
canExpandInline = isClassExact;
Expand Down Expand Up @@ -5616,8 +5616,8 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
GenTree* condTrue;
if (isCastClass)
{
assert((helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTARRAY) ||
(helper == CORINFO_HELP_CHKCASTANY) || (helper == CORINFO_HELP_CHKCASTINTERFACE));
assert((helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTANY) ||
(helper == CORINFO_HELP_CHKCASTINTERFACE));

CorInfoHelpFunc specialHelper = helper;
if ((helper == CORINFO_HELP_CHKCASTCLASS) &&
Expand Down Expand Up @@ -13612,7 +13612,7 @@ methodPointerInfo* Compiler::impAllocateMethodPointerInfo(const CORINFO_RESOLVED
bool Compiler::impIsClassExact(CORINFO_CLASS_HANDLE classHnd)
{
DWORD flags = info.compCompHnd->getClassAttribs(classHnd);
DWORD flagsMask = CORINFO_FLG_FINAL | CORINFO_FLG_VARIANCE | CORINFO_FLG_ARRAY;
DWORD flagsMask = CORINFO_FLG_FINAL | CORINFO_FLG_VARIANCE | CORINFO_FLG_TYPE_EQUIVALENCE | CORINFO_FLG_ARRAY;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both CORINFO_FLG_VARIANCE and CORINFO_FLG_TYPE_EQUIVALENCE are only computed to make the impIsClassExact work. Computing these flags is a waste in all other cases. It is the kind of pattern that calls for introduction of dedicated JIT/EE interface API that replaces the flags.


if ((flags & flagsMask) == CORINFO_FLG_FINAL)
{
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/jit/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,6 @@ void HelperCallProperties::init()

// type casting helpers
case CORINFO_HELP_ISINSTANCEOFINTERFACE:
case CORINFO_HELP_ISINSTANCEOFARRAY:
case CORINFO_HELP_ISINSTANCEOFCLASS:
case CORINFO_HELP_ISINSTANCEOFANY:
case CORINFO_HELP_READYTORUN_ISINSTANCEOF:
Expand All @@ -1408,7 +1407,6 @@ void HelperCallProperties::init()

// type casting helpers that throw
case CORINFO_HELP_CHKCASTINTERFACE:
case CORINFO_HELP_CHKCASTARRAY:
case CORINFO_HELP_CHKCASTCLASS:
case CORINFO_HELP_CHKCASTANY:
case CORINFO_HELP_CHKCASTCLASS_SPECIAL:
Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/jit/valuenum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12755,7 +12755,6 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc)

case CORINFO_HELP_CHKCASTCLASS:
case CORINFO_HELP_CHKCASTCLASS_SPECIAL:
case CORINFO_HELP_CHKCASTARRAY:
case CORINFO_HELP_CHKCASTINTERFACE:
case CORINFO_HELP_CHKCASTANY:
vnf = VNF_CastClass;
Expand All @@ -12767,7 +12766,6 @@ VNFunc Compiler::fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc)

case CORINFO_HELP_ISINSTANCEOFCLASS:
case CORINFO_HELP_ISINSTANCEOFINTERFACE:
case CORINFO_HELP_ISINSTANCEOFARRAY:
case CORINFO_HELP_ISINSTANCEOFANY:
vnf = VNF_IsInstanceOf;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, EETypePtr pUnboxT
}
else
{
if (o != null && (TypeCast.IsInstanceOf(ptrUnboxToEEType, o) == null))
if (o != null && (TypeCast.IsInstanceOfAny(ptrUnboxToEEType, o) == null))
{
throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
}
Expand Down Expand Up @@ -392,26 +392,18 @@ internal static unsafe IntPtr RhGetRuntimeHelperForType(MethodTable* pEEType, Ru
return (IntPtr)(delegate*<MethodTable*, object>)&InternalCalls.RhpNewFast;

case RuntimeHelperKind.IsInst:
if (pEEType->IsArray)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.IsInstanceOfArray;
else if (pEEType->HasGenericVariance)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.IsInstanceOf;
if (pEEType->HasGenericVariance || pEEType->IsParameterizedType || pEEType->IsFunctionPointerType)
return (IntPtr)(delegate*<MethodTable*, object, object?>)&TypeCast.IsInstanceOfAny;
else if (pEEType->IsInterface)
return (IntPtr)(delegate*<MethodTable*, object?, object?>)&TypeCast.IsInstanceOfInterface;
else if (pEEType->IsParameterizedType || pEEType->IsFunctionPointerType)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.IsInstanceOf; // Array handled above; pointers and byrefs handled here
else
return (IntPtr)(delegate*<MethodTable*, object?, object?>)&TypeCast.IsInstanceOfClass;

case RuntimeHelperKind.CastClass:
if (pEEType->IsArray)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCastArray;
else if (pEEType->HasGenericVariance)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCast;
if (pEEType->HasGenericVariance || pEEType->IsParameterizedType || pEEType->IsFunctionPointerType)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCastAny;
else if (pEEType->IsInterface)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCastInterface;
else if (pEEType->IsParameterizedType || pEEType->IsFunctionPointerType)
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCast; // Array handled above; pointers and byrefs handled here
else
return (IntPtr)(delegate*<MethodTable*, object, object>)&TypeCast.CheckCastClass;

Expand Down
Loading