summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vm/callingconvention.h16
-rw-r--r--src/vm/class.h5
-rw-r--r--src/vm/dllimport.cpp2
-rw-r--r--src/vm/method.cpp31
-rw-r--r--src/vm/method.hpp4
-rw-r--r--src/vm/methodtable.h9
-rw-r--r--src/vm/reflectioninvocation.cpp5
7 files changed, 60 insertions, 12 deletions
diff --git a/src/vm/callingconvention.h b/src/vm/callingconvention.h
index b66279c398..295db1f9b1 100644
--- a/src/vm/callingconvention.h
+++ b/src/vm/callingconvention.h
@@ -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()
{
diff --git a/src/vm/class.h b/src/vm/class.h
index 58b0c01e80..608870efcd 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -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();
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index 0b20aaeebb..6fd4366624 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -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);
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index b16e27d33e..963dce491a 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -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()
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index 414d2a33f0..0baf2a4934 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -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();
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index c93a21fff7..b3e8b690bf 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -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.
diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp
index dd112ebf0a..6f5011ffc3 100644
--- a/src/vm/reflectioninvocation.cpp
+++ b/src/vm/reflectioninvocation.cpp
@@ -759,6 +759,11 @@ protected:
{
LIMITED_METHOD_CONTRACT;
}
+
+ FORCEINLINE BOOL IsRegPassedStruct(MethodTable* pMT)
+ {
+ return pMT->IsRegPassedStruct();
+ }
public:
BOOL HasThis()