Fix #14423
authornoahfalk <noahfalk@microsoft.com>
Wed, 11 Oct 2017 07:22:53 +0000 (00:22 -0700)
committernoahfalk <noahfalk@microsoft.com>
Wed, 11 Oct 2017 07:46:20 +0000 (00:46 -0700)
The JIT now invokes the debugger's JITComplete callback on every jitting of a method

src/debug/ee/debugger.cpp
src/debug/ee/debugger.h
src/debug/ee/functioninfo.cpp
src/vm/jitinterface.cpp

index 9954839..772862d 100644 (file)
@@ -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;
index f99931e..812bde5 100644 (file)
@@ -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);
index aa75b30..78bba43 100644 (file)
@@ -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!
index d326a92..f3179aa 100644 (file)
@@ -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);
                 }
             }
         }