summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorSergey Andreenko <seandree@microsoft.com>2019-05-02 15:45:08 -0700
committerSergey Andreenko <seandree@microsoft.com>2019-05-02 16:01:33 -0700
commit353637b8cdb53fc743630aa3e6bc038b1b50162d (patch)
tree05f64f71b911c2b4a263994ceee6da3a24efcb8a /src/vm
parent0c16be11a2bb4b08c5ca701ac9a6d786cf18ce4e (diff)
downloadcoreclr-353637b8cdb53fc743630aa3e6bc038b1b50162d.tar.gz
coreclr-353637b8cdb53fc743630aa3e6bc038b1b50162d.tar.bz2
coreclr-353637b8cdb53fc743630aa3e6bc038b1b50162d.zip
Fix DoGcStress for multireg return with GC pointers.
Note: we are overprotecting registers here, for example, we always protect 2 registers even if only one is returned. GCStress infrastructure should be able to tolerate extra registers. We have had such examples before (for example when returned a struct without pointers we protected the first reg anyway).
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..f4851489fc 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_)
+ // Multireg return.
+ 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);