BOOL CInjection::StartUpdateILCodes( MethodTable * pMethodTable , CORINFO_METHOD_HANDLE pMethodHandle , mdMethodDef md , LPBYTE pBuffer , DWORD dwSize ) { if( s_nStatus != Status_Ready || !pMethodHandle ) return FALSE; MethodDesc * pMethodDesc = (MethodDesc*)pMethodHandle; pMethodDesc->Reset(); MethodDesc * pStripMethodDesc = pMethodDesc->StripMethodInstantiation(); if( pStripMethodDesc ) pStripMethodDesc->Reset(); ILCodeBuffer tILCodeBuffer; tILCodeBuffer.pBuffer = pBuffer; tILCodeBuffer.dwSize = dwSize; tILCodeBuffer.bIsGeneric = FALSE; // this is a generic method if( pMethodDesc->ContainsGenericVariables() || pMethodDesc->HasClassOrMethodInstantiation() ) { tILCodeBuffer.bIsGeneric = TRUE; MethodDesc * pWrappedMethodDesc = pMethodDesc->GetWrappedMethodDesc(); if( pWrappedMethodDesc ) { pWrappedMethodDesc->Reset(); } // find out all the instantiations of this generic method Module * pModule = pMethodDesc->GetLoaderModule(); AppDomain * pAppDomain = pMethodDesc->GetDomain(); if( pModule ) { LoadedMethodDescIterator * pLoadedMethodDescIter = new LoadedMethodDescIterator( pAppDomain, pModule, md); while(pLoadedMethodDescIter->Next()) { MethodDesc * pMD = pLoadedMethodDescIter->Current(); if( pMD ) pMD->Reset(); } delete pLoadedMethodDescIter; } } std::map< CORINFO_METHOD_HANDLE, ILCodeBuffer>::iterator iter = s_mpILBuffers.find(pMethodHandle); if( iter != s_mpILBuffers.end() ) { LocalFree(iter->second.pBuffer); s_mpILBuffers.erase(iter); } s_mpILBuffers.insert( std::pair< CORINFO_METHOD_HANDLE, ILCodeBuffer>( pMethodHandle, tILCodeBuffer) ); return TRUE; }
CorJitResult __stdcall CInjection::compileMethod(ICorJitInfo * pJitInfo , CORINFO_METHOD_INFO * pCorMethodInfo , UINT nFlags , LPBYTE * pEntryAddress , ULONG * pSizeOfCode ) { ICorJitCompiler * pCorJitCompiler = (ICorJitCompiler *)this; LPBYTE pOriginalILCode = pCorMethodInfo->ILCode; unsigned int nOriginalSize = pCorMethodInfo->ILCodeSize; // find the method to be replaced ILCodeBuffer tILCodeBuffer = {0}; if( pCorMethodInfo && GetStatus() == Status_Ready ) { MethodDesc * pMethodDesc = (MethodDesc*)pCorMethodInfo->ftn; std::map< CORINFO_METHOD_HANDLE, ILCodeBuffer>::iterator iter = s_mpILBuffers.find((CORINFO_METHOD_HANDLE)pMethodDesc); // if the current method is not found, try to search its generic definition method if( iter == s_mpILBuffers.end() && pMethodDesc->HasClassOrMethodInstantiation() ) { MethodDesc * pStripMD = pMethodDesc->StripMethodInstantiation(); if( pStripMD ) iter = s_mpILBuffers.find((CORINFO_METHOD_HANDLE)pStripMD); if( iter == s_mpILBuffers.end() ) { MethodDesc * pWrappedMD = pMethodDesc->GetWrappedMethodDesc(); if( pWrappedMD ) iter = s_mpILBuffers.find((CORINFO_METHOD_HANDLE)pWrappedMD); } } if( iter != s_mpILBuffers.end() ) { tILCodeBuffer = iter->second; pCorMethodInfo->ILCode = tILCodeBuffer.pBuffer; pCorMethodInfo->ILCodeSize = tILCodeBuffer.dwSize; if( !tILCodeBuffer.bIsGeneric ) s_mpILBuffers.erase(iter); } } CorJitResult result = pCorJitCompiler->compileMethod( pJitInfo, pCorMethodInfo, nFlags, pEntryAddress, pSizeOfCode); if( tILCodeBuffer.pBuffer ) { pCorMethodInfo->ILCode = pOriginalILCode; pCorMethodInfo->ILCodeSize = nOriginalSize; if( !tILCodeBuffer.bIsGeneric ) LocalFree(tILCodeBuffer.pBuffer); } return result; }