summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSujin Kim <sjsujin.kim@samsung.com>2016-12-20 15:53:51 +0900
committerJan Kotas <jkotas@microsoft.com>2016-12-19 22:53:51 -0800
commitdea1b9e5c0393daa420831eb74177b1fd6546181 (patch)
tree535ed586d99deb7aa6a0d530ea380feda835b89f
parent669499706ebc3fc4cc55632c42393fad4db2cead (diff)
downloadcoreclr-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.cpp1
-rw-r--r--src/vm/class.h1
-rw-r--r--src/vm/comdelegate.cpp122
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