summaryrefslogtreecommitdiff
path: root/src/vm/eetwain.cpp
diff options
context:
space:
mode:
authorJonghyun Park <parjong@gmail.com>2017-04-05 09:30:08 +0900
committerJonghyun Park <parjong@gmail.com>2017-04-07 08:48:17 +0900
commit42924c80d75313c45abb049d2e38fbb9f538f589 (patch)
treed779a5f18605347dedaae18ca65a8a52c96cec17 /src/vm/eetwain.cpp
parent9c74cbac6c86f2c484c7ebd4c81a6aee6bd7cc25 (diff)
downloadcoreclr-42924c80d75313c45abb049d2e38fbb9f538f589.tar.gz
coreclr-42924c80d75313c45abb049d2e38fbb9f538f589.tar.bz2
coreclr-42924c80d75313c45abb049d2e38fbb9f538f589.zip
[x86/Linux] Use GCInfo for funclet unwinding
Diffstat (limited to 'src/vm/eetwain.cpp')
-rw-r--r--src/vm/eetwain.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index aff2507489..4f0bbbcebe 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -2413,6 +2413,18 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
_ASSERTE(*castto(table, unsigned short *)++ == 0xBABE);
#endif
+ bool isPartialArgInfo;
+
+#ifndef UNIX_X86_ABI
+ isPartialArgInfo = info->ebpFrame;
+#else
+ // For x86/Linux, interruptible code always has full arg info
+ //
+ // This should be aligned with emitFullArgInfo setting at
+ // emitter::emitEndCodeGen (in JIT)
+ isPartialArgInfo = false;
+#endif
+
/*
Encoding table for methods that are fully interruptible
@@ -2611,9 +2623,9 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
argOfs--;
}
- else if (info->ebpFrame)
+ else if (isPartialArgInfo)
argCnt--;
- else /* !ebpFrame && not a ref */
+ else /* full arg info && not a ref */
argOfs--;
/* Continue with the next lower bit */
@@ -2622,11 +2634,11 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
while (argOfs);
- _ASSERTE((info->ebpFrame != 0) ||
+ _ASSERTE(!isPartialArgInfo ||
isZero(argHigh) ||
(argHigh == CONSTRUCT_ptrArgTP(1, (argCnt-1))));
- if (info->ebpFrame)
+ if (isPartialArgInfo)
{
while (!intersect(argHigh, ptrArgs) && (!isZero(argHigh)))
argHigh >>= 1;
@@ -2643,10 +2655,10 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
else
{
- /* For ESP-frames, all pushes are reported, and so
+ /* Full arg info reports all pushes, and thus
argOffs has to be consistent with argCnt */
- _ASSERTE(info->ebpFrame || argCnt == argOfs);
+ _ASSERTE(isPartialArgInfo || argCnt == argOfs);
/* store arg count */
@@ -2692,7 +2704,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
else {
/* non-ptr arg push */
- _ASSERTE(!(info->ebpFrame));
+ _ASSERTE(!isPartialArgInfo);
ptrOffs += (val & 0x07);
if (ptrOffs > curOffs) {
iptr = isThis = false;
@@ -2753,9 +2765,9 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
}
- // For ebp-frames, need to find the next higest pointer for argHigh
+ // For partial arg info, need to find the next higest pointer for argHigh
- if (info->ebpFrame)
+ if (isPartialArgInfo)
{
for(argHigh = ptrArgTP(0); !isZero(argMask); argMask >>= 1)
{
@@ -2794,7 +2806,7 @@ REPORT_REFS:
info->thisPtrResult = thisPtrReg;
_ASSERTE(thisPtrReg == REGI_NA || (regNumToMask(thisPtrReg) & info->regMaskResult));
- if (info->ebpFrame)
+ if (isPartialArgInfo)
{
return 0;
}
@@ -3789,7 +3801,9 @@ bool UnwindEbpDoubleAlignFrame(
PREGDISPLAY pContext,
EECodeInfo *pCodeInfo,
hdrInfo *info,
+ PTR_CBYTE table,
PTR_CBYTE methodStart,
+ DWORD curOffs,
unsigned flags,
StackwalkCacheUnwindInfo *pUnwindInfo) // out-only, perf improvement
{
@@ -3815,8 +3829,9 @@ bool UnwindEbpDoubleAlignFrame(
// TODO Currently we assume that ESP of funclet frames is always fixed but actually it could change.
if (pCodeInfo->IsFunclet())
{
+ baseSP = curESP;
// Set baseSP as initial SP
- baseSP = pContext->pCurrentContext->ResumeEsp;
+ baseSP += GetPushedArgSize(info, table, curOffs);
// 16-byte stack alignment padding (allocated in genFuncletProlog)
baseSP += 12;
@@ -4014,7 +4029,7 @@ bool UnwindStackFrame(PREGDISPLAY pContext,
* Now we know that have an EBP frame
*/
- if (!UnwindEbpDoubleAlignFrame(pContext, pCodeInfo, info, methodStart, flags, pUnwindInfo))
+ if (!UnwindEbpDoubleAlignFrame(pContext, pCodeInfo, info, table, methodStart, curOffs, flags, pUnwindInfo))
return false;
}