summaryrefslogtreecommitdiff
path: root/src/vm/jitinterface.cpp
diff options
context:
space:
mode:
authorDavid Mason <davmason@microsoft.com>2019-05-13 21:40:29 -0700
committerGitHub <noreply@github.com>2019-05-13 21:40:29 -0700
commit1fc8b490bc086cce155f374db2805f2ed5e4e6c1 (patch)
tree180432500053cab7739b99262dcdb60b36e0c2e1 /src/vm/jitinterface.cpp
parent287d6af711f63149123cb67c5de9ae6684749016 (diff)
downloadcoreclr-1fc8b490bc086cce155f374db2805f2ed5e4e6c1.tar.gz
coreclr-1fc8b490bc086cce155f374db2805f2ed5e4e6c1.tar.bz2
coreclr-1fc8b490bc086cce155f374db2805f2ed5e4e6c1.zip
Profiler API to request ReJIT with inliners (#24461)
This API is necessary for attaching profilers to be able to ReJIT methods and replace everything that uses the old IL.
Diffstat (limited to 'src/vm/jitinterface.cpp')
-rw-r--r--src/vm/jitinterface.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index f8896aedd6..ef3b9d0e70 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -35,7 +35,8 @@
#include "eetoprofinterfaceimpl.h"
#include "eetoprofinterfaceimpl.inl"
#include "profilepriv.h"
-#endif
+#include "rejit.h"
+#endif // PROFILING_SUPPORTED
#include "ecall.h"
#include "generics.h"
#include "typestring.h"
@@ -8038,6 +8039,21 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
goto exit;
}
+#if defined(FEATURE_REJIT) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ if (CORProfilerEnableRejit())
+ {
+ CodeVersionManager* pCodeVersionManager = pCallee->GetCodeVersionManager();
+ CodeVersionManager::TableLockHolder lock(pCodeVersionManager);
+ ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pCallee);
+ if (ilVersion.GetRejitState() != ILCodeVersion::kStateActive || !ilVersion.HasDefaultIL())
+ {
+ result = INLINE_FAIL;
+ szFailReason = "ReJIT methods cannot be inlined.";
+ goto exit;
+ }
+ }
+#endif // defined(FEATURE_REJIT) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
// If the profiler wishes to be notified of JIT events and the result from
// the above tests will cause a function to be inlined, we need to tell the
// profiler that this inlining is going to take place, and give them a
@@ -8051,7 +8067,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
else
{
BOOL fShouldInline;
-
HRESULT hr = g_profControlBlock.pProfInterface->JITInlining(
(FunctionID)pCaller,
(FunctionID)pCallee,
@@ -8224,6 +8239,35 @@ void CEEInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
}
+
+#if defined FEATURE_REJIT && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+ if(inlineResult == INLINE_PASS)
+ {
+ // We don't want to track the chain of methods, so intentionally use m_pMethodBeingCompiled
+ // to just track the methods that pCallee is eventually inlined in
+ MethodDesc *pCallee = GetMethod(inlineeHnd);
+ MethodDesc *pCaller = m_pMethodBeingCompiled;
+ pCallee->GetModule()->AddInlining(pCaller, pCallee);
+
+ if (CORProfilerEnableRejit())
+ {
+ // If ReJIT is enabled, there is a chance that a race happened where the profiler
+ // requested a ReJIT on a method, but before the ReJIT occurred an inlining happened.
+ // If we end up reporting an inlining on a method with non-default IL it means the race
+ // happened and we need to manually request ReJIT for it since it was missed.
+ CodeVersionManager* pCodeVersionManager = pCallee->GetCodeVersionManager();
+ CodeVersionManager::TableLockHolder lock(pCodeVersionManager);
+ ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pCallee);
+ if (ilVersion.GetRejitState() != ILCodeVersion::kStateActive || !ilVersion.HasDefaultIL())
+ {
+ ModuleID modId = pCaller->GetModule()->GetModuleID();
+ mdMethodDef methodDef = pCaller->GetMemberDef();
+ ReJitManager::RequestReJIT(1, &modId, &methodDef, static_cast<COR_PRF_REJIT_FLAGS>(0));
+ }
+ }
+ }
+#endif // defined FEATURE_REJIT && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+
EE_TO_JIT_TRANSITION();
}