@@ -73,7 +73,7 @@ InterpreterMethodInfo::InterpreterMethodInfo(CEEInfo* comp, CORINFO_METHOD_INFO*
7373#if defined(_DEBUG)
7474 m_methName = ::eeGetMethodFullName (comp, methInfo->ftn , &clsName);
7575#else
76- m_methName = comp-> getMethodNameFromMetadata ( methInfo->ftn , &clsName, NULL , NULL );
76+ m_methName = getMethodName (comp, methInfo->ftn , &clsName);
7777#endif
7878 char * myClsName = new char [strlen (clsName) + 1 ];
7979 strcpy (myClsName, clsName);
@@ -752,7 +752,7 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
752752 if (!jmpCall)
753753 {
754754 const char * clsName;
755- const char * methName = comp-> getMethodNameFromMetadata ( info->ftn , &clsName, NULL , NULL );
755+ const char * methName = getMethodName (comp, info->ftn , &clsName);
756756 if ( !s_InterpretMeths.contains (methName, clsName, info->args .pSig )
757757 || s_InterpretMethsExclude.contains (methName, clsName, info->args .pSig ))
758758 {
@@ -9226,26 +9226,27 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
92269226 // Point A in our cycle count.
92279227
92289228
9229- // TODO: enable when NamedIntrinsic is available to interpreter
9230-
9231- /*
92329229 // Is the method an intrinsic? If so, and if it's one we've written special-case code for
92339230 // handle intrinsically.
9234- NamedIntrinsic intrinsicName ;
9231+ InterpreterNamedIntrinsics intrinsicId ;
92359232 {
92369233 GCX_PREEMP ();
9237- intrinsicName = getIntrinsicName( CORINFO_METHOD_HANDLE(methToCall), nullptr );
9234+ intrinsicId = getNamedIntrinsicID (&m_interpCeeInfo, CORINFO_METHOD_HANDLE (methToCall));
92389235 }
92399236
92409237#if INTERP_TRACING
9241- if (intrinsicName == NI_Illegal)
9238+ if (intrinsicId == NI_Illegal)
92429239 InterlockedIncrement (&s_totalInterpCallsToIntrinsics);
92439240#endif // INTERP_TRACING
92449241 bool didIntrinsic = false ;
92459242 if (!m_constrainedFlag)
92469243 {
92479244 switch (intrinsicId)
92489245 {
9246+ case NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference:
9247+ DoGetArrayDataReference ();
9248+ didIntrinsic = true ;
9249+ break ;
92499250#if INTERP_ILSTUBS
92509251 case NI_System_StubHelpers_GetStubContext:
92519252 OpStackSet<void *>(m_curStackHt, GetStubContext ());
@@ -9283,20 +9284,31 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
92839284 // Hardware intrinsics are recognized by name.
92849285 const char * namespaceName = NULL ;
92859286 const char * className = NULL ;
9286- const char* methodName = m_interpCeeInfo.getMethodNameFromMetadata( (CORINFO_METHOD_HANDLE)methToCall, &className, &namespaceName, NULL);
9287+ const char * methodName = getMethodName (&m_interpCeeInfo, (CORINFO_METHOD_HANDLE)methToCall, &className, &namespaceName, NULL );
92879288 if (
9289+ (strcmp (namespaceName, " System.Runtime.Intrinsics" ) == 0 ||
92889290#if defined(TARGET_X86) || defined(TARGET_AMD64)
9289- strcmp(namespaceName, "System.Runtime.Intrinsics.X86") == 0 &&
9291+ strcmp (namespaceName, " System.Runtime.Intrinsics.X86" ) == 0
92909292#elif defined(TARGET_ARM64)
9291- strcmp(namespaceName, "System.Runtime.Intrinsics.Arm") == 0 &&
9292- #endif // defined(TARGET_X86) || defined(TARGET_AMD64)
9293+ strcmp (namespaceName, " System.Runtime.Intrinsics.Arm" ) == 0
9294+ #else
9295+ 0
9296+ #endif
9297+ ) &&
92939298 strcmp (methodName, " get_IsSupported" ) == 0
92949299 )
92959300 {
92969301 GCX_COOP ();
92979302 DoGetIsSupported ();
92989303 didIntrinsic = true ;
92999304 }
9305+
9306+ if (strcmp (methodName, " get_IsHardwareAccelerated" ) == 0 && strcmp (namespaceName, " System.Runtime.Intrinsics" ) == 0 )
9307+ {
9308+ GCX_COOP ();
9309+ DoGetIsSupported ();
9310+ didIntrinsic = true ;
9311+ }
93009312 }
93019313
93029314#if FEATURE_SIMD
@@ -9310,7 +9322,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
93109322 // SIMD intrinsics are recognized by name.
93119323 const char * namespaceName = NULL ;
93129324 const char * className = NULL ;
9313- const char* methodName = m_interpCeeInfo.getMethodNameFromMetadata( (CORINFO_METHOD_HANDLE)methToCall, &className, &namespaceName, NULL);
9325+ const char * methodName = getMethodName (&m_interpCeeInfo, (CORINFO_METHOD_HANDLE)methToCall, &className, &namespaceName, NULL );
93149326 if ((strcmp (methodName, " get_IsHardwareAccelerated" ) == 0 ) && (strcmp (className, " Vector" ) == 0 ) && (strcmp (namespaceName, " System.Numerics" ) == 0 ))
93159327 {
93169328 GCX_COOP ();
@@ -9339,7 +9351,6 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
93399351 // Now we can return.
93409352 return ;
93419353 }
9342- */
93439354
93449355 // Handle other simple special cases:
93459356
@@ -9571,9 +9582,20 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
95719582 {
95729583 _ASSERTE (m_callThisArg == NULL ); // "m_callThisArg" non-null only for .ctor, which are not callvirts.
95739584
9574- CorInfoType argCIT = OpStackTypeGet (argsBase + arg).ToCorInfoType ();
9575- if (argCIT != CORINFO_TYPE_BYREF)
9576- VerificationError (" This arg of constrained call must be managed pointer." );
9585+ // The constrained. prefix will be immediately followed by a ldftn, call or callvirt instruction.
9586+ // See Ecma-335-Augments.md#iii21-constrained---prefix-invoke-a-member-on-a-value-of-a-variable-type-page-316 for more detail
9587+ if (sigInfo.hasThis ())
9588+ {
9589+ // For the callvirt instruction, the ptr argument will be a managed pointer (&) to thisType.
9590+ CorInfoType argCIT = OpStackTypeGet (argsBase + arg).ToCorInfoType ();
9591+ if (argCIT != CORINFO_TYPE_BYREF)
9592+ VerificationError (" This arg of constrained call must be managed pointer." );
9593+ }
9594+ else
9595+ {
9596+ // If the constrained. prefix is applied to a call or ldftn instruction, method must be a virtual static method.
9597+ // TODO: Assert it is a virtual static method.
9598+ }
95779599
95789600 // We only cache for the CORINFO_NO_THIS_TRANSFORM case, so we may assume that if we have a cached call site,
95799601 // there's no thisTransform to perform.
@@ -9658,7 +9680,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
96589680 const char * methToCallName = NULL ;
96599681 {
96609682 GCX_PREEMP ();
9661- methToCallName = m_interpCeeInfo. getMethodNameFromMetadata ( CORINFO_METHOD_HANDLE (methToCall), &clsOfMethToCallName, NULL , NULL );
9683+ methToCallName = getMethodName (&m_interpCeeInfo, CORINFO_METHOD_HANDLE (methToCall), &clsOfMethToCallName);
96629684 }
96639685#if INTERP_TRACING
96649686 if (strncmp (methToCallName, " get_" , 4 ) == 0 )
@@ -10851,6 +10873,39 @@ void Interpreter::DoGetIsSupported()
1085110873 m_curStackHt++;
1085210874}
1085310875
10876+ void Interpreter::DoGetArrayDataReference ()
10877+ {
10878+ CONTRACTL {
10879+ THROWS;
10880+ GC_TRIGGERS;
10881+ MODE_COOPERATIVE;
10882+ } CONTRACTL_END;
10883+
10884+ _ASSERTE (m_curStackHt > 0 );
10885+ unsigned ind = m_curStackHt - 1 ;
10886+
10887+ #ifdef _DEBUG
10888+ _ASSERTE (OpStackTypeGet (ind).ToCorInfoType () == CORINFO_TYPE_CLASS);
10889+ #endif // _DEBUG
10890+
10891+ Object* obj = OpStackGet<Object*>(ind);
10892+
10893+ if (obj == NULL )
10894+ {
10895+ ThrowNullPointerException ();
10896+ }
10897+
10898+ #ifdef _DEBUG
10899+ _ASSERTE (obj->GetMethodTable ()->IsArray ());
10900+ #endif // _DEBUG
10901+
10902+ ArrayBase* a = reinterpret_cast <ArrayBase*>(obj);
10903+ ThrowOnInvalidPointer (a);
10904+ PTR_BYTE dataPtr = a->GetDataPtr ();
10905+ OpStackSet<void *>(ind, dataPtr);
10906+ OpStackTypeSet (ind, InterpreterType (CORINFO_TYPE_BYREF));
10907+ }
10908+
1085410909void Interpreter::RecordConstrainedCall ()
1085510910{
1085610911 CONTRACTL {
@@ -11672,6 +11727,67 @@ static const char* CorInfoTypeNames[] = {
1167211727 " var"
1167311728};
1167411729
11730+ // Also see Compiler::lookupNamedIntrinsic
11731+ Interpreter::InterpreterNamedIntrinsics Interpreter::getNamedIntrinsicID (CEEInfo* info, CORINFO_METHOD_HANDLE methodHnd)
11732+ {
11733+ InterpreterNamedIntrinsics result = NI_Illegal;
11734+
11735+ const char * namespaceName = NULL ;
11736+ const char * className = NULL ;
11737+ const char * methodName = getMethodName (info, (CORINFO_METHOD_HANDLE)methodHnd, &className, &namespaceName, NULL );
11738+
11739+ if (strncmp (namespaceName, " System" , 6 ) == 0 )
11740+ {
11741+ namespaceName += 6 ;
11742+ if (namespaceName[0 ] == ' .' )
11743+ {
11744+ namespaceName += 1 ;
11745+ if (strcmp (namespaceName, " StubHelpers" ) == 0 )
11746+ {
11747+ if (strcmp (className, " StubHelpers" ) == 0 )
11748+ {
11749+ if (strcmp (methodName, " GetStubContext" ) == 0 )
11750+ {
11751+ result = NI_System_StubHelpers_GetStubContext;
11752+ }
11753+ }
11754+ }
11755+ else if (strncmp (namespaceName, " Runtime." , 8 ) == 0 )
11756+ {
11757+ namespaceName += 8 ;
11758+ if (strcmp (namespaceName, " InteropServices" ) == 0 )
11759+ {
11760+ if (strcmp (className, " MemoryMarshal" ) == 0 )
11761+ {
11762+ if (strcmp (methodName, " GetArrayDataReference" ) == 0 )
11763+ {
11764+ result = NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference;
11765+ }
11766+ }
11767+ }
11768+ }
11769+ }
11770+ }
11771+ return result;
11772+ }
11773+
11774+ // Simple version of getMethodName which supports IL Stubs such as IL_STUB_PInvoke additionally.
11775+ // Also see getMethodNameFromMetadata and printMethodName in corinfo.h
11776+ const char * Interpreter::getMethodName (CEEInfo* info, CORINFO_METHOD_HANDLE hnd, const char ** className, const char ** namespaceName, const char **enclosingClassName)
11777+ {
11778+ MethodDesc *pMD = GetMethod (hnd);
11779+ if (pMD->IsILStub ())
11780+ {
11781+ if (className != NULL )
11782+ {
11783+ *className = ILStubResolver::GetStubClassName (pMD);
11784+ }
11785+ return pMD->GetName ();
11786+ }
11787+
11788+ return info->getMethodNameFromMetadata (hnd, className, namespaceName, enclosingClassName);
11789+ }
11790+
1167511791const char * eeGetMethodFullName (CEEInfo* info, CORINFO_METHOD_HANDLE hnd, const char ** clsName)
1167611792{
1167711793 CONTRACTL {
@@ -11685,7 +11801,7 @@ const char* eeGetMethodFullName(CEEInfo* info, CORINFO_METHOD_HANDLE hnd, const
1168511801 const char * returnType = NULL ;
1168611802
1168711803 const char * className;
11688- const char * methodName = info-> getMethodNameFromMetadata ( hnd, &className, NULL , NULL );
11804+ const char * methodName = Interpreter::getMethodName (info, hnd, &className);
1168911805 if (clsName != NULL )
1169011806 {
1169111807 *clsName = className;
0 commit comments