summaryrefslogtreecommitdiff
path: root/src/vm/comdelegate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/comdelegate.cpp')
-rw-r--r--src/vm/comdelegate.cpp128
1 files changed, 77 insertions, 51 deletions
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index 9ba1bdb328..4c85a0216e 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -1249,7 +1249,7 @@ PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
// Get UMEntryThunk from appdomain thunkcache cache.
UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
// System.Runtime.InteropServices.NativeCallableAttribute
BYTE* pData = NULL;
@@ -1281,7 +1281,7 @@ PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
pUMThunkMarshalInfo->SetCallingConvention(callConv);
}
}
-#endif //_TARGET_X86_
+#endif //_TARGET_X86_ && !FEATURE_STUBS_AS_IL
pCode = (PCODE)pUMEntryThunk->GetCode();
_ASSERTE(pCode != NULL);
@@ -2395,7 +2395,7 @@ PCODE COMDelegate::TheDelegateInvokeStub()
}
CONTRACT_END;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
static PCODE s_pInvokeStub;
if (s_pInvokeStub == NULL)
@@ -2415,7 +2415,7 @@ PCODE COMDelegate::TheDelegateInvokeStub()
RETURN s_pInvokeStub;
#else
RETURN GetEEFuncEntryPoint(SinglecastDelegateInvokeStub);
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
}
// Get the cpu stub for a delegate invoke.
@@ -2931,47 +2931,61 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
#ifdef FEATURE_CAS_POLICY
#error GetSecureInvoke not implemented
#else
- GCX_PREEMP();
+ MethodTable * pDelegateMT = pMD->GetMethodTable();
+ DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
+ Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
+
+ if (pStub == NULL)
+ {
+
+ GCX_PREEMP();
+
+ MetaSig sig(pMD);
+
+ BOOL fReturnVal = !sig.IsReturnTypeVoid();
- MetaSig sig(pMD);
+ SigTypeContext emptyContext;
+ ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE);
+
+ ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
- BOOL fReturnVal = !sig.IsReturnTypeVoid();
+ // Load the "real" delegate
+ pCode->EmitLoadThis();
+ pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST)));
- SigTypeContext emptyContext;
- ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE);
+ // Load the arguments
+ UINT paramCount = 0;
+ while(paramCount < sig.NumFixedArgs())
+ pCode->EmitLDARG(paramCount++);
- ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
+ // Call the delegate
+ pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
- // Load the "real" delegate
- pCode->EmitLoadThis();
- pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST)));
+ // Return
+ pCode->EmitRET();
- // Load the arguments
- UINT paramCount = 0;
- while(paramCount < sig.NumFixedArgs())
- pCode->EmitLDARG(paramCount++);
+ PCCOR_SIGNATURE pSig;
+ DWORD cbSig;
- // Call the delegate
- pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
+ pMD->GetSig(&pSig,&cbSig);
- // Return
- pCode->EmitRET();
+ MethodDesc* pStubMD =
+ ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
+ pMD->GetMethodTable(),
+ ILSTUB_SECUREDELEGATE_INVOKE,
+ pMD->GetModule(),
+ pSig, cbSig,
+ NULL,
+ &sl);
- PCCOR_SIGNATURE pSig;
- DWORD cbSig;
+ pStub = Stub::NewStub(JitILStub(pStubMD));
- pMD->GetSig(&pSig,&cbSig);
+ g_IBCLogger.LogEEClassCOWTableAccess(pDelegateMT);
- MethodDesc* pStubMD =
- ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
- pMD->GetMethodTable(),
- ILSTUB_SECUREDELEGATE_INVOKE,
- pMD->GetModule(),
- pSig, cbSig,
- NULL,
- &sl);
+ InterlockedCompareExchangeT<PTR_Stub>(EnsureWritablePages(&delegateEEClass->m_pSecureDelegateInvokeStub), pStub, NULL);
- return Stub::NewStub(JitILStub(pStubMD))->GetEntryPoint();
+ }
+ return pStub->GetEntryPoint();
#endif
}
#else // FEATURE_STUBS_AS_IL
@@ -2986,32 +3000,44 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
CONTRACT_END;
- GCX_PREEMP();
-
- MetaSig sig(pMD);
+ MethodTable * pDelegateMT = pMD->GetMethodTable();
+ DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
- UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig);
+ Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
- Stub *pStub = m_pSecureDelegateStubCache->GetStub(hash);
- if (!pStub)
+ if (pStub == NULL)
{
- CPUSTUBLINKER sl;
+ GCX_PREEMP();
- LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n"));
- sl.EmitSecureDelegateInvoke(hash);
+ MetaSig sig(pMD);
- // The cache is process-wide, based on signature. It never unloads
- Stub *pCandidate = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap(), NEWSTUB_FL_MULTICAST);
+ UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig);
- Stub *pWinner = m_pSecureDelegateStubCache->AttemptToSetStub(hash, pCandidate);
- pCandidate->DecRef();
- if (!pWinner)
- COMPlusThrowOM();
+ pStub = m_pSecureDelegateStubCache->GetStub(hash);
+ if (!pStub)
+ {
+ CPUSTUBLINKER sl;
- LOG((LF_CORDB,LL_INFO10000, "Putting a MC stub at 0x%x (code:0x%x)\n",
- pWinner, (BYTE*)pWinner+sizeof(Stub)));
+ LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n"));
+ sl.EmitSecureDelegateInvoke(hash);
- pStub = pWinner;
+ // The cache is process-wide, based on signature. It never unloads
+ Stub *pCandidate = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap(), NEWSTUB_FL_MULTICAST);
+
+ Stub *pWinner = m_pSecureDelegateStubCache->AttemptToSetStub(hash, pCandidate);
+ pCandidate->DecRef();
+ if (!pWinner)
+ COMPlusThrowOM();
+
+ LOG((LF_CORDB,LL_INFO10000, "Putting a MC stub at 0x%x (code:0x%x)\n",
+ pWinner, (BYTE*)pWinner+sizeof(Stub)));
+
+ pStub = pWinner;
+ }
+
+ g_IBCLogger.LogEEClassCOWTableAccess(pDelegateMT);
+ EnsureWritablePages(&delegateEEClass->m_pSecureDelegateInvokeStub);
+ delegateEEClass->m_pSecureDelegateInvokeStub = pStub;
}
RETURN (pStub->GetEntryPoint());
}