Skip to content

Commit 6aafd03

Browse files
Progress. (#2721)
Update Delegate impl for interpreter. Add GetMethodTable intrinsic. Fix issue with RW/RX confusion with unwinder headers.
1 parent e45602b commit 6aafd03

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed

src/coreclr/vm/comdelegate.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,10 @@ Stub* COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
18791879
if (*pMD->GetSig() != (IMAGE_CEE_CS_CALLCONV_HASTHIS | IMAGE_CEE_CS_CALLCONV_DEFAULT))
18801880
COMPlusThrow(kInvalidProgramException);
18811881

1882+
PCCOR_SIGNATURE pSig;
1883+
DWORD cbSig;
1884+
pMD->GetSig(&pSig,&cbSig);
1885+
18821886
MetaSig sig(pMD);
18831887

18841888
BOOL fReturnVal = !sig.IsReturnTypeVoid();
@@ -1888,29 +1892,37 @@ Stub* COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
18881892

18891893
ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
18901894

1891-
// This stub is only used for rare indirect cases, for example
1892-
// when Delegate.Invoke method is wrapped into another delegate.
1893-
// Direct invocation of delegate is expanded by JIT.
1894-
// Emit a recursive call here to let JIT handle complex cases like
1895-
// virtual dispatch and GC safety.
1896-
18971895
// Load the delegate object
18981896
pCode->EmitLoadThis();
18991897

19001898
// Load the arguments
19011899
for (UINT paramCount = 0; paramCount < sig.NumFixedArgs(); paramCount++)
19021900
pCode->EmitLDARG(paramCount);
19031901

1904-
// recursively call the delegate itself
1902+
#ifdef FEATURE_INTERPRETER
1903+
// Call the underlying method pointer.
1904+
pCode->EmitLoadThis();
1905+
pCode->EmitLDFLD(FIELD__DELEGATE__METHOD_PTR);
1906+
1907+
mdToken sigTok = pCode->GetSigToken(pSig, cbSig);
1908+
pCode->EmitCALLI(sigTok, sig.NumFixedArgs(), fReturnVal);
1909+
1910+
pCode->EmitLoadThis();
1911+
pCode->EmitCALL(METHOD__GC__KEEP_ALIVE, 1, 0);
1912+
#else
1913+
// This stub is only used for rare indirect cases, for example
1914+
// when Delegate.Invoke method is wrapped into another delegate.
1915+
// Direct invocation of delegate is expanded by JIT.
1916+
// Emit a recursive call here to let JIT handle complex cases like
1917+
// virtual dispatch and GC safety.
1918+
1919+
// Recursively call the delegate itself.
19051920
pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
1921+
#endif // !FEATURE_INTERPRETER
19061922

19071923
// return
19081924
pCode->EmitRET();
19091925

1910-
PCCOR_SIGNATURE pSig;
1911-
DWORD cbSig;
1912-
pMD->GetSig(&pSig,&cbSig);
1913-
19141926
MethodDesc* pStubMD = ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
19151927
pMD->GetMethodTable(),
19161928
ILSTUB_DELEGATE_INVOKE_METHOD,

src/coreclr/vm/interpreter.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9289,6 +9289,11 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
92899289
didIntrinsic = true;
92909290
break;
92919291

9292+
case NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable:
9293+
DoGetMethodTable();
9294+
didIntrinsic = true;
9295+
break;
9296+
92929297
case NI_System_Threading_Interlocked_CompareExchange:
92939298
// Here and in other Interlocked.* intrinsics we use sigInfo.retType to be able
92949299
// to detect small-integer overloads.
@@ -10986,6 +10991,34 @@ void Interpreter::DoIsReferenceOrContainsReferences(CORINFO_METHOD_HANDLE method
1098610991
m_curStackHt++;
1098710992
}
1098810993

10994+
void Interpreter::DoGetMethodTable()
10995+
{
10996+
CONTRACTL{
10997+
THROWS;
10998+
GC_TRIGGERS;
10999+
MODE_COOPERATIVE;
11000+
} CONTRACTL_END;
11001+
11002+
_ASSERTE(m_curStackHt > 0);
11003+
unsigned ind = m_curStackHt - 1;
11004+
11005+
#ifdef _DEBUG
11006+
_ASSERTE(OpStackTypeGet(ind).ToCorInfoType() == CORINFO_TYPE_CLASS);
11007+
#endif // _DEBUG
11008+
11009+
Object* obj = OpStackGet<Object*>(ind);
11010+
11011+
if (obj == NULL)
11012+
{
11013+
ThrowNullPointerException();
11014+
}
11015+
11016+
MethodTable* pMT = obj->RawGetMethodTable();
11017+
11018+
OpStackSet<MethodTable*>(m_curStackHt, pMT);
11019+
OpStackTypeSet(m_curStackHt, InterpreterType(CORINFO_TYPE_NATIVEINT));
11020+
}
11021+
1098911022
bool Interpreter::DoInterlockedCompareExchange(CorInfoType retType)
1099011023
{
1099111024
CONTRACTL{
@@ -11992,6 +12025,10 @@ Interpreter::InterpreterNamedIntrinsics Interpreter::getNamedIntrinsicID(CEEInfo
1199212025
{
1199312026
result = NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences;
1199412027
}
12028+
else if (strcmp(methodName, "GetMethodTable") == 0)
12029+
{
12030+
result = NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable;
12031+
}
1199512032
}
1199612033
}
1199712034
}

src/coreclr/vm/interpreter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,7 @@ class Interpreter
923923
NI_System_StubHelpers_GetStubContext,
924924
NI_System_Runtime_InteropService_MemoryMarshal_GetArrayDataReference,
925925
NI_System_Runtime_CompilerServices_RuntimeHelpers_IsReferenceOrContainsReferences,
926+
NI_System_Runtime_CompilerServices_RuntimeHelpers_GetMethodTable,
926927
NI_System_Threading_Interlocked_CompareExchange,
927928
NI_System_Threading_Interlocked_Exchange,
928929
NI_System_Threading_Interlocked_ExchangeAdd,
@@ -1797,6 +1798,7 @@ class Interpreter
17971798
void DoGetIsSupported();
17981799
void DoGetArrayDataReference();
17991800
void DoIsReferenceOrContainsReferences(CORINFO_METHOD_HANDLE method);
1801+
void DoGetMethodTable();
18001802
bool DoInterlockedCompareExchange(CorInfoType retType);
18011803
bool DoInterlockedExchange(CorInfoType retType);
18021804
bool DoInterlockedExchangeAdd(CorInfoType retType);

src/coreclr/vm/stublink.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStubRX, Stub* pStubRW, int globalsize, Lo
18111811
//
18121812

18131813
pHeaderRW->pNext = pStubHeapSegment->pUnwindHeaderList;
1814-
pStubHeapSegment->pUnwindHeaderList = pHeaderRW;
1814+
pStubHeapSegment->pUnwindHeaderList = pHeaderRX;
18151815

18161816
#ifdef TARGET_AMD64
18171817
// Publish Unwind info to ETW stack crawler
@@ -1826,7 +1826,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStubRX, Stub* pStubRW, int globalsize, Lo
18261826

18271827
#ifdef _DEBUG
18281828
_ASSERTE(pHeaderRW->IsRegistered());
1829-
_ASSERTE( &pHeaderRW->FunctionEntry
1829+
_ASSERTE( &pHeaderRX->FunctionEntry
18301830
== FindStubFunctionEntry((ULONG64)pCode, EncodeDynamicFunctionTableContext(pStubHeapSegment, DYNFNTABLE_STUB)));
18311831
#endif
18321832

0 commit comments

Comments
 (0)