diff options
author | Sujin Kim <sjsujin.kim@samsung.com> | 2016-12-20 15:53:51 +0900 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-12-19 22:53:51 -0800 |
commit | dea1b9e5c0393daa420831eb74177b1fd6546181 (patch) | |
tree | 535ed586d99deb7aa6a0d530ea380feda835b89f | |
parent | 669499706ebc3fc4cc55632c42393fad4db2cead (diff) | |
download | coreclr-dea1b9e5c0393daa420831eb74177b1fd6546181.tar.gz coreclr-dea1b9e5c0393daa420831eb74177b1fd6546181.tar.bz2 coreclr-dea1b9e5c0393daa420831eb74177b1fd6546181.zip |
Fix the bug that Secure Delegate Stubs are compiled every time. (#8592)
* Fix the bug that Secure Delegate Stubs are compiled every time.
I found that Secure Delegate stubs are compiled every time during application execution, which has a negative impact on execution performance. #8554
Like the GetMulticastInvoke() method, GetSecureInvoke() checks the hashtable when the method is executed and uses it if it already exists.
* Fix pDelMT bug and change file rights
-rw-r--r-- | src/vm/class.cpp | 1 | ||||
-rw-r--r-- | src/vm/class.h | 1 | ||||
-rw-r--r-- | src/vm/comdelegate.cpp | 122 |
3 files changed, 76 insertions, 48 deletions
diff --git a/src/vm/class.cpp b/src/vm/class.cpp index 0b9efd54ef..cff71f328f 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -3068,6 +3068,7 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT) image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pUMThunkMarshInfo)); image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pStaticCallStub)); image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pMultiCastInvokeStub)); + image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pSecureDelegateInvokeStub)); image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pMarshalStub)); #ifdef FEATURE_COMINTEROP diff --git a/src/vm/class.h b/src/vm/class.h index 391955d578..7517863278 100644 --- a/src/vm/class.h +++ b/src/vm/class.h @@ -2416,6 +2416,7 @@ public: PTR_Stub m_pInstRetBuffCallStub; PTR_MethodDesc m_pInvokeMethod; PTR_Stub m_pMultiCastInvokeStub; + PTR_Stub m_pSecureDelegateInvokeStub; UMThunkMarshInfo* m_pUMThunkMarshInfo; PTR_MethodDesc m_pBeginInvokeMethod; PTR_MethodDesc m_pEndInvokeMethod; diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp index 0246611667..c6b3df4740 100644 --- a/src/vm/comdelegate.cpp +++ b/src/vm/comdelegate.cpp @@ -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(); + + SigTypeContext emptyContext; + ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE); - MetaSig sig(pMD); + 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,33 +3000,45 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD) } CONTRACT_END; - GCX_PREEMP(); + MethodTable * pDelegateMT = pMD->GetMethodTable(); + DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass(); + + Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub; + + if (pStub == NULL) + { + GCX_PREEMP(); - MetaSig sig(pMD); + MetaSig sig(pMD); - UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig); + UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig); - Stub *pStub = m_pSecureDelegateStubCache->GetStub(hash); - if (!pStub) - { - CPUSTUBLINKER sl; + pStub = m_pSecureDelegateStubCache->GetStub(hash); + if (!pStub) + { + CPUSTUBLINKER sl; - LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n")); - sl.EmitSecureDelegateInvoke(hash); + LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n")); + sl.EmitSecureDelegateInvoke(hash); - // The cache is process-wide, based on signature. It never unloads - Stub *pCandidate = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap(), NEWSTUB_FL_MULTICAST); + // 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(); - 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))); - LOG((LF_CORDB,LL_INFO10000, "Putting a MC stub at 0x%x (code:0x%x)\n", - pWinner, (BYTE*)pWinner+sizeof(Stub))); + pStub = pWinner; + } - pStub = pWinner; - } + g_IBCLogger.LogEEClassCOWTableAccess(pDelegateMT); + EnsureWritablePages(&delegateEEClass->m_pSecureDelegateInvokeStub); + delegateEEClass->m_pSecureDelegateInvokeStub = pStub; + } RETURN (pStub->GetEntryPoint()); } #endif // FEATURE_STUBS_AS_IL |