summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2019-05-03 00:59:56 -0700
committerGitHub <noreply@github.com>2019-05-03 00:59:56 -0700
commit964461ca69639003914fd4fedaf08baf1f388f7e (patch)
tree044b819e3b62809695db605b05c09cfb93d6bc34 /src/vm
parent821f9055dc4a7e6c0353e30c85d4cda12ff1a6c5 (diff)
parent2e8a39483708e7729e72100849fcc3f45c0a69c0 (diff)
downloadcoreclr-964461ca69639003914fd4fedaf08baf1f388f7e.tar.gz
coreclr-964461ca69639003914fd4fedaf08baf1f388f7e.tar.bz2
coreclr-964461ca69639003914fd4fedaf08baf1f388f7e.zip
Merge pull request #24363 from sandreenko/GitHub_23199
Fix GCStress for multireg returns.
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/gccover.cpp36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/vm/gccover.cpp b/src/vm/gccover.cpp
index a080289bb1..684907c053 100644
--- a/src/vm/gccover.cpp
+++ b/src/vm/gccover.cpp
@@ -1692,22 +1692,38 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
FrameWithCookie<GCFrame> gcFrame;
- DWORD_PTR retVal = 0;
+
+ OBJECTREF* retPointer = 0;
+ UINT numObjRefs = 1;
+#if defined(UNIX_AMD64_ABI) || defined(_TARGET_ARM64_)
+ // These targets support multireg returns.
+ DWORD_PTR retValArray[2];
+ retPointer = (OBJECTREF*)retValArray;
+#else // ARM32, x86, AMD64 Windows.
+ DWORD_PTR retVal;
+ retPointer = (OBJECTREF*)&retVal;
+#endif
if (afterCallProtect) // Do I need to protect return value?
- {
-#ifdef _TARGET_AMD64_
+ {
+#if defined(UNIX_AMD64_ABI)
+ numObjRefs = 2;
+ retValArray[0] = regs->Rax;
+ retValArray[1] = regs->Rdx;
+#elif defined(_TARGET_AMD64_)
retVal = regs->Rax;
#elif defined(_TARGET_X86_)
retVal = regs->Eax;
#elif defined(_TARGET_ARM_)
retVal = regs->R0;
#elif defined(_TARGET_ARM64_)
- retVal = regs->X0;
+ numObjRefs = 2;
+ retValArray[0] = regs->X0;
+ retValArray[1] = regs->X1;
#else
PORTABILITY_ASSERT("DoGCStress - return register");
#endif
- gcFrame.Init(pThread, (OBJECTREF*) &retVal, 1, TRUE);
+ gcFrame.Init(pThread, retPointer, numObjRefs, TRUE);
}
#endif // _TARGET_*
@@ -1743,23 +1759,25 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
CONSISTENCY_CHECK(!pThread->HasPendingGCStressInstructionUpdate());
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
if (afterCallProtect)
{
-#ifdef _TARGET_AMD64_
+#if defined(UNIX_AMD64_ABI)
+ regs->Rax = retValArray[0];
+ regs->Rdx = retValArray[1];
+#elif _TARGET_AMD64_
regs->Rax = retVal;
#elif defined(_TARGET_X86_)
regs->Eax = retVal;
#elif defined(_TARGET_ARM_)
regs->R0 = retVal;
#elif defined(_TARGET_ARM64_)
- regs->X[0] = retVal;
+ regs->X0 = retValArray[0];
+ regs->X1 = retValArray[1];
#else
PORTABILITY_ASSERT("DoGCStress - return register");
#endif
gcFrame.Pop();
}
-#endif // _TARGET_*
#if !defined(USE_REDIRECT_FOR_GCSTRESS)
frame.Pop(pThread);