Skip to content

Commit 617f81f

Browse files
authored
Drop generic type constraints from Unsafe.BitCast (#100842)
* 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
1 parent 3c10707 commit 617f81f

File tree

25 files changed

+451
-289
lines changed

25 files changed

+451
-289
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,11 @@ class ICorStaticInfo
27092709
CORINFO_CLASS_HANDLE cls
27102710
) = 0;
27112711

2712+
// Returns whether a class handle represents a Nullable type, if that can be statically determined.
2713+
virtual TypeCompareState isNullableType(
2714+
CORINFO_CLASS_HANDLE cls
2715+
) = 0;
2716+
27122717
// Returns TypeCompareState::Must if cls is known to be an enum.
27132718
// For enums with known exact type returns the underlying
27142719
// type in underlyingType when the provided pointer is

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ bool isMoreSpecificType(
344344
bool isExactType(
345345
CORINFO_CLASS_HANDLE cls) override;
346346

347+
TypeCompareState isNullableType(
348+
CORINFO_CLASS_HANDLE cls) override;
349+
347350
TypeCompareState isEnum(
348351
CORINFO_CLASS_HANDLE cls,
349352
CORINFO_CLASS_HANDLE* underlyingType) override;

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
4343
#define GUID_DEFINED
4444
#endif // !GUID_DEFINED
4545

46-
constexpr GUID JITEEVersionIdentifier = { /* 3c216494-65f8-49e2-b69a-7f272193bcc6 */
47-
0x3c216494,
48-
0x65f8,
49-
0x49e2,
50-
{0xb6, 0x9a, 0x7f, 0x27, 0x21, 0x93, 0xbc, 0xc6}
46+
constexpr GUID JITEEVersionIdentifier = { /* 8f046bcb-ca5f-4692-9277-898b71cb7938 */
47+
0x8f046bcb,
48+
0xca5f,
49+
0x4692,
50+
{0x92, 0x77, 0x89, 0x8b, 0x71, 0xcb, 0x79, 0x38}
5151
};
5252

5353
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/jit/ICorJitInfo_names_generated.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ DEF_CLR_API(compareTypesForCast)
8585
DEF_CLR_API(compareTypesForEquality)
8686
DEF_CLR_API(isMoreSpecificType)
8787
DEF_CLR_API(isExactType)
88+
DEF_CLR_API(isNullableType)
8889
DEF_CLR_API(isEnum)
8990
DEF_CLR_API(getParentType)
9091
DEF_CLR_API(getChildType)

src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,15 @@ bool WrapICorJitInfo::isExactType(
804804
return temp;
805805
}
806806

807+
TypeCompareState WrapICorJitInfo::isNullableType(
808+
CORINFO_CLASS_HANDLE cls)
809+
{
810+
API_ENTER(isNullableType);
811+
TypeCompareState temp = wrapHnd->isNullableType(cls);
812+
API_LEAVE(isNullableType);
813+
return temp;
814+
}
815+
807816
TypeCompareState WrapICorJitInfo::isEnum(
808817
CORINFO_CLASS_HANDLE cls,
809818
CORINFO_CLASS_HANDLE* underlyingType)

src/coreclr/jit/importercalls.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4717,6 +4717,14 @@ GenTree* Compiler::impSRCSUnsafeIntrinsic(NamedIntrinsic intrinsic,
47174717
ClassLayout* toLayout = nullptr;
47184718
var_types toType = TypeHandleToVarType(toTypeHnd, &toLayout);
47194719

4720+
if (fromType == TYP_REF || info.compCompHnd->isNullableType(fromTypeHnd) != TypeCompareState::MustNot ||
4721+
toType == TYP_REF || info.compCompHnd->isNullableType(toTypeHnd) != TypeCompareState::MustNot)
4722+
{
4723+
// Fallback to the software implementation to throw when the types fail a "default(T) is not null"
4724+
// check.
4725+
return nullptr;
4726+
}
4727+
47204728
unsigned fromSize = fromLayout != nullptr ? fromLayout->GetSize() : genTypeSize(fromType);
47214729
unsigned toSize = toLayout != nullptr ? toLayout->GetSize() : genTypeSize(toType);
47224730

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

4732-
assert((fromType != TYP_REF) && (toType != TYP_REF));
4733-
47344740
GenTree* op1 = impPopStack().val;
47354741

47364742
op1 = impImplicitR4orR8Cast(op1, fromType);

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2941,6 +2941,13 @@ private bool isExactType(CORINFO_CLASS_STRUCT_* cls)
29412941
return _compilation.IsEffectivelySealed(type);
29422942
}
29432943

2944+
private TypeCompareState isNullableType(CORINFO_CLASS_STRUCT_* cls)
2945+
{
2946+
TypeDesc type = HandleToObject(cls);
2947+
2948+
return type.IsNullable ? TypeCompareState.Must : TypeCompareState.MustNot;
2949+
}
2950+
29442951
private TypeCompareState isEnum(CORINFO_CLASS_STRUCT_* cls, CORINFO_CLASS_STRUCT_** underlyingType)
29452952
{
29462953
Debug.Assert(cls != null);

src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs

Lines changed: 110 additions & 94 deletions
Large diffs are not rendered by default.

src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ FUNCTIONS
244244
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
245245
bool isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
246246
bool isExactType(CORINFO_CLASS_HANDLE cls)
247+
TypeCompareState isNullableType(CORINFO_CLASS_HANDLE cls)
247248
TypeCompareState isEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType)
248249
CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls)
249250
CorInfoType getChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet)

src/coreclr/tools/aot/jitinterface/jitinterface_generated.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct JitInterfaceCallbacks
9292
TypeCompareState (* compareTypesForEquality)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
9393
bool (* isMoreSpecificType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
9494
bool (* isExactType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
95+
TypeCompareState (* isNullableType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
9596
TypeCompareState (* isEnum)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType);
9697
CORINFO_CLASS_HANDLE (* getParentType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls);
9798
CorInfoType (* getChildType)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet);
@@ -992,6 +993,15 @@ class JitInterfaceWrapper : public ICorJitInfo
992993
return temp;
993994
}
994995

996+
virtual TypeCompareState isNullableType(
997+
CORINFO_CLASS_HANDLE cls)
998+
{
999+
CorInfoExceptionClass* pException = nullptr;
1000+
TypeCompareState temp = _callbacks->isNullableType(_thisHandle, &pException, cls);
1001+
if (pException != nullptr) throw pException;
1002+
return temp;
1003+
}
1004+
9951005
virtual TypeCompareState isEnum(
9961006
CORINFO_CLASS_HANDLE cls,
9971007
CORINFO_CLASS_HANDLE* underlyingType)

src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ LWM(PrintMethodName, DWORDLONG, Agnostic_PrintResult)
158158
LWM(IsValueClass, DWORDLONG, DWORD)
159159
LWM(IsMoreSpecificType, DLDL, DWORD)
160160
LWM(IsExactType, DWORDLONG, DWORD)
161+
LWM(IsNullableType, DWORDLONG, DWORD)
161162
LWM(IsEnum, DWORDLONG, DLD)
162163
LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD)
163164
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5920,6 +5920,28 @@ bool MethodContext::repIsExactType(CORINFO_CLASS_HANDLE cls)
59205920
return value != 0;
59215921
}
59225922

5923+
void MethodContext::recIsNullableType(CORINFO_CLASS_HANDLE cls, TypeCompareState result)
5924+
{
5925+
if (IsNullableType == nullptr)
5926+
IsNullableType = new LightWeightMap<DWORDLONG, DWORD>();
5927+
5928+
DWORDLONG key = CastHandle(cls);
5929+
DWORD value = (DWORD)result;
5930+
IsNullableType->Add(key, value);
5931+
DEBUG_REC(dmpIsNullableType(key, value));
5932+
}
5933+
void MethodContext::dmpIsNullableType(DWORDLONG key, DWORD value)
5934+
{
5935+
printf("IsNullableType key cls-%016" PRIX64 ", value res-%d", key, value);
5936+
}
5937+
TypeCompareState MethodContext::repIsNullableType(CORINFO_CLASS_HANDLE cls)
5938+
{
5939+
DWORDLONG key = CastHandle(cls);
5940+
DWORD value = LookupByKeyOrMiss(IsNullableType, key, ": key %016" PRIX64 "", key);
5941+
DEBUG_REP(dmpIsNullableType(key, value));
5942+
return (TypeCompareState)value;
5943+
}
5944+
59235945
void MethodContext::recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result)
59245946
{
59255947
if (IsEnum == nullptr)

src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,10 @@ class MethodContext
723723
void dmpIsExactType(DWORDLONG key, DWORD value);
724724
bool repIsExactType(CORINFO_CLASS_HANDLE cls);
725725

726+
void recIsNullableType(CORINFO_CLASS_HANDLE cls, TypeCompareState result);
727+
void dmpIsNullableType(DWORDLONG key, DWORD value);
728+
TypeCompareState repIsNullableType(CORINFO_CLASS_HANDLE cls);
729+
726730
void recIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE underlyingType, TypeCompareState result);
727731
void dmpIsEnum(DWORDLONG key, DLD value);
728732
TypeCompareState repIsEnum(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE* underlyingType);
@@ -1165,6 +1169,7 @@ enum mcPackets
11651169
Packet_NotifyMethodInfoUsage = 214,
11661170
Packet_IsExactType = 215,
11671171
Packet_GetSwiftLowering = 216,
1172+
Packet_IsNullableType = 217,
11681173
};
11691174

11701175
void SetDebugDumpVariables();

src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,15 @@ bool interceptor_ICJI::isExactType(CORINFO_CLASS_HANDLE cls)
914914
return temp;
915915
}
916916

917+
// Returns whether a class handle represents a Nullable type, if that can be statically determined.
918+
TypeCompareState interceptor_ICJI::isNullableType(CORINFO_CLASS_HANDLE cls)
919+
{
920+
mc->cr->AddCall("isNullableType");
921+
TypeCompareState temp = original_ICorJitInfo->isNullableType(cls);
922+
mc->recIsNullableType(cls, temp);
923+
return temp;
924+
}
925+
917926
// Returns TypeCompareState::Must if cls is known to be an enum.
918927
// For enums with known exact type returns the underlying
919928
// type in underlyingType when the provided pointer is

src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,13 @@ bool interceptor_ICJI::isExactType(
659659
return original_ICorJitInfo->isExactType(cls);
660660
}
661661

662+
TypeCompareState interceptor_ICJI::isNullableType(
663+
CORINFO_CLASS_HANDLE cls)
664+
{
665+
mcs->AddCall("isNullableType");
666+
return original_ICorJitInfo->isNullableType(cls);
667+
}
668+
662669
TypeCompareState interceptor_ICJI::isEnum(
663670
CORINFO_CLASS_HANDLE cls,
664671
CORINFO_CLASS_HANDLE* underlyingType)

src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,12 @@ bool interceptor_ICJI::isExactType(
578578
return original_ICorJitInfo->isExactType(cls);
579579
}
580580

581+
TypeCompareState interceptor_ICJI::isNullableType(
582+
CORINFO_CLASS_HANDLE cls)
583+
{
584+
return original_ICorJitInfo->isNullableType(cls);
585+
}
586+
581587
TypeCompareState interceptor_ICJI::isEnum(
582588
CORINFO_CLASS_HANDLE cls,
583589
CORINFO_CLASS_HANDLE* underlyingType)

src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,13 @@ bool MyICJI::isExactType(CORINFO_CLASS_HANDLE cls)
764764
return jitInstance->mc->repIsExactType(cls);
765765
}
766766

767+
// Returns true if a class handle represents a Nullable type.
768+
TypeCompareState MyICJI::isNullableType(CORINFO_CLASS_HANDLE cls)
769+
{
770+
jitInstance->mc->cr->AddCall("isNullableType");
771+
return jitInstance->mc->repIsNullableType(cls);
772+
}
773+
767774
// Returns TypeCompareState::Must if cls is known to be an enum.
768775
// For enums with known exact type returns the underlying
769776
// type in underlyingType when the provided pointer is

src/coreclr/vm/jitinterface.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4658,6 +4658,31 @@ bool CEEInfo::isExactType(CORINFO_CLASS_HANDLE cls)
46584658
return result;
46594659
}
46604660

4661+
// Returns whether a class handle represents a Nullable type, if that can be statically determined.
4662+
TypeCompareState CEEInfo::isNullableType(CORINFO_CLASS_HANDLE cls)
4663+
{
4664+
CONTRACTL {
4665+
THROWS;
4666+
GC_TRIGGERS;
4667+
MODE_PREEMPTIVE;
4668+
} CONTRACTL_END;
4669+
4670+
TypeHandle typeHandle = TypeHandle();
4671+
4672+
TypeCompareState result = TypeCompareState::May;
4673+
4674+
JIT_TO_EE_TRANSITION();
4675+
4676+
if (typeHandle != TypeHandle(g_pCanonMethodTableClass))
4677+
{
4678+
TypeHandle VMClsHnd(cls);
4679+
result = Nullable::IsNullableType(VMClsHnd) ? TypeCompareState::Must : TypeCompareState::MustNot;
4680+
}
4681+
4682+
EE_TO_JIT_TRANSITION();
4683+
return result;
4684+
}
4685+
46614686
/*********************************************************************/
46624687
// Returns TypeCompareState::Must if cls is known to be an enum.
46634688
// For enums with known exact type returns the underlying

0 commit comments

Comments
 (0)