From c6e91455a206d391ed6a23c9208645cff3a058f6 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 23 Jan 2020 00:33:25 -0800 Subject: [PATCH] JIT: fix jitstress/gcstress issue with return value liveness (#2055) The jit was not extending return value liveness properly for methods that returned a ref-wrapped struct, if jitstress caused code to be added between the final body statement and the epilog (eg a profile leave hook). Fixes many of the cases in #1971. --- src/coreclr/src/jit/codegencommon.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index b704e82c48e2dc..f28617694924f3 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -1719,7 +1719,7 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg) // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0). - if (!pushReg && (compiler->info.compRetType == TYP_REF)) + if (!pushReg && (compiler->info.compRetNativeType == TYP_REF)) gcInfo.gcRegGCrefSetCur |= RBM_INTRET; // We need two temporary registers, to load the GS cookie values and compare them. We can't use @@ -2253,6 +2253,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode) { if (JitConfig.JitForceFallback() || compiler->compStressCompile(Compiler::STRESS_GENERIC_VARN, 5)) { + JITDUMP("\n\n*** forcing no-way fallback -- current jit request will be abandoned ***\n\n"); NO_WAY_NOASSERT("Stress failure"); } } @@ -2289,8 +2290,8 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode) codeSize = GetEmitter()->emitEndCodeGen(compiler, trackedStackPtrsContig, GetInterruptible(), IsFullPtrRegMapRequired(), - (compiler->info.compRetType == TYP_REF), compiler->compHndBBtabCount, &prologSize, - &epilogSize, codePtr, &coldCodePtr, &consPtr); + (compiler->info.compRetNativeType == TYP_REF), compiler->compHndBBtabCount, + &prologSize, &epilogSize, codePtr, &coldCodePtr, &consPtr); compiler->EndPhase(PHASE_EMIT_CODE); @@ -6713,6 +6714,8 @@ void CodeGen::genReserveEpilog(BasicBlock* block) default: break; } + + JITDUMP("Extending return value GC liveness to epilog\n"); } } @@ -11143,9 +11146,9 @@ void CodeGen::genReturn(GenTree* treeNode) regCount = retTypeDesc.GetReturnRegCount(); } - if (varTypeIsGC(compiler->info.compRetType)) + if (varTypeIsGC(compiler->info.compRetNativeType)) { - gcInfo.gcMarkRegPtrVal(REG_INTRET, compiler->info.compRetType); + gcInfo.gcMarkRegPtrVal(REG_INTRET, compiler->info.compRetNativeType); } else if (compiler->compMethodReturnsMultiRegRetType()) { @@ -11160,7 +11163,7 @@ void CodeGen::genReturn(GenTree* treeNode) genProfilingLeaveCallback(CORINFO_HELP_PROF_FCN_LEAVE); - if (varTypeIsGC(compiler->info.compRetType)) + if (varTypeIsGC(compiler->info.compRetNativeType)) { gcInfo.gcMarkRegSetNpt(genRegMask(REG_INTRET)); }