#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
}
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