Make the check for a struct fitting in a register check for either managed or native...
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Tue, 30 Oct 2018 23:30:16 +0000 (16:30 -0700)
committerJeremy Koritzinsky <jkoritzinsky@gmail.com>
Thu, 1 Nov 2018 00:24:05 +0000 (17:24 -0700)
Clean up duplicate #ifdefs.

Move #ifdef into method impl instead of outside the implementations.

Move IsRegPassedStruct out of UNIX_AMD64_ABI #ifdef.

Move check for enregistered struct out of UNIX_AMD64_ABI #ifdef

Add dummy implementation of IsRegPassedStruct and IsNativeStructPassedInRegisters when UNIX_AMD64_ABI isn't defined.

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

src/coreclr/src/vm/callingconvention.h
src/coreclr/src/vm/class.h
src/coreclr/src/vm/dllimport.cpp
src/coreclr/src/vm/method.cpp
src/coreclr/src/vm/method.hpp
src/coreclr/src/vm/methodtable.h
src/coreclr/src/vm/reflectioninvocation.cpp

index b66279c..295db1f 100644 (file)
@@ -1015,9 +1015,8 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
 
     case ELEMENT_TYPE_VALUETYPE:
     {
-#ifdef UNIX_AMD64_ABI
         MethodTable *pMT = m_argTypeHandle.GetMethodTable();
-        if (pMT->IsRegPassedStruct())
+        if (this->IsRegPassedStruct(pMT))
         {
             EEClass* eeClass = pMT->GetClass();
             cGenRegs = 0;
@@ -1061,10 +1060,6 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
         // Set the register counts to indicate that this argument will not be passed in registers
         cFPRegs = 0;
         cGenRegs = 0;
-#else // UNIX_AMD64_ABI
-        argSize = sizeof(TADDR);        
-#endif // UNIX_AMD64_ABI
-
         break;
     }
 
@@ -1086,9 +1081,7 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
         return argOfs;
     }
 
-#if defined(UNIX_AMD64_ABI)
-    m_fArgInRegisters = false;
-#endif        
+    m_fArgInRegisters = false;     
 
     int argOfs = TransitionBlock::GetOffsetOfArgs() + m_idxStack * STACK_ELEM_SIZE;
 
@@ -1701,6 +1694,11 @@ protected:
         m_pSig->Reset();
     }
 
+    FORCEINLINE BOOL IsRegPassedStruct(MethodTable* pMT)
+    {
+        return pMT->IsRegPassedStruct();
+    }
+
 public:
     BOOL HasThis()
     {
index 58b0c01..608870e 100644 (file)
@@ -516,6 +516,11 @@ class EEClassLayoutInfo
             LIMITED_METHOD_CONTRACT;
             return (m_bFlags & e_NATIVE_PASS_IN_REGISTERS) != 0;
         }
+#else
+        bool IsNativeStructPassedInRegisters()
+        {
+            return false;
+        }
 #endif // UNIX_AMD64_ABI
 
         CorElementType GetNativeHFATypeRaw();
index 0b20aae..6fd4366 100644 (file)
@@ -599,7 +599,7 @@ public:
 
 #ifndef _TARGET_X86_
             // we store the real managed argument stack size in the stub MethodDesc on non-X86
-            UINT stackSize = pStubMD->SizeOfArgStack();
+            UINT stackSize = pStubMD->SizeOfNativeArgStack();
 
             if (!FitsInU2(stackSize))
                 COMPlusThrow(kMarshalDirectiveException, IDS_EE_SIGTOOCOMPLEX);
index b16e27d..963dce4 100644 (file)
@@ -98,6 +98,24 @@ const SIZE_T MethodDesc::s_ClassificationSizeTable[] = {
 #undef ComPlusCallMethodDesc
 #endif
 
+class ArgIteratorBaseForPInvoke : public ArgIteratorBase
+{
+protected:
+    FORCEINLINE BOOL IsRegPassedStruct(MethodTable* pMT)
+    {
+        return pMT->GetLayoutInfo()->IsNativeStructPassedInRegisters();
+    }
+};
+
+class PInvokeArgIterator : public ArgIteratorTemplate<ArgIteratorBaseForPInvoke>
+{
+public:
+    PInvokeArgIterator(MetaSig* pSig)
+    {
+        m_pSig = pSig;
+    }
+};
+
 
 //*******************************************************************************
 SIZE_T MethodDesc::SizeOf()
@@ -1753,6 +1771,19 @@ UINT MethodDesc::SizeOfArgStack()
     return argit.SizeOfArgStack();
 }
 
+
+UINT MethodDesc::SizeOfNativeArgStack()
+{
+#ifndef UNIX_AMD64_ABI
+    return SizeOfArgStack();
+#else
+    WRAPPER_NO_CONTRACT;
+    MetaSig msig(this);
+    PInvokeArgIterator argit(&msig);
+    return argit.SizeOfArgStack();
+#endif
+}
+
 #ifdef _TARGET_X86_
 //*******************************************************************************
 UINT MethodDesc::CbStackPop()
index 414d2a3..0baf2a4 100644 (file)
@@ -753,6 +753,10 @@ public:
     // arguments passed in registers.
     UINT SizeOfArgStack();
 
+    // Returns the # of bytes of stack used by arguments in a call from native to this function.
+    // Does not include arguments passed in registers.
+    UINT SizeOfNativeArgStack();
+
     // Returns the # of bytes to pop after a call. Not necessary the
     // same as SizeOfArgStack()!
     UINT CbStackPop();
index c93a21f..b3e8b69 100644 (file)
@@ -2012,7 +2012,7 @@ public:
     bool IsNativeHFA();
     CorElementType GetNativeHFAType();
 
-#if defined(UNIX_AMD64_ABI)
+#ifdef UNIX_AMD64_ABI
     inline bool IsRegPassedStruct()
     {
         LIMITED_METHOD_CONTRACT;
@@ -2024,7 +2024,12 @@ public:
         LIMITED_METHOD_CONTRACT;
         SetFlag(enum_flag_IsRegStructPassed);
     }
-#endif // defined(UNIX_AMD64_ABI)
+#else
+    inline bool IsRegPassedStruct()
+    {
+        return false;
+    }
+#endif
 
 #ifdef FEATURE_64BIT_ALIGNMENT
     // Returns true iff the native view of this type requires 64-bit aligment.
index dd112eb..6f5011f 100644 (file)
@@ -759,6 +759,11 @@ protected:
     {
         LIMITED_METHOD_CONTRACT;
     }
+    
+    FORCEINLINE BOOL IsRegPassedStruct(MethodTable* pMT)
+    {
+        return pMT->IsRegPassedStruct();
+    }
 
 public:
     BOOL HasThis()