diff options
Diffstat (limited to 'src/vm/comdelegate.cpp')
-rw-r--r-- | src/vm/comdelegate.cpp | 128 |
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()); } |