Skip to content

Commit

Permalink
Drop generic type constraints from Unsafe.BitCast (dotnet#100842)
Browse files Browse the repository at this point in the history
* Drop generic type constraints from Unsafe.BitCast

* Add isNullableType to JIT interface

* superpmi

* Comment formatting

* Check IsGenericParameter instead of Canon

* Replace IsGenericParameter check with assert

* Just kidding, remove it completely :D
  • Loading branch information
MihaZupan authored Apr 15, 2024
1 parent 3c10707 commit 617f81f
Show file tree
Hide file tree
Showing 25 changed files with 451 additions and 289 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
10 changes: 8 additions & 2 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4717,6 +4717,14 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic,
ClassLayout* toLayout = nullptr;
var_types toType = TypeHandleToVarType(toTypeHnd, &toLayout);

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 fail a "default(T) is not null"
// check.
return nullptr;
}

unsigned fromSize = fromLayout != nullptr ? fromLayout->GetSize() : genTypeSize(fromType);
unsigned toSize = toLayout != nullptr ? toLayout->GetSize() : genTypeSize(toType);

Expand All @@ -4729,8 +4737,6 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic,
return nullptr;
}

assert((fromType != TYP_REF) && (toType != TYP_REF));

GenTree* op1 = impPopStack().val;

op1 = impImplicitR4orR8Cast(op1, fromType);
Expand Down
7 changes: 7 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,13 @@ private bool isExactType(CORINFO_CLASS_STRUCT_* cls)
return _compilation.IsEffectivelySealed(type);
}

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

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
1 change: 1 addition & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ LWM(PrintMethodName, DWORDLONG, Agnostic_PrintResult)
LWM(IsValueClass, DWORDLONG, DWORD)
LWM(IsMoreSpecificType, DLDL, DWORD)
LWM(IsExactType, DWORDLONG, DWORD)
LWM(IsNullableType, DWORDLONG, DWORD)
LWM(IsEnum, DWORDLONG, DLD)
LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD)
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)
Expand Down
22 changes: 22 additions & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5920,6 +5920,28 @@ bool MethodContext::repIsExactType(CORINFO_CLASS_HANDLE cls)
return value != 0;
}

void MethodContext::recIsNullableType(CORINFO_CLASS_HANDLE cls, TypeCompareState result)
{
if (IsNullableType == nullptr)
IsNullableType = new LightWeightMap<DWORDLONG, DWORD>();

DWORDLONG key = CastHandle(cls);
DWORD value = (DWORD)result;
IsNullableType->Add(key, value);
DEBUG_REC(dmpIsNullableType(key, value));
}
void MethodContext::dmpIsNullableType(DWORDLONG key, DWORD value)
{
printf("IsNullableType key cls-%016" PRIX64 ", value res-%d", key, value);
}
TypeCompareState MethodContext::repIsNullableType(CORINFO_CLASS_HANDLE cls)
{
DWORDLONG key = CastHandle(cls);
DWORD value = LookupByKeyOrMiss(IsNullableType, key, ": key %016" PRIX64 "", key);
DEBUG_REP(dmpIsNullableType(key, value));
return (TypeCompareState)value;
}

void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result)
{
if (IsEnum == nullptr)
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,10 @@ class MethodContext
void dmpIsExactType(DWORDLONG key, DWORD value);
bool repIsExactType(CORINFO_CLASS_HANDLE cls);

void recIsNullableType(CORINFO_CLASS_HANDLE cls, TypeCompareState result);
void dmpIsNullableType(DWORDLONG key, DWORD value);
TypeCompareState repIsNullableType(CORINFO_CLASS_HANDLE cls);

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);
Expand Down Expand Up @@ -1165,6 +1169,7 @@ enum mcPackets
Packet_NotifyMethodInfoUsage = 214,
Packet_IsExactType = 215,
Packet_GetSwiftLowering = 216,
Packet_IsNullableType = 217,
};

void SetDebugDumpVariables();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,15 @@ bool interceptor_ICJI::isExactType(CORINFO_CLASS_HANDLE cls)
return temp;
}

// Returns whether a class handle represents a Nullable type, if that can be statically determined.
TypeCompareState interceptor_ICJI::isNullableType(CORINFO_CLASS_HANDLE cls)
{
mc->cr->AddCall("isNullableType");
TypeCompareState temp = original_ICorJitInfo->isNullableType(cls);
mc->recIsNullableType(cls, temp);
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
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
7 changes: 7 additions & 0 deletions src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,13 @@ bool MyICJI::isExactType(CORINFO_CLASS_HANDLE cls)
return jitInstance->mc->repIsExactType(cls);
}

// Returns true if a class handle represents a Nullable type.
TypeCompareState MyICJI::isNullableType(CORINFO_CLASS_HANDLE cls)
{
jitInstance->mc->cr->AddCall("isNullableType");
return jitInstance->mc->repIsNullableType(cls);
}

// 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
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
Loading

0 comments on commit 617f81f

Please sign in to comment.