Fix PInvoke transition frame in CPAOT (dotnet/coreclr#26706)
authorTomáš Rylek <trylek@microsoft.com>
Sat, 14 Sep 2019 12:31:39 +0000 (05:31 -0700)
committerGitHub <noreply@github.com>
Sat, 14 Sep 2019 12:31:39 +0000 (05:31 -0700)
During investigation of Linux CPAOT failures Jan Vorlicek discovered
that we were using the wrong constant for the PInvoke transition
frame. I have verified that the change fixes all tests under
JIT\methodical\explicit\basic I was previously seeing; I am running
the complete Pridotnet/coreclr#1 test suite to get an overall picture.

Thanks

Tomas

Commit migrated from https://github.com/dotnet/coreclr/commit/e4f35bf59cd2a96e00232ce7e004ec33d8317183

src/coreclr/src/inc/readytorun.h
src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/FixupConstants.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
src/coreclr/src/vm/jitinterface.cpp

index 6b257fd..7a84377 100644 (file)
@@ -360,4 +360,9 @@ struct READYTORUN_EXCEPTION_CLAUSE
     };  
 };
 
+enum ReadyToRunRuntimeConstants : DWORD
+{
+    READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11
+};
+
 #endif // __READYTORUN_H__
index aa02385..a64cf95 100644 (file)
@@ -2389,30 +2389,6 @@ namespace Internal.JitInterface
         private void ThrowExceptionForHelper(ref CORINFO_HELPER_DESC throwHelper)
         { throw new NotImplementedException("ThrowExceptionForHelper"); }
 
-        private uint SizeOfPInvokeTransitionFrame
-        {
-            get
-            {
-                // struct PInvokeTransitionFrame:
-                // #ifdef _TARGET_ARM_
-                //  m_ChainPointer
-                // #endif
-                //  m_RIP
-                //  m_FramePointer
-                //  m_pThread
-                //  m_Flags + align (no align for ARM64 that has 64 bit m_Flags)
-                //  m_PreserverRegs - RSP
-                //      No need to save other preserved regs because of the JIT ensures that there are
-                //      no live GC references in callee saved registers around the PInvoke callsite.
-                int size = 5 * this.PointerSize;
-
-                if (_compilation.TypeSystemContext.Target.Architecture == TargetArchitecture.ARM)
-                    size += this.PointerSize; // m_ChainPointer
-
-                return (uint)size;
-            }
-        }
-
         private void getEEInfo(ref CORINFO_EE_INFO pEEInfoOut)
         {
             pEEInfoOut = new CORINFO_EE_INFO();
@@ -2426,7 +2402,7 @@ namespace Internal.JitInterface
 
             int pointerSize = this.PointerSize;
 
-            pEEInfoOut.inlinedCallFrameInfo.size = this.SizeOfPInvokeTransitionFrame;
+            pEEInfoOut.inlinedCallFrameInfo.size = (uint)SizeOfPInvokeTransitionFrame;
 
             pEEInfoOut.offsetOfDelegateInstance = (uint)pointerSize;            // Delegate::m_firstParameter
             pEEInfoOut.offsetOfDelegateFirstTarget = OffsetOfDelegateFirstTarget;
index 06b7ef0..87bc41b 100644 (file)
@@ -173,4 +173,9 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
         ELEMENT_TYPE_SENTINEL = 65,
         ELEMENT_TYPE_PINNED = 69
     }
+
+    public static class ReadyToRunRuntimeConstants
+    {
+        public const int READYTORUN_PInvokeTransitionFrameSizeInPointerUnits = 11;
+    }
 }
index c2a54f7..aad86bd 100644 (file)
@@ -1842,5 +1842,7 @@ namespace Internal.JitInterface
 
             return false;
         }
+
+        private int SizeOfPInvokeTransitionFrame => ReadyToRunRuntimeConstants.READYTORUN_PInvokeTransitionFrameSizeInPointerUnits * _compilation.NodeFactory.Target.PointerSize;
     }
 }
index 5653fa4..20043c4 100644 (file)
@@ -10301,7 +10301,7 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut)
         // ** IMPORTANT ** If you ever need to change the value of this fixed size, make sure to change the R2R
         // version number, otherwise older R2R images will probably crash when used.
 
-        const int r2rInlinedCallFrameSize = TARGET_POINTER_SIZE * 11;
+        const int r2rInlinedCallFrameSize = TARGET_POINTER_SIZE * READYTORUN_PInvokeTransitionFrameSizeInPointerUnits;
 
 #if defined(_DEBUG) && !defined(CROSSBITNESS_COMPILE)
         InlinedCallFrame::GetEEInfo(&pEEInfoOut->inlinedCallFrameInfo);