diff options
author | noahfalk <noahfalk@microsoft.com> | 2017-10-11 00:22:53 -0700 |
---|---|---|
committer | noahfalk <noahfalk@microsoft.com> | 2017-10-11 00:46:20 -0700 |
commit | 079f9b7aca410aae735fd68a94a92818c6afb17a (patch) | |
tree | 0f1eb2f47bab6e639fed3a995634035216f5a72f /src | |
parent | faca87ae7fd06c520fc0458a81b5b4a99a1c5e72 (diff) | |
download | coreclr-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
Diffstat (limited to 'src')
-rw-r--r-- | src/debug/ee/debugger.cpp | 23 | ||||
-rw-r--r-- | src/debug/ee/debugger.h | 2 | ||||
-rw-r--r-- | src/debug/ee/functioninfo.cpp | 10 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 19 |
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); } } } |