[RyuJIT] Fix get_ManagedThreadId(get_CurrentThread) optimization (convert to NI)...
authorEgor Bogatov <egorbo@gmail.com>
Tue, 10 Nov 2020 14:54:09 +0000 (17:54 +0300)
committerGitHub <noreply@github.com>
Tue, 10 Nov 2020 14:54:09 +0000 (06:54 -0800)
* Convert get_ManagedThreadId(get_CurrentThread) optimization to NamedIntrinsics

* drop CORINFO_HELP_INTERNALTHROW and CORINFO_HELP_SEC_UNMGDCODE_EXCPT

19 files changed:
src/coreclr/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs
src/coreclr/src/inc/corinfo.h
src/coreclr/src/inc/jithelpers.h
src/coreclr/src/inc/readytorun.h
src/coreclr/src/inc/readytorunhelpers.h
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/morph.cpp
src/coreclr/src/jit/namedintrinsiclist.h
src/coreclr/src/jit/utils.cpp
src/coreclr/src/tools/Common/Internal/Runtime/ReadyToRunConstants.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoHelpFunc.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs
src/coreclr/src/tools/aot/jitinterface/jitwrapper.cpp
src/coreclr/src/vm/ecalllist.h
src/coreclr/src/vm/jithelpers.cpp
src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs

index cc894d2..dc8a82c 100644 (file)
@@ -165,6 +165,7 @@ namespace System.Threading
 
         public extern int ManagedThreadId
         {
+            [Intrinsic]
             [MethodImpl(MethodImplOptions.InternalCall)]
             get;
         }
index e1ddd17..76be79c 100644 (file)
@@ -208,11 +208,11 @@ TODO: Talk about initializing strutures before use
 //
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-constexpr GUID JITEEVersionIdentifier = { /* 062114d0-bd20-483f-8a3e-c4ee39706ae8 */
-    0x062114d0,
-    0xbd20,
-    0x483f,
-    {0x8a, 0x3e, 0xc4, 0xee, 0x39, 0x70, 0x6a, 0xe8}
+constexpr GUID JITEEVersionIdentifier = { /* a0184d06-a562-43f6-94ad-44627db87310 */
+    0xa0184d06,
+    0xa562,
+    0x43f6,
+    {0x94, 0xad, 0x44, 0x62, 0x7d, 0xb8, 0x73, 0x10}
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -431,9 +431,7 @@ enum CorInfoHelpFunc
     CORINFO_HELP_THROWDIVZERO,      // throw a divide by zero exception
     CORINFO_HELP_THROWNULLREF,      // throw a null reference exception
 
-    CORINFO_HELP_INTERNALTHROW,     // Support for really fast jit
     CORINFO_HELP_VERIFICATION,      // Throw a VerificationException
-    CORINFO_HELP_SEC_UNMGDCODE_EXCPT, // throw a security unmanaged code exception
     CORINFO_HELP_FAIL_FAST,         // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
 
     CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
@@ -918,8 +916,6 @@ enum CorInfoIntrinsics
     CORINFO_INTRINSIC_InterlockedCmpXchg64,
     CORINFO_INTRINSIC_MemoryBarrier,
     CORINFO_INTRINSIC_MemoryBarrierLoad,
-    CORINFO_INTRINSIC_GetCurrentManagedThread,
-    CORINFO_INTRINSIC_GetManagedThreadId,
     CORINFO_INTRINSIC_ByReference_Ctor,
     CORINFO_INTRINSIC_ByReference_Value,
     CORINFO_INTRINSIC_Span_GetItem,
index 5e863e1..a1f6878 100644 (file)
     JITHELPER(CORINFO_HELP_OVERFLOW,            JIT_Overflow,       CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_THROWDIVZERO,        JIT_ThrowDivZero,   CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_THROWNULLREF,        JIT_ThrowNullRef,   CORINFO_HELP_SIG_REG_ONLY)
-    JITHELPER(CORINFO_HELP_INTERNALTHROW,       JIT_InternalThrow,  CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_VERIFICATION,        IL_VerificationError,CORINFO_HELP_SIG_REG_ONLY)
-    JITHELPER(CORINFO_HELP_SEC_UNMGDCODE_EXCPT, JIT_SecurityUnmanagedCodeException, CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_FAIL_FAST,           JIT_FailFast,       CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_METHOD_ACCESS_EXCEPTION,JIT_ThrowMethodAccessException, CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_FIELD_ACCESS_EXCEPTION,JIT_ThrowFieldAccessException, CORINFO_HELP_SIG_REG_ONLY)
index 9f79c89..84d3a81 100644 (file)
@@ -365,6 +365,8 @@ enum ReadyToRunHelper
 
     // Stack probing helper
     READYTORUN_HELPER_StackProbe                = 0x111,
+
+    READYTORUN_HELPER_GetCurrentManagedThreadId = 0x112,
 };
 
 #include "readytoruninstructionset.h"
index 465b603..ea3ea68 100644 (file)
@@ -123,5 +123,7 @@ HELPER(READYTORUN_HELPER_MonitorExit,               CORINFO_HELP_MON_EXIT,
 HELPER(READYTORUN_HELPER_StackProbe,                CORINFO_HELP_STACK_PROBE,                       )
 #endif
 
+HELPER(READYTORUN_HELPER_GetCurrentManagedThreadId, CORINFO_HELP_GETCURRENTMANAGEDTHREADID,         )
+
 #undef HELPER
 #undef OPTIMIZEFORSPEED
index d5b909d..1ef8630 100644 (file)
@@ -4189,14 +4189,6 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
             break;
         }
 
-        case CORINFO_INTRINSIC_GetCurrentManagedThread:
-        case CORINFO_INTRINSIC_GetManagedThreadId:
-        {
-            // Retry optimizing these during morph
-            isSpecial = true;
-            break;
-        }
-
         default:
             /* Unknown intrinsic */
             intrinsicID = CORINFO_INTRINSIC_Illegal;
@@ -4279,6 +4271,25 @@ GenTree* Compiler::impIntrinsic(GenTree*                newobjThis,
                 break;
             }
 
+            case NI_System_Threading_Thread_get_ManagedThreadId:
+            {
+                if (opts.OptimizationEnabled() && impStackTop().val->OperIs(GT_RET_EXPR))
+                {
+                    GenTreeCall* call = impStackTop().val->AsRetExpr()->gtInlineCandidate->AsCall();
+                    if (call->gtFlags & CORINFO_FLG_JIT_INTRINSIC)
+                    {
+                        if (lookupNamedIntrinsic(call->gtCallMethHnd) == NI_System_Threading_Thread_get_CurrentThread)
+                        {
+                            // drop get_CurrentThread() call
+                            impPopStack();
+                            call->ReplaceWith(gtNewNothingNode(), this);
+                            retNode = gtNewHelperCallNode(CORINFO_HELP_GETCURRENTMANAGEDTHREADID, TYP_INT);
+                        }
+                    }
+                }
+                break;
+            }
+
 #ifdef FEATURE_HW_INTRINSICS
             case NI_System_Math_FusedMultiplyAdd:
             {
@@ -4767,6 +4778,20 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
             }
         }
     }
+    else if (strcmp(namespaceName, "System.Threading") == 0)
+    {
+        if (strcmp(className, "Thread") == 0)
+        {
+            if (strcmp(methodName, "get_CurrentThread") == 0)
+            {
+                result = NI_System_Threading_Thread_get_CurrentThread;
+            }
+            else if (strcmp(methodName, "get_ManagedThreadId") == 0)
+            {
+                result = NI_System_Threading_Thread_get_ManagedThreadId;
+            }
+        }
+    }
 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
     else if (strcmp(namespaceName, "System.Buffers.Binary") == 0)
     {
index e172a9c..2679b45 100644 (file)
@@ -9086,26 +9086,6 @@ GenTree* Compiler::fgMorphCall(GenTreeCall* call)
         }
     }
 
-    // Optimize get_ManagedThreadId(get_CurrentThread)
-    if ((call->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC) &&
-        info.compCompHnd->getIntrinsicID(call->gtCallMethHnd) == CORINFO_INTRINSIC_GetManagedThreadId)
-    {
-        noway_assert(origDest == nullptr);
-        noway_assert(call->gtCallLateArgs->GetNode() != nullptr);
-
-        GenTree* innerCall = call->gtCallLateArgs->GetNode();
-
-        if (innerCall->gtOper == GT_CALL && (innerCall->AsCall()->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC) &&
-            info.compCompHnd->getIntrinsicID(innerCall->AsCall()->gtCallMethHnd) ==
-                CORINFO_INTRINSIC_GetCurrentManagedThread)
-        {
-            // substitute expression with call to helper
-            GenTree* newCall = gtNewHelperCallNode(CORINFO_HELP_GETCURRENTMANAGEDTHREADID, TYP_INT);
-            JITDUMP("get_ManagedThreadId(get_CurrentThread) folding performed\n");
-            return fgMorphTree(newCall);
-        }
-    }
-
     if (origDest != nullptr)
     {
         GenTree* retValVarAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, gtNewLclvNode(retValTmpNum, TYP_STRUCT));
index 3040446..5c31fb8 100644 (file)
@@ -38,6 +38,8 @@ enum NamedIntrinsic : unsigned short
     NI_System_Buffers_Binary_BinaryPrimitives_ReverseEndianness,
     NI_System_Numerics_BitOperations_PopCount,
     NI_System_GC_KeepAlive,
+    NI_System_Threading_Thread_get_CurrentThread,
+    NI_System_Threading_Thread_get_ManagedThreadId,
     NI_System_Type_get_IsValueType,
     NI_System_Type_IsAssignableFrom,
     NI_System_Type_IsAssignableTo,
index 133b49f..1f041a3 100644 (file)
@@ -1336,7 +1336,7 @@ void HelperCallProperties::init()
                 break;
 
             case CORINFO_HELP_ARE_TYPES_EQUIVALENT:
-
+            case CORINFO_HELP_GETCURRENTMANAGEDTHREADID:
                 isPure  = true;
                 noThrow = true;
                 break;
@@ -1473,7 +1473,6 @@ void HelperCallProperties::init()
             case CORINFO_HELP_INIT_PINVOKE_FRAME:
             case CORINFO_HELP_JIT_PINVOKE_BEGIN:
             case CORINFO_HELP_JIT_PINVOKE_END:
-            case CORINFO_HELP_GETCURRENTMANAGEDTHREADID:
 
                 noThrow = true;
                 break;
index 6d92e7b..d579a65 100644 (file)
@@ -312,6 +312,8 @@ namespace Internal.ReadyToRunConstants
         TypeHandleToRuntimeType,
         GetRefAny,
         TypeHandleToRuntimeTypeHandle,
+
+        GetCurrentManagedThreadId,
     }
 
     // Enum used for HFA type recognition.
index 87fa09e..8f22b0c 100644 (file)
@@ -104,9 +104,7 @@ namespace Internal.JitInterface
         CORINFO_HELP_THROWDIVZERO,      // throw a divide by zero exception
         CORINFO_HELP_THROWNULLREF,      // throw a null reference exception
 
-        CORINFO_HELP_INTERNALTHROW,     // Support for really fast jit
         CORINFO_HELP_VERIFICATION,      // Throw a VerificationException
-        CORINFO_HELP_SEC_UNMGDCODE_EXCPT, // throw a security unmanaged code exception
         CORINFO_HELP_FAIL_FAST,         // Kill the process avoiding any exceptions or stack and data dependencies (use for GuardStack unsafe buffer checks)
 
         CORINFO_HELP_METHOD_ACCESS_EXCEPTION,//Throw an access exception due to a failed member/class access check.
index 46cac9f..2f53520 100644 (file)
@@ -103,8 +103,6 @@ namespace Internal.JitInterface
             // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg64, "CompareExchange", "System.Threading", "Interlocked"); // ambiguous match
             table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_MemoryBarrier, "MemoryBarrier", "System.Threading", "Interlocked");
             table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_MemoryBarrierLoad, "LoadBarrier", "System.Threading", "Interlocked");
-            // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetCurrentManagedThread, "GetCurrentThreadNative", "System", "Thread"); // not in .NET Core
-            // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetManagedThreadId, "get_ManagedThreadId", "System", "Thread"); // not in .NET Core
             table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Ctor, ".ctor", "System", "ByReference`1");
             table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Value, "get_Value", "System", "ByReference`1");
             table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_Span_GetItem, "get_Item", "System", "Span`1");
index 01add8f..de9e108 100644 (file)
@@ -415,8 +415,6 @@ namespace Internal.JitInterface
         CORINFO_INTRINSIC_InterlockedCmpXchg64,
         CORINFO_INTRINSIC_MemoryBarrier,
         CORINFO_INTRINSIC_MemoryBarrierLoad,
-        CORINFO_INTRINSIC_GetCurrentManagedThread,
-        CORINFO_INTRINSIC_GetManagedThreadId,
         CORINFO_INTRINSIC_ByReference_Ctor,
         CORINFO_INTRINSIC_ByReference_Value,
         CORINFO_INTRINSIC_Span_GetItem,
index 67a9f9e..90f7658 100644 (file)
@@ -788,6 +788,10 @@ namespace Internal.JitInterface
                     id = ReadyToRunHelper.GCPoll;
                     break;
 
+                case CorInfoHelpFunc.CORINFO_HELP_GETCURRENTMANAGEDTHREADID:
+                    id = ReadyToRunHelper.GetCurrentManagedThreadId;
+                    break;
+
                 case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER:
                     id = ReadyToRunHelper.ReversePInvokeEnter;
                     break;
index a6ff0e7..6c6b2f0 100644 (file)
@@ -1610,6 +1610,10 @@ namespace ILCompiler.Reflection.ReadyToRun
                     builder.Append("GCPOLL");
                     break;
 
+                case ReadyToRunHelper.GetCurrentManagedThreadId:
+                    builder.Append("GET_CURRENT_MANAGED_THREAD_ID");
+                    break;
+
                 case ReadyToRunHelper.ReversePInvokeEnter:
                     builder.Append("REVERSE_PINVOKE_ENTER");
                     break;
index cf21e76..34cb996 100644 (file)
@@ -26,11 +26,11 @@ private:
     uint64_t corJitFlags;
 };
 
-static const GUID JITEEVersionIdentifier = { /* 062114d0-bd20-483f-8a3e-c4ee39706ae8 */
-    0x062114d0,
-    0xbd20,
-    0x483f,
-    {0x8a, 0x3e, 0xc4, 0xee, 0x39, 0x70, 0x6a, 0xe8}
+static const GUID JITEEVersionIdentifier = { /* a0184d06-a562-43f6-94ad-44627db87310 */
+    0xa0184d06,
+    0xa562,
+    0x43f6,
+    {0x94, 0xad, 0x44, 0x62, 0x7d, 0xb8, 0x73, 0x10}
 };
 
 class Jit
index 804c061..d24d0dc 100644 (file)
@@ -598,8 +598,8 @@ FCFuncStart(gThreadFuncs)
     QCFuncElement("InformThreadNameChange", ThreadNative::InformThreadNameChange)
     FCFuncElement("SpinWaitInternal", ThreadNative::SpinWait)
     QCFuncElement("YieldInternal", ThreadNative::YieldThread)
-    FCIntrinsic("GetCurrentThreadNative", ThreadNative::GetCurrentThread, CORINFO_INTRINSIC_GetCurrentManagedThread)
-    FCIntrinsic("get_ManagedThreadId", ThreadNative::GetManagedThreadId, CORINFO_INTRINSIC_GetManagedThreadId)
+    FCFuncElement("GetCurrentThreadNative", ThreadNative::GetCurrentThread)
+    FCFuncElement("get_ManagedThreadId", ThreadNative::GetManagedThreadId)
     FCFuncElement("InternalFinalize", ThreadNative::Finalize)
 #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
     FCFuncElement("StartupSetApartmentStateInternal", ThreadNative::StartupSetApartmentState)
index 435f8ca..0df65b9 100644 (file)
@@ -4399,21 +4399,6 @@ HCIMPL1(void, IL_VerificationError,  int ilOffset)
 HCIMPLEND
 
 /*********************************************************************/
-HCIMPL1(void, JIT_SecurityUnmanagedCodeException, CORINFO_CLASS_HANDLE typeHnd_)
-{
-    FCALL_CONTRACT;
-
-    FC_GC_POLL_NOT_NEEDED();    // throws always open up for GC
-
-    HELPER_METHOD_FRAME_BEGIN_ATTRIB_NOPOLL(Frame::FRAME_ATTR_EXCEPTION);    // Set up a frame
-
-    COMPlusThrow(kSecurityException);
-
-    HELPER_METHOD_FRAME_END();
-}
-HCIMPLEND
-
-/*********************************************************************/
 static RuntimeExceptionKind MapCorInfoExceptionToRuntimeExceptionKind(unsigned exceptNum)
 {
     LIMITED_METHOD_CONTRACT;
index 2da41c6..0bfcc94 100644 (file)
@@ -155,7 +155,14 @@ namespace System.Threading
             }
         }
 
-        public static Thread CurrentThread => t_currentThread ?? InitializeCurrentThread();
+        public static Thread CurrentThread
+        {
+            [Intrinsic]
+            get
+            {
+                return t_currentThread ?? InitializeCurrentThread();
+            }
+        }
 
         public ExecutionContext? ExecutionContext => ExecutionContext.Capture();