@@ -73,7 +73,7 @@ InterpreterMethodInfo::InterpreterMethodInfo(CEEInfo* comp, CORINFO_METHOD_INFO*
73
73
#if defined(_DEBUG)
74
74
m_methName = ::eeGetMethodFullName (comp, methInfo->ftn , &clsName);
75
75
#else
76
- m_methName = comp-> getMethodNameFromMetadata ( methInfo->ftn , &clsName, NULL , NULL );
76
+ m_methName = getMethodName (comp, methInfo->ftn , &clsName);
77
77
#endif
78
78
char * myClsName = new char [strlen (clsName) + 1 ];
79
79
strcpy (myClsName, clsName);
@@ -752,7 +752,7 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
752
752
if (!jmpCall)
753
753
{
754
754
const char * clsName;
755
- const char * methName = comp-> getMethodNameFromMetadata ( info->ftn , &clsName, NULL , NULL );
755
+ const char * methName = getMethodName (comp, info->ftn , &clsName);
756
756
if ( !s_InterpretMeths.contains (methName, clsName, info->args .pSig )
757
757
|| s_InterpretMethsExclude.contains (methName, clsName, info->args .pSig ))
758
758
{
@@ -9226,26 +9226,27 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9226
9226
// Point A in our cycle count.
9227
9227
9228
9228
9229
- // TODO: enable when NamedIntrinsic is available to interpreter
9230
-
9231
- /*
9232
9229
// Is the method an intrinsic? If so, and if it's one we've written special-case code for
9233
9230
// handle intrinsically.
9234
- NamedIntrinsic intrinsicName ;
9231
+ InterpreterNamedIntrinsics intrinsicId ;
9235
9232
{
9236
9233
GCX_PREEMP ();
9237
- intrinsicName = getIntrinsicName( CORINFO_METHOD_HANDLE(methToCall), nullptr );
9234
+ intrinsicId = getNamedIntrinsicID (&m_interpCeeInfo, CORINFO_METHOD_HANDLE (methToCall));
9238
9235
}
9239
9236
9240
9237
#if INTERP_TRACING
9241
- if (intrinsicName == NI_Illegal)
9238
+ if (intrinsicId == NI_Illegal)
9242
9239
InterlockedIncrement (&s_totalInterpCallsToIntrinsics);
9243
9240
#endif // INTERP_TRACING
9244
9241
bool didIntrinsic = false ;
9245
9242
if (!m_constrainedFlag)
9246
9243
{
9247
9244
switch (intrinsicId)
9248
9245
{
9246
+ case NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference:
9247
+ DoGetArrayDataReference ();
9248
+ didIntrinsic = true ;
9249
+ break ;
9249
9250
#if INTERP_ILSTUBS
9250
9251
case NI_System_StubHelpers_GetStubContext:
9251
9252
OpStackSet<void *>(m_curStackHt, GetStubContext ());
@@ -9283,20 +9284,31 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9283
9284
// Hardware intrinsics are recognized by name.
9284
9285
const char * namespaceName = NULL ;
9285
9286
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 );
9287
9288
if (
9289
+ (strcmp (namespaceName, " System.Runtime.Intrinsics" ) == 0 ||
9288
9290
#if defined(TARGET_X86) || defined(TARGET_AMD64)
9289
- strcmp(namespaceName, "System.Runtime.Intrinsics.X86") == 0 &&
9291
+ strcmp (namespaceName, " System.Runtime.Intrinsics.X86" ) == 0
9290
9292
#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
+ ) &&
9293
9298
strcmp (methodName, " get_IsSupported" ) == 0
9294
9299
)
9295
9300
{
9296
9301
GCX_COOP ();
9297
9302
DoGetIsSupported ();
9298
9303
didIntrinsic = true ;
9299
9304
}
9305
+
9306
+ if (strcmp (methodName, " get_IsHardwareAccelerated" ) == 0 && strcmp (namespaceName, " System.Runtime.Intrinsics" ) == 0 )
9307
+ {
9308
+ GCX_COOP ();
9309
+ DoGetIsSupported ();
9310
+ didIntrinsic = true ;
9311
+ }
9300
9312
}
9301
9313
9302
9314
#if FEATURE_SIMD
@@ -9310,7 +9322,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9310
9322
// SIMD intrinsics are recognized by name.
9311
9323
const char * namespaceName = NULL ;
9312
9324
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 );
9314
9326
if ((strcmp (methodName, " get_IsHardwareAccelerated" ) == 0 ) && (strcmp (className, " Vector" ) == 0 ) && (strcmp (namespaceName, " System.Numerics" ) == 0 ))
9315
9327
{
9316
9328
GCX_COOP ();
@@ -9339,7 +9351,6 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9339
9351
// Now we can return.
9340
9352
return ;
9341
9353
}
9342
- */
9343
9354
9344
9355
// Handle other simple special cases:
9345
9356
@@ -9571,9 +9582,20 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9571
9582
{
9572
9583
_ASSERTE (m_callThisArg == NULL ); // "m_callThisArg" non-null only for .ctor, which are not callvirts.
9573
9584
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
+ }
9577
9599
9578
9600
// We only cache for the CORINFO_NO_THIS_TRANSFORM case, so we may assume that if we have a cached call site,
9579
9601
// there's no thisTransform to perform.
@@ -9658,7 +9680,7 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
9658
9680
const char * methToCallName = NULL ;
9659
9681
{
9660
9682
GCX_PREEMP ();
9661
- methToCallName = m_interpCeeInfo. getMethodNameFromMetadata ( CORINFO_METHOD_HANDLE (methToCall), &clsOfMethToCallName, NULL , NULL );
9683
+ methToCallName = getMethodName (&m_interpCeeInfo, CORINFO_METHOD_HANDLE (methToCall), &clsOfMethToCallName);
9662
9684
}
9663
9685
#if INTERP_TRACING
9664
9686
if (strncmp (methToCallName, " get_" , 4 ) == 0 )
@@ -10851,6 +10873,39 @@ void Interpreter::DoGetIsSupported()
10851
10873
m_curStackHt++;
10852
10874
}
10853
10875
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
+
10854
10909
void Interpreter::RecordConstrainedCall ()
10855
10910
{
10856
10911
CONTRACTL {
@@ -11672,6 +11727,67 @@ static const char* CorInfoTypeNames[] = {
11672
11727
" var"
11673
11728
};
11674
11729
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
+
11675
11791
const char * eeGetMethodFullName (CEEInfo* info, CORINFO_METHOD_HANDLE hnd, const char ** clsName)
11676
11792
{
11677
11793
CONTRACTL {
@@ -11685,7 +11801,7 @@ const char* eeGetMethodFullName(CEEInfo* info, CORINFO_METHOD_HANDLE hnd, const
11685
11801
const char * returnType = NULL ;
11686
11802
11687
11803
const char * className;
11688
- const char * methodName = info-> getMethodNameFromMetadata ( hnd, &className, NULL , NULL );
11804
+ const char * methodName = Interpreter::getMethodName (info, hnd, &className);
11689
11805
if (clsName != NULL )
11690
11806
{
11691
11807
*clsName = className;
0 commit comments