Skip to content

Commit

Permalink
Add isNullableType to JIT interface
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed Apr 14, 2024
1 parent 856328c commit bb52b25
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 102 deletions.
5 changes: 5 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2709,6 +2709,11 @@ class ICorStaticInfo
CORINFO_CLASS_HANDLE cls
) = 0;

// Returns whether a class handle represents a Nullable type, if that can be statically determined.
virtual TypeCompareState isNullableType(
CORINFO_CLASS_HANDLE cls
) = 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
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ bool isMoreSpecificType(
bool isExactType(
CORINFO_CLASS_HANDLE cls) override;

TypeCompareState isNullableType(
CORINFO_CLASS_HANDLE cls) override;

TypeCompareState isEnum(
CORINFO_CLASS_HANDLE cls,
CORINFO_CLASS_HANDLE* underlyingType) override;
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 = { /* 3c216494-65f8-49e2-b69a-7f272193bcc6 */
0x3c216494,
0x65f8,
0x49e2,
{0xb6, 0x9a, 0x7f, 0x27, 0x21, 0x93, 0xbc, 0xc6}
constexpr GUID JITEEVersionIdentifier = { /* 8f046bcb-ca5f-4692-9277-898b71cb7938 */
0x8f046bcb,
0xca5f,
0x4692,
{0x92, 0x77, 0x89, 0x8b, 0x71, 0xcb, 0x79, 0x38}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ DEF_CLR_API(compareTypesForCast)
DEF_CLR_API(compareTypesForEquality)
DEF_CLR_API(isMoreSpecificType)
DEF_CLR_API(isExactType)
DEF_CLR_API(isNullableType)
DEF_CLR_API(isEnum)
DEF_CLR_API(getParentType)
DEF_CLR_API(getChildType)
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,15 @@ bool WrapICorJitInfo::isExactType(
return temp;
}

TypeCompareState WrapICorJitInfo::isNullableType(
CORINFO_CLASS_HANDLE cls)
{
API_ENTER(isNullableType);
TypeCompareState temp = wrapHnd->isNullableType(cls);
API_LEAVE(isNullableType);
return temp;
}

TypeCompareState WrapICorJitInfo::isEnum(
CORINFO_CLASS_HANDLE cls,
CORINFO_CLASS_HANDLE* underlyingType)
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4717,10 +4717,10 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic,
ClassLayout* toLayout = nullptr;
var_types toType = TypeHandleToVarType(toTypeHnd, &toLayout);

if (fromType == TYP_REF || info.compCompHnd->getBoxHelper(fromTypeHnd) == CORINFO_HELP_BOX_NULLABLE ||
toType == TYP_REF || info.compCompHnd->getBoxHelper(toTypeHnd) == CORINFO_HELP_BOX_NULLABLE)
if (fromType == TYP_REF || info.compCompHnd->isNullableType(fromTypeHnd) != TypeCompareState::MustNot ||
toType == TYP_REF || info.compCompHnd->isNullableType(toTypeHnd) != TypeCompareState::MustNot)
{
// Fallback to the software implementation to throw when the types don't fit "where T : struct"
// Fallback to the software implementation to throw when the types fail a "default(T) is not null" check.
return nullptr;
}

Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,18 @@ private bool isExactType(CORINFO_CLASS_STRUCT_* cls)
return _compilation.IsEffectivelySealed(type);
}

private TypeCompareState isNullableType(CORINFO_CLASS_STRUCT_* cls)
{
TypeDesc type = HandleToObject(cls);

if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any))
{
return TypeCompareState.May;
}

return type.IsNullable ? TypeCompareState.Must : TypeCompareState.MustNot;
}

private TypeCompareState isEnum(CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType)
{
Debug.Assert(cls != null);
Expand Down
204 changes: 110 additions & 94 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ FUNCTIONS
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
bool isExactType(CORINFO_CLASS_HANDLE cls)
TypeCompareState isNullableType(CORINFO_CLASS_HANDLE cls)
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)
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/tools/aot/jitinterface/jitinterface_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct JitInterfaceCallbacks
TypeCompareState (* compareTypesForEquality)(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);
bool (* isExactType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
TypeCompareState (* isNullableType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
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);
Expand Down Expand Up @@ -992,6 +993,15 @@ class JitInterfaceWrapper : public ICorJitInfo
return temp;
}

virtual TypeCompareState isNullableType(
CORINFO_CLASS_HANDLE cls)
{
CorInfoExceptionClass* pException = nullptr;
TypeCompareState temp = _callbacks->isNullableType(_thisHandle, &pException, cls);
if (pException != nullptr) throw pException;
return temp;
}

virtual TypeCompareState isEnum(
CORINFO_CLASS_HANDLE cls,
CORINFO_CLASS_HANDLE* underlyingType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,13 @@ bool interceptor_ICJI::isExactType(
return original_ICorJitInfo->isExactType(cls);
}

TypeCompareState interceptor_ICJI::isNullableType(
CORINFO_CLASS_HANDLE cls)
{
mcs->AddCall("isNullableType");
return original_ICorJitInfo->isNullableType(cls);
}

TypeCompareState interceptor_ICJI::isEnum(
CORINFO_CLASS_HANDLE cls,
CORINFO_CLASS_HANDLE* underlyingType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,12 @@ bool interceptor_ICJI::isExactType(
return original_ICorJitInfo->isExactType(cls);
}

TypeCompareState interceptor_ICJI::isNullableType(
CORINFO_CLASS_HANDLE cls)
{
return original_ICorJitInfo->isNullableType(cls);
}

TypeCompareState interceptor_ICJI::isEnum(
CORINFO_CLASS_HANDLE cls,
CORINFO_CLASS_HANDLE* underlyingType)
Expand Down
25 changes: 25 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4658,6 +4658,31 @@ bool CEEInfo::isExactType(CORINFO_CLASS_HANDLE cls)
return result;
}

// Returns whether a class handle represents a Nullable type, if that can be statically determined.
TypeCompareState CEEInfo::isNullableType(CORINFO_CLASS_HANDLE cls)
{
CONTRACTL {
THROWS;
GC_TRIGGERS;
MODE_PREEMPTIVE;
} CONTRACTL_END;

TypeHandle typeHandle = TypeHandle();

TypeCompareState result = TypeCompareState::May;

JIT_TO_EE_TRANSITION();

if (typeHandle != TypeHandle(g_pCanonMethodTableClass))
{
TypeHandle VMClsHnd(cls);
result = Nullable::IsNullableType(VMClsHnd) ? TypeCompareState::Must : TypeCompareState::MustNot;
}

EE_TO_JIT_TRANSITION();
return result;
}

/*********************************************************************/
// Returns TypeCompareState::Must if cls is known to be an enum.
// For enums with known exact type returns the underlying
Expand Down

0 comments on commit bb52b25

Please sign in to comment.