From 435a69a9aca037f348a09e00dffef8a0888682a7 Mon Sep 17 00:00:00 2001 From: Noah Falk Date: Thu, 7 Jun 2018 12:53:08 -0700 Subject: Allow ILCodeVersion to fallback to default IL (#18322) For compat with profilers that used our APIs in unexpected ways we can allow the ILCodeVersion to fallback to the default IL code when no IL was explicitly given. --- src/vm/codeversion.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src/vm/codeversion.cpp') diff --git a/src/vm/codeversion.cpp b/src/vm/codeversion.cpp index 7406d19109..cf756e14f9 100644 --- a/src/vm/codeversion.cpp +++ b/src/vm/codeversion.cpp @@ -773,23 +773,38 @@ PTR_COR_ILMETHOD ILCodeVersion::GetIL() const } CONTRACTL_END + PTR_COR_ILMETHOD pIL = NULL; if (m_storageKind == StorageKind::Explicit) { - return AsNode()->GetIL(); + pIL = AsNode()->GetIL(); } - else + + // For the default code version we always fetch the globally stored default IL for a method + // + // In the non-default code version we assume NULL is the equivalent of explicitly requesting to + // re-use the default IL. Ideally there would be no reason to create a new version that re-uses + // the default IL (just use the default code version for that) but we do it here for compat. We've + // got some profilers that use ReJIT to create a new code version and then instead of calling + // ICorProfilerFunctionControl::SetILFunctionBody they call ICorProfilerInfo::SetILFunctionBody. + // This mutates the default IL so that it is now correct for their new code version. Of course this + // also overwrote the previous default IL so now the default code version GetIL() is out of sync + // with the jitted code. In the majority of cases we never re-read the IL after the initial + // jitting so this issue goes unnoticed. + // + // If changing the default IL after it is in use becomes more problematic in the future we would + // need to add enforcement that prevents profilers from using ICorProfilerInfo::SetILFunctionBody + // that way + coordinate with them because it is a breaking change for any profiler currently doing it. + if(pIL == NULL) { PTR_Module pModule = GetModule(); PTR_MethodDesc pMethodDesc = dac_cast(pModule->LookupMethodDef(GetMethodDef())); - if (pMethodDesc == NULL) + if (pMethodDesc != NULL) { - return NULL; - } - else - { - return dac_cast(pMethodDesc->GetILHeader(TRUE)); + pIL = dac_cast(pMethodDesc->GetILHeader(TRUE)); } } + + return pIL; } PTR_COR_ILMETHOD ILCodeVersion::GetILNoThrow() const -- cgit v1.2.3