Fix inlining issue for raw pinvoke calls when using debug builds (#455)
authorFadi Hanna <fadim@microsoft.com>
Tue, 3 Dec 2019 04:56:43 +0000 (20:56 -0800)
committerGitHub <noreply@github.com>
Tue, 3 Dec 2019 04:56:43 +0000 (20:56 -0800)
* Fix inlining issue for raw pinvoke calls when using debug builds

* Do not generate PInvoke stubs for cross-module pinvokes outside of version bubble

src/coreclr/src/jit/importer.cpp
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunSingleAssemblyCompilationModuleGroup.cs

index 2e13643..c474744 100644 (file)
@@ -6496,17 +6496,25 @@ void Compiler::impCheckForPInvokeCall(
         // inlining in CoreRT. Skip the ambient conditions checks and profitability checks.
         if (!IsTargetAbi(CORINFO_CORERT_ABI) || (info.compFlags & CORINFO_FLG_PINVOKE) == 0)
         {
-            if (!impCanPInvokeInline())
+            if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) && opts.ShouldUsePInvokeHelpers())
             {
-                return;
+                // Raw PInvoke call in PInvoke IL stub generated must be inlined to avoid infinite
+                // recursive calls to the stub.
             }
-
-            // Size-speed tradeoff: don't use inline pinvoke at rarely
-            // executed call sites.  The non-inline version is more
-            // compact.
-            if (block->isRunRarely())
+            else
             {
-                return;
+                if (!impCanPInvokeInline())
+                {
+                    return;
+                }
+
+                // Size-speed tradeoff: don't use inline pinvoke at rarely
+                // executed call sites.  The non-inline version is more
+                // compact.
+                if (block->isRunRarely())
+                {
+                    return;
+                }
             }
         }
 
index fb1f990..bad1708 100644 (file)
@@ -636,15 +636,8 @@ namespace Internal.JitInterface
                 result |= CorInfoFlag.CORINFO_FLG_SHAREDINST;
 
             if (method.IsPInvoke)
-            {
                 result |= CorInfoFlag.CORINFO_FLG_PINVOKE;
 
-                if (method.IsRawPInvoke())
-                {
-                    result |= CorInfoFlag.CORINFO_FLG_FORCEINLINE;
-                }
-            }
-
 #if READYTORUN
             if (method.RequireSecObject)
             {
index a079c20..9778cc8 100644 (file)
@@ -200,6 +200,11 @@ namespace ILCompiler
 
             Debug.Assert(method is EcmaMethod);
 
+            // If the PInvoke is declared on an external module, we can only compile it if
+            // that module is part of the version bubble.
+            if (!_versionBubbleModuleSet.Contains(((EcmaMethod)method).Module))
+                return false;
+
             if (((EcmaMethod)method).Module.Equals(method.Context.SystemModule))
                 return true;