From 049c59e4092d82b719bb7931812b463781678ce8 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 18:48:03 +0900 Subject: [PATCH 01/10] Give Activator.CreateInstance an exact type --- src/coreclr/jit/gentree.cpp | 16 ++++++++++++++++ src/coreclr/jit/importercalls.cpp | 12 ++++++++++++ src/coreclr/jit/namedintrinsiclist.h | 1 + 3 files changed, 29 insertions(+) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 81d50ebbc9cc94..074c71b44369bc 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20828,6 +20828,22 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); break; } + if (ni == NI_System_Activator_CreateInstance_T) + { + CallArg* instArg = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); + if (instArg != nullptr && instArg->GetNode()->IsIconHandle()) + { + CORINFO_SIG_INFO methodSig; + eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->IconValue(), &methodSig); + if (methodSig.sigInst.methInstCount == 1) + { + objClass = methodSig.sigInst.methInst[0]; + *pIsExact = !eeIsSharedInst(objClass); + *pIsNonNull = true; + } + } + break; + } CORINFO_CLASS_HANDLE specialObjClass = impGetSpecialIntrinsicExactReturnType(call); if (specialObjClass != nullptr) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index a0340343c58c44..91d90a63d20dca 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3898,6 +3898,12 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, break; } + case NI_System_Activator_CreateInstance_T: + { + isSpecial = true; + break; + } + case NI_System_Span_get_Item: case NI_System_ReadOnlySpan_get_Item: { @@ -10659,6 +10665,8 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) const char* methodName = info.compCompHnd->getMethodNameFromMetadata(method, &className, &namespaceName, enclosingClassNames, ArrLen(enclosingClassNames)); + CORINFO_SIG_INFO sig; + eeGetMethodSig(method, &sig); JITDUMP("Named Intrinsic "); @@ -10726,6 +10734,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Activator_AllocatorOf; } + else if (strcmp(methodName, "CreateInstance") == 0 && sig.hasTypeArg()) + { + result = NI_System_Activator_CreateInstance_T; + } else if (strcmp(methodName, "DefaultConstructorOf") == 0) { result = NI_System_Activator_DefaultConstructorOf; diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index 5f96a30903d1d2..7c9028e9fdffd8 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -100,6 +100,7 @@ enum NamedIntrinsic : unsigned short NI_System_Type_op_Inequality, NI_System_Type_GetTypeFromHandle, NI_System_Type_GetGenericTypeDefinition, + NI_System_Activator_CreateInstance_T, NI_System_Array_Clone, NI_System_Array_GetLength, NI_System_Array_GetLowerBound, From 3e14c52841cca46ea9ce8436acbd10e6281f60e6 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:13:00 +0900 Subject: [PATCH 02/10] Use GetCompileTimeHandle --- src/coreclr/jit/gentree.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 074c71b44369bc..fe61d0d59fd133 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20834,7 +20834,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if (instArg != nullptr && instArg->GetNode()->IsIconHandle()) { CORINFO_SIG_INFO methodSig; - eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->IconValue(), &methodSig); + eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->GetCompileTimeHandle(), + &methodSig); if (methodSig.sigInst.methInstCount == 1) { objClass = methodSig.sigInst.methInst[0]; From 07a0d522226a29000efcac1007da6c1589900038 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:16:43 +0900 Subject: [PATCH 03/10] Merge into impGetSpecialIntrinsicExactReturnType --- src/coreclr/jit/gentree.cpp | 17 ----------------- src/coreclr/jit/importercalls.cpp | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index fe61d0d59fd133..81d50ebbc9cc94 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20828,23 +20828,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); break; } - if (ni == NI_System_Activator_CreateInstance_T) - { - CallArg* instArg = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); - if (instArg != nullptr && instArg->GetNode()->IsIconHandle()) - { - CORINFO_SIG_INFO methodSig; - eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->GetCompileTimeHandle(), - &methodSig); - if (methodSig.sigInst.methInstCount == 1) - { - objClass = methodSig.sigInst.methInst[0]; - *pIsExact = !eeIsSharedInst(objClass); - *pIsNonNull = true; - } - } - break; - } CORINFO_CLASS_HANDLE specialObjClass = impGetSpecialIntrinsicExactReturnType(call); if (specialObjClass != nullptr) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 91d90a63d20dca..b3e307f0e457db 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -9995,6 +9995,26 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall break; } + case NI_System_Activator_CreateInstance_T: + { + CallArg* instArg = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); + if (instArg != nullptr && instArg->GetNode()->IsIconHandle()) + { + CORINFO_SIG_INFO methodSig; + eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->GetCompileTimeHandle(), + &methodSig); + if (methodSig.sigInst.methInstCount == 1) + { + CORINFO_CLASS_HANDLE objClass = methodSig.sigInst.methInst[0]; + if (!eeIsSharedInst(objClass)) + { + result = objClass; + } + } + } + break; + } + default: { JITDUMP("This special intrinsic not handled, sorry...\n"); From 9c98d36d9720ac54933233428ec6343445c438f7 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:21:49 +0900 Subject: [PATCH 04/10] Address feedbacks --- src/coreclr/jit/importercalls.cpp | 39 ++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index b3e307f0e457db..f6cbf64d4e5231 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -9997,21 +9997,38 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall case NI_System_Activator_CreateInstance_T: { - CallArg* instArg = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); - if (instArg != nullptr && instArg->GetNode()->IsIconHandle()) + // Expect one method generic parameter; figure out which it is. + CORINFO_SIG_INFO sig; + info.compCompHnd->getMethodSig(methodHnd, &sig); + assert(sig.sigInst.methInstCount == 1); + assert(sig.sigInst.classInstCount == 0); + + CORINFO_CLASS_HANDLE typeHnd = sig.sigInst.methInst[0]; + assert(typeHnd != nullptr); + + CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); + if (instParam != nullptr) { - CORINFO_SIG_INFO methodSig; - eeGetMethodSig((CORINFO_METHOD_HANDLE)instArg->GetNode()->AsIntCon()->GetCompileTimeHandle(), - &methodSig); - if (methodSig.sigInst.methInstCount == 1) + assert(instParam->GetNext() == nullptr); + CORINFO_METHOD_HANDLE hMethod = gtGetHelperArgMethodHandle(instParam->GetNode()); + if (hMethod != NO_METHOD_HANDLE) { - CORINFO_CLASS_HANDLE objClass = methodSig.sigInst.methInst[0]; - if (!eeIsSharedInst(objClass)) - { - result = objClass; - } + typeHnd = getMethodInstantiationArgument(hMethod, 0); } } + + result = eeIsSharedInst(typeHnd) ? NO_CLASS_HANDLE : typeHnd; + + if (result != NO_CLASS_HANDLE) + { + JITDUMP("Special intrinsic for type %s: return type is %s\n", eeGetClassName(typeHnd), + result != nullptr ? eeGetClassName(result) : "unknown"); + } + else + { + JITDUMP("Special intrinsic for type %s: return type undetermined or inexact, so deferring opt\n", + eeGetClassName(typeHnd)); + } break; } From c734d5b4d7afda0d26ee638ba4e94cb702f81e81 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:24:05 +0900 Subject: [PATCH 05/10] Avoid unconditionally calling eeGetMethodSig --- src/coreclr/jit/importercalls.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index f6cbf64d4e5231..d05374350b8b14 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10702,8 +10702,6 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) const char* methodName = info.compCompHnd->getMethodNameFromMetadata(method, &className, &namespaceName, enclosingClassNames, ArrLen(enclosingClassNames)); - CORINFO_SIG_INFO sig; - eeGetMethodSig(method, &sig); JITDUMP("Named Intrinsic "); @@ -10771,9 +10769,14 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { result = NI_System_Activator_AllocatorOf; } - else if (strcmp(methodName, "CreateInstance") == 0 && sig.hasTypeArg()) + else if (strcmp(methodName, "CreateInstance") == 0) { - result = NI_System_Activator_CreateInstance_T; + CORINFO_SIG_INFO sig; + eeGetMethodSig(method, &sig); + if (sig.hasTypeArg()) + { + result = NI_System_Activator_CreateInstance_T; + } } else if (strcmp(methodName, "DefaultConstructorOf") == 0) { From 0df5fd7f9af427b18658ffbf809509d87a930254 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:32:25 +0900 Subject: [PATCH 06/10] Nit --- src/coreclr/jit/importercalls.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index d05374350b8b14..02bf8288e579f8 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10021,13 +10021,12 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall if (result != NO_CLASS_HANDLE) { - JITDUMP("Special intrinsic for type %s: return type is %s\n", eeGetClassName(typeHnd), + JITDUMP("Special intrinsic: return type is %s\n", result != nullptr ? eeGetClassName(result) : "unknown"); } else { - JITDUMP("Special intrinsic for type %s: return type undetermined or inexact, so deferring opt\n", - eeGetClassName(typeHnd)); + JITDUMP("Special intrinsic: return type undetermined or inexact, so deferring opt\n"); } break; } From bda47cc59e2a0311eebe9ac0fb318e5db1669d1f Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:35:03 +0900 Subject: [PATCH 07/10] Don't fail for Canon --- src/coreclr/jit/importercalls.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 02bf8288e579f8..2d4d65709c5d72 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10003,8 +10003,8 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall assert(sig.sigInst.methInstCount == 1); assert(sig.sigInst.classInstCount == 0); - CORINFO_CLASS_HANDLE typeHnd = sig.sigInst.methInst[0]; - assert(typeHnd != nullptr); + CORINFO_CLASS_HANDLE result = sig.sigInst.methInst[0]; + assert(result != nullptr); CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); if (instParam != nullptr) @@ -10013,12 +10013,10 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall CORINFO_METHOD_HANDLE hMethod = gtGetHelperArgMethodHandle(instParam->GetNode()); if (hMethod != NO_METHOD_HANDLE) { - typeHnd = getMethodInstantiationArgument(hMethod, 0); + result = getMethodInstantiationArgument(hMethod, 0); } } - result = eeIsSharedInst(typeHnd) ? NO_CLASS_HANDLE : typeHnd; - if (result != NO_CLASS_HANDLE) { JITDUMP("Special intrinsic: return type is %s\n", From 81dd80feb46074c1416c6e572c3c9abcf54e9a09 Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:44:01 +0900 Subject: [PATCH 08/10] Address more feedbacks --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 2d4d65709c5d72..32cc8571bad9ef 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10770,7 +10770,7 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) { CORINFO_SIG_INFO sig; eeGetMethodSig(method, &sig); - if (sig.hasTypeArg()) + if ((sig.sigInst.methInstCount == 1) && (sig.sigInst.classInstCount == 0)) { result = NI_System_Activator_CreateInstance_T; } From ab2f0fc75f6e95c0fc6a800a4ed9712ec9cbb6ec Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:46:42 +0900 Subject: [PATCH 09/10] Oops --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 32cc8571bad9ef..7927cfe6903dce 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10003,7 +10003,7 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall assert(sig.sigInst.methInstCount == 1); assert(sig.sigInst.classInstCount == 0); - CORINFO_CLASS_HANDLE result = sig.sigInst.methInst[0]; + result = sig.sigInst.methInst[0]; assert(result != nullptr); CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); From b157a3a81e98f1c5fabcd04f042a8b4e972681ec Mon Sep 17 00:00:00 2001 From: Steven He Date: Wed, 1 Jul 2026 19:58:34 +0900 Subject: [PATCH 10/10] Nit --- src/coreclr/jit/importercalls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 7927cfe6903dce..7955788e1f6010 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -10003,8 +10003,8 @@ CORINFO_CLASS_HANDLE Compiler::impGetSpecialIntrinsicExactReturnType(GenTreeCall assert(sig.sigInst.methInstCount == 1); assert(sig.sigInst.classInstCount == 0); - result = sig.sigInst.methInst[0]; - assert(result != nullptr); + CORINFO_CLASS_HANDLE typeHnd = sig.sigInst.methInst[0]; + assert(typeHnd != nullptr); CallArg* instParam = call->gtArgs.FindWellKnownArg(WellKnownArg::InstParam); if (instParam != nullptr)