Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop generic type constraints from Unsafe.BitCast #100842

Merged
merged 7 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
8 changes: 8 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,14 @@ private bool isExactType(CORINFO_CLASS_STRUCT_* cls)
return _compilation.IsEffectivelySealed(type);
}

private TypeCompareState isNullableType(CORINFO_CLASS_STRUCT_* cls)
{
TypeDesc type = HandleToObject(cls);
Debug.Assert(!type.IsGenericParameter);
MihaZupan marked this conversation as resolved.
Show resolved Hide resolved

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
Loading