diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5ace208a747371..dc809ea7cd339f 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -13409,8 +13409,28 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, ret = portableEntryPoint; #else // !FEATURE_PORTABLE_ENTRYPOINTS + InterpreterPrecode* pPrecode = NULL; AllocMemTracker amt; - InterpreterPrecode* pPrecode = Precode::AllocateInterpreterPrecode(ret, ftn->GetLoaderAllocator(), &amt); + if (ftn->IsDynamicMethod()) + { + // For LCG methods, the precode is stashed in the DynamicMethodDesc, and is shared across all future uses of the DynamicMethodDesc + DynamicMethodDesc* pDMD = ftn->AsDynamicMethodDesc(); + if (pDMD->m_interpreterPrecode != NULL) + { + pPrecode = pDMD->m_interpreterPrecode; + pPrecode->GetData()->ByteCodeAddr = ret; + FlushCacheForDynamicMappedStub(pPrecode, sizeof(InterpreterPrecode)); + } + else + { + pPrecode = Precode::AllocateInterpreterPrecode(ret, ftn->GetLoaderAllocator(), &amt); + pDMD->m_interpreterPrecode = pPrecode; + } + } + else + { + pPrecode = Precode::AllocateInterpreterPrecode(ret, ftn->GetLoaderAllocator(), &amt); + } amt.SuppressRelease(); ret = PINSTRToPCODE(pPrecode->GetEntryPoint()); diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 93920ad4975114..890b5517b8d8c8 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -2426,6 +2426,11 @@ void MethodDesc::Reset() { *GetAddrOfNativeCodeSlot() = (PCODE)NULL; } + +#ifdef FEATURE_INTERPRETER + ClearInterpreterCodePointer(); +#endif + _ASSERTE(!HasNativeCode()); } diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 9e272f64457e54..b88a13625602b9 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1817,6 +1817,11 @@ class MethodDesc LIMITED_METHOD_CONTRACT; VolatileStore(&m_interpreterCode, interpreterCode); } + void ClearInterpreterCodePointer() + { + LIMITED_METHOD_CONTRACT; + VolatileStore(&m_interpreterCode, dac_cast((TADDR)NULL)); + } #endif // FEATURE_INTERPRETER #ifdef _DEBUG @@ -2707,6 +2712,12 @@ class DynamicMethodDesc : public StoredSigMethodDesc PTR_DynamicResolver m_pResolver; public: + +#if defined(FEATURE_INTERPRETER) && !defined(FEATURE_PORTABLE_ENTRYPOINTS) + // Cached InterpreterPrecode instance for dynamic methods to avoid repeated allocations. + DPTR(struct InterpreterPrecode) m_interpreterPrecode; +#endif + enum ILStubType : DWORD { StubNotSet = 0,