summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vm/callhelpers.cpp88
1 files changed, 50 insertions, 38 deletions
diff --git a/src/vm/callhelpers.cpp b/src/vm/callhelpers.cpp
index 9152f71d79..addd5192da 100644
--- a/src/vm/callhelpers.cpp
+++ b/src/vm/callhelpers.cpp
@@ -16,6 +16,8 @@
// To include declaration of "SignatureNative"
#include "runtimehandles.h"
+#include "invokeutil.h"
+#include "argdestination.h"
#if defined(FEATURE_MULTICOREJIT) && defined(_DEBUG)
@@ -536,7 +538,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
}
#endif
- int ofs;
+ int ofs;
for (; TransitionBlock::InvalidOffset != (ofs = m_argIt.GetNextOffset()); arg++)
{
#ifdef CALLDESCR_REGTYPEMAP
@@ -567,46 +569,56 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
}
#endif // CHECK_APP_DOMAIN_LEAKS
-#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
- _ASSERTE(ofs != TransitionBlock::StructInRegsOffset);
-#endif
- PVOID pDest = pTransitionBlock + ofs;
+ ArgDestination argDest(pTransitionBlock, ofs, m_argIt.GetArgLocDescForStructInRegs());
UINT32 stackSize = m_argIt.GetArgSize();
- switch (stackSize)
+ // We need to pass in a pointer, but be careful of the ARG_SLOT calling convention. We might already have a pointer in the ARG_SLOT.
+ PVOID pSrc = stackSize > sizeof(ARG_SLOT) ? (LPVOID)ArgSlotToPtr(pArguments[arg]) : (LPVOID)ArgSlotEndianessFixup((ARG_SLOT*)&pArguments[arg], stackSize);
+
+#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+ if (argDest.IsStructPassedInRegs())
+ {
+ TypeHandle th;
+ m_argIt.GetArgType(&th);
+
+ argDest.CopyStructToRegisters(pSrc, th.AsMethodTable()->GetNumInstanceFieldBytes(), 0);
+ }
+ else
+#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
{
- case 1:
- case 2:
- case 4:
- *((INT32*)pDest) = (INT32)pArguments[arg];
- break;
-
- case 8:
- *((INT64*)pDest) = pArguments[arg];
- break;
-
- default:
- // The ARG_SLOT contains a pointer to the value-type
-#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
- if (m_argIt.IsArgPassedByRef())
- {
- // We need to pass in a pointer, but be careful of the ARG_SLOT calling convention.
- // We might already have a pointer in the ARG_SLOT
- *(PVOID*)pDest = stackSize>sizeof(ARG_SLOT) ?
- (LPVOID)ArgSlotToPtr(pArguments[arg]) :
- (LPVOID)ArgSlotEndianessFixup((ARG_SLOT*)&pArguments[arg], stackSize);
- }
- else
-#endif // ENREGISTERED_PARAMTYPE_MAXSIZE
- if (stackSize>sizeof(ARG_SLOT))
- {
- CopyMemory(pDest, ArgSlotToPtr(pArguments[arg]), stackSize);
- }
- else
- {
- CopyMemory(pDest, (LPVOID) (&pArguments[arg]), stackSize);
- }
- break;
+ PVOID pDest = argDest.GetDestinationAddress();
+
+ switch (stackSize)
+ {
+ case 1:
+ case 2:
+ case 4:
+ *((INT32*)pDest) = (INT32)pArguments[arg];
+ break;
+
+ case 8:
+ *((INT64*)pDest) = pArguments[arg];
+ break;
+
+ default:
+ // The ARG_SLOT contains a pointer to the value-type
+ #ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
+ if (m_argIt.IsArgPassedByRef())
+ {
+ *(PVOID*)pDest = pSrc;
+ }
+ else
+ #endif // ENREGISTERED_PARAMTYPE_MAXSIZE
+ if (stackSize > sizeof(ARG_SLOT))
+ {
+ CopyMemory(pDest, ArgSlotToPtr(pArguments[arg]), stackSize);
+ }
+ else
+ {
+ CopyMemory(pDest, (LPVOID) (&pArguments[arg]), stackSize);
+ }
+ break;
+ }
}
}