From: Sujin Kim Date: Tue, 20 Dec 2016 06:53:51 +0000 (+0900) Subject: Fix the bug that Secure Delegate Stubs are compiled every time. (dotnet/coreclr#8592) X-Git-Tag: submit/tizen/20210909.063632~11030^2~8579 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f7ecd8d17107447dd3a2693103accc882cfad63;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix the bug that Secure Delegate Stubs are compiled every time. (dotnet/coreclr#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. dotnet/coreclr#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 Commit migrated from https://github.com/dotnet/coreclr/commit/dea1b9e5c0393daa420831eb74177b1fd6546181 --- diff --git a/src/coreclr/src/vm/class.cpp b/src/coreclr/src/vm/class.cpp index 0b9efd5..cff71f3 100644 --- a/src/coreclr/src/vm/class.cpp +++ b/src/coreclr/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/coreclr/src/vm/class.h b/src/coreclr/src/vm/class.h index 391955d..7517863 100644 --- a/src/coreclr/src/vm/class.h +++ b/src/coreclr/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/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 0246611..c6b3df4 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/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(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