summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornoahfalk <noahfalk@microsoft.com>2017-10-11 00:22:53 -0700
committernoahfalk <noahfalk@microsoft.com>2017-10-11 00:46:20 -0700
commit079f9b7aca410aae735fd68a94a92818c6afb17a (patch)
tree0f1eb2f47bab6e639fed3a995634035216f5a72f
parentfaca87ae7fd06c520fc0458a81b5b4a99a1c5e72 (diff)
downloadcoreclr-079f9b7aca410aae735fd68a94a92818c6afb17a.tar.gz
coreclr-079f9b7aca410aae735fd68a94a92818c6afb17a.tar.bz2
coreclr-079f9b7aca410aae735fd68a94a92818c6afb17a.zip
Fix #14423
The JIT now invokes the debugger's JITComplete callback on every jitting of a method
-rw-r--r--src/debug/ee/debugger.cpp23
-rw-r--r--src/debug/ee/debugger.h2
-rw-r--r--src/debug/ee/functioninfo.cpp10
-rw-r--r--src/vm/jitinterface.cpp19
4 files changed, 34 insertions, 20 deletions
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index 9954839701..772862d839 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -2670,6 +2670,10 @@ void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress)
}
CONTRACTL_END;
+ LOG((LF_CORDB, LL_INFO100000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x.\n",
+ fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
+ newAddress));
+
#ifdef _TARGET_ARM_
newAddress = newAddress|THUMB_CODE;
#endif
@@ -2690,7 +2694,24 @@ void Debugger::JITComplete(MethodDesc* fd, TADDR newAddress)
{
goto Exit;
}
- DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(fd, newAddress);
+ BOOL jiWasCreated = FALSE;
+ DebuggerJitInfo * ji = dmi->CreateInitAndAddJitInfo(fd, newAddress, &jiWasCreated);
+ if (!jiWasCreated)
+ {
+ // we've already been notified about this code, no work remains.
+ // The JIT is occasionally asked to generate code for the same
+ // method on two threads. When this occurs both threads will
+ // return the same code pointer and this callback is invoked
+ // multiple times.
+ LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x. Already created\n",
+ fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
+ newAddress));
+ goto Exit;
+ }
+
+ LOG((LF_CORDB, LL_INFO1000000, "D::JITComplete: md:0x%x (%s::%s), address:0x%x. Created ji:0x%x\n",
+ fd, fd->m_pszDebugClassName, fd->m_pszDebugMethodName,
+ newAddress, ji));
// Bind any IL patches to the newly jitted native code.
HRESULT hr;
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index f99931e9dd..812bde5513 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -1003,7 +1003,7 @@ public:
// Creating the Jit-infos.
DebuggerJitInfo *FindOrCreateInitAndAddJitInfo(MethodDesc* fd);
- DebuggerJitInfo *CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr);
+ DebuggerJitInfo *CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr, BOOL* jitInfoWasCreated);
void DeleteJitInfo(DebuggerJitInfo *dji);
diff --git a/src/debug/ee/functioninfo.cpp b/src/debug/ee/functioninfo.cpp
index aa75b30407..78bba432e5 100644
--- a/src/debug/ee/functioninfo.cpp
+++ b/src/debug/ee/functioninfo.cpp
@@ -1580,14 +1580,15 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f
// CreateInitAndAddJitInfo takes a lock and checks the list again, which
// makes this thread-safe.
- return CreateInitAndAddJitInfo(fd, addr);
+ BOOL unused;
+ return CreateInitAndAddJitInfo(fd, addr, &unused);
}
// Create a DJI around a method-desc. The EE already has all the information we need for a DJI,
// the DJI just serves as a cache of the information for the debugger.
// Caller makes no guarantees about whether the DJI is already in the table. (Caller should avoid this if
// it knows it's in the table, but b/c we can't expect caller to synchronize w/ the other threads).
-DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr)
+DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TADDR startAddr, BOOL* jitInfoWasCreated)
{
CONTRACTL
{
@@ -1603,6 +1604,7 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD
// May or may-not be jitted, that's why we passed in the start addr & size explicitly.
_ASSERTE(startAddr != NULL);
+ *jitInfoWasCreated = FALSE;
// No support for light-weight codegen methods.
if (fd->IsDynamicMethod())
@@ -1642,6 +1644,10 @@ DebuggerJitInfo *DebuggerMethodInfo::CreateInitAndAddJitInfo(MethodDesc* fd, TAD
DeleteInteropSafe(dji);
return pResult;
}
+ else
+ {
+ *jitInfoWasCreated = TRUE;
+ }
}
// We know it's not in the table. Go add it!
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index d326a92ccb..f3179aab06 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -12093,24 +12093,11 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
//
// Notify the debugger that we have successfully jitted the function
//
- if (ftn->HasNativeCode())
+ if (g_pDebugInterface)
{
- //
- // Nothing to do here (don't need to notify the debugger
- // because the function has already been successfully jitted)
- //
- // This is the case where we aborted the jit because of a deadlock cycle
- // in initClass.
- //
- }
- else
- {
- if (g_pDebugInterface)
+ if (param.res == CORJIT_OK && !((CEEJitInfo*)param.comp)->JitAgain())
{
- if (param.res == CORJIT_OK && !((CEEJitInfo*)param.comp)->JitAgain())
- {
- g_pDebugInterface->JITComplete(ftn, (TADDR) *nativeEntry);
- }
+ g_pDebugInterface->JITComplete(ftn, (TADDR)*nativeEntry);
}
}
}