Fix JITEEInterface::IsValueClass to return false for pointers. (#50749)
authorSergey Andreenko <seandree@microsoft.com>
Tue, 13 Apr 2021 07:42:50 +0000 (00:42 -0700)
committerGitHub <noreply@github.com>
Tue, 13 Apr 2021 07:42:50 +0000 (00:42 -0700)
* lets VM return `isValueClass=false` for pointers.

* fix assert and add a comment.

* fix diffs.

* fix crossgen2 part.

* Update JITEEVersionIdentifier.

src/coreclr/inc/jiteeversionguid.h
src/coreclr/jit/importer.cpp
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/vm/jitinterface.cpp

index cda7486..5e6a2ef 100644 (file)
@@ -16,7 +16,7 @@
 // Note that this file is parsed by some tools, namely superpmi.py, so make sure the first line is exactly
 // of the form:
 //
-//   constexpr GUID JITEEVersionIdentifier = { /* a7bb194e-4e7c-4850-af12-ea9f30ea5a13 */
+//   constexpr GUID JITEEVersionIdentifier = { /* 1776ab48-edfa-49be-a11f-ec216b28174c */
 //
 // (without the leading slashes or spaces).
 //
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
 #define GUID_DEFINED
 #endif // !GUID_DEFINED
 
-constexpr GUID JITEEVersionIdentifier = { /* a1f5e9a1-ee44-42f9-9319-e2a2dbf8c5c9 */
-    0xa1f5e9a1,
-    0xee44,
-    0x42f9,
-    {0x93, 0x19, 0xe2, 0xa2, 0xdb, 0xf8, 0xc5, 0xc9}
+constexpr GUID JITEEVersionIdentifier = { /* 1776ab48-edfa-49be-a11f-ec216b28174c */
+    0x1776ab48,
+    0xedfa,
+    0x49be,
+    {0xa1, 0x1f, 0xec, 0x21, 0x6b, 0x28, 0x17, 0x4c}
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
index 819e966..139d204 100644 (file)
@@ -16841,9 +16841,10 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode)
             impBashVarAddrsToI(op2);
             op2 = impImplicitIorI4Cast(op2, info.compRetType);
             op2 = impImplicitR4orR8Cast(op2, info.compRetType);
+            // Note that we allow TYP_I_IMPL<->TYP_BYREF transformation, but only TYP_I_IMPL<-TYP_REF.
             assertImp((genActualType(op2->TypeGet()) == genActualType(info.compRetType)) ||
-                      ((op2->TypeGet() == TYP_I_IMPL) && (info.compRetType == TYP_BYREF)) ||
-                      ((op2->TypeGet() == TYP_BYREF) && (info.compRetType == TYP_I_IMPL)) ||
+                      ((op2->TypeGet() == TYP_I_IMPL) && TypeIs(info.compRetType, TYP_BYREF)) ||
+                      (op2->TypeIs(TYP_BYREF, TYP_REF) && (info.compRetType == TYP_I_IMPL)) ||
                       (varTypeIsFloating(op2->gtType) && varTypeIsFloating(info.compRetType)) ||
                       (varTypeIsStruct(op2) && varTypeIsStruct(info.compRetType)));
 
@@ -16892,9 +16893,10 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode)
 
             if (returnType != originalCallType)
             {
-                // Allow TYP_BYREF to be returned as TYP_I_IMPL and vice versa
-                if (((returnType == TYP_BYREF) && (originalCallType == TYP_I_IMPL)) ||
-                    ((returnType == TYP_I_IMPL) && (originalCallType == TYP_BYREF)))
+                // Allow TYP_BYREF to be returned as TYP_I_IMPL and vice versa.
+                // Allow TYP_REF to be returned as TYP_I_IMPL and NOT vice verse.
+                if ((TypeIs(returnType, TYP_BYREF, TYP_REF) && (originalCallType == TYP_I_IMPL)) ||
+                    ((returnType == TYP_I_IMPL) && TypeIs(originalCallType, TYP_BYREF)))
                 {
                     JITDUMP("Allowing return type mismatch: have %s, needed %s\n", varTypeName(returnType),
                             varTypeName(originalCallType));
index 00a37e1..c138b95 100644 (file)
@@ -1580,8 +1580,7 @@ namespace Internal.JitInterface
 
         private bool isValueClass(CORINFO_CLASS_STRUCT_* cls)
         {
-            TypeDesc type = HandleToObject(cls);
-            return type.IsValueType || type.IsPointer || type.IsFunctionPointer;
+            return HandleToObject(cls).IsValueType;
         }
 
         private CorInfoInlineTypeCheck canInlineTypeCheck(CORINFO_CLASS_STRUCT_* cls, CorInfoInlineTypeCheckSource source)
@@ -1603,10 +1602,6 @@ namespace Internal.JitInterface
 
             CorInfoFlag result = (CorInfoFlag)0;
 
-            // CoreCLR uses UIntPtr in place of pointers here
-            if (type.IsPointer || type.IsFunctionPointer)
-                type = _compilation.TypeSystemContext.GetWellKnownType(WellKnownType.UIntPtr);
-
             var metadataType = type as MetadataType;
 
             // The array flag is used to identify the faked-up methods on
index 2423c48..dc8bdb9 100644 (file)
@@ -3772,11 +3772,7 @@ bool CEEInfo::isValueClass(CORINFO_CLASS_HANDLE clsHnd)
 
     _ASSERTE(clsHnd);
 
-    // Note that clsHnd.IsValueType() would not return what the JIT expects
-    // for corner cases like ELEMENT_TYPE_FNPTR
-    TypeHandle VMClsHnd(clsHnd);
-    MethodTable * pMT = VMClsHnd.GetMethodTable();
-    ret = (pMT != NULL) ? pMT->IsValueType() : false;
+    ret = TypeHandle(clsHnd).IsValueType();
 
     EE_TO_JIT_TRANSITION_LEAF();
 
@@ -3888,7 +3884,7 @@ uint32_t CEEInfo::getClassAttribsInternal (CORINFO_CLASS_HANDLE clsHnd)
         if (pMT->HasComponentSize())
             ret |= CORINFO_FLG_VAROBJSIZE;
 
-        if (pMT->IsValueType())
+        if (VMClsHnd.IsValueType())
         {
             ret |= CORINFO_FLG_VALUECLASS;