@@ -1516,8 +1516,22 @@ void CodeGen::genExitCode(BasicBlock* block)
15161516 bool jmpEpilog = block->HasFlag (BBF_HAS_JMP);
15171517 if (compiler->getNeedsGSSecurityCookie ())
15181518 {
1519+ #ifndef JIT32_GCENCODER
1520+ // At this point the gc info that we track in codegen is often incorrect,
1521+ // as it could be missing return registers or arg registers (in a case of tail call).
1522+ // GS cookie check will emit a call and that will pass our GC info to emit and potentially mess things up.
1523+ // While we could infer returns/args and force them to be live and it seems to work in JIT32_GCENCODER case,
1524+ // it appears to be nontrivial in more general case.
1525+ // So, instead, we just claim that the whole thing is not GC-interruptible.
1526+ // Effectively this starts the epilog a few instructions earlier.
1527+ //
1528+ // CONSIDER: is that a good place to be that codegen loses track of returns/args at this point?
1529+ GetEmitter ()->emitDisableGC ();
1530+ #endif
1531+
15191532 genEmitGSCookieCheck (jmpEpilog);
15201533
1534+ #ifdef JIT32_GCENCODER
15211535 if (jmpEpilog)
15221536 {
15231537 // Dev10 642944 -
@@ -1540,6 +1554,7 @@ void CodeGen::genExitCode(BasicBlock* block)
15401554 GetEmitter ()->emitThisGCrefRegs = GetEmitter ()->emitInitGCrefRegs = gcInfo.gcRegGCrefSetCur ;
15411555 GetEmitter ()->emitThisByrefRegs = GetEmitter ()->emitInitByrefRegs = gcInfo.gcRegByrefSetCur ;
15421556 }
1557+ #endif
15431558 }
15441559
15451560 genReserveEpilog (block);
@@ -4728,43 +4743,13 @@ void CodeGen::genReserveProlog(BasicBlock* block)
47284743
47294744void CodeGen::genReserveEpilog (BasicBlock* block)
47304745{
4731- regMaskTP gcrefRegsArg = gcInfo.gcRegGCrefSetCur ;
4732- regMaskTP byrefRegsArg = gcInfo.gcRegByrefSetCur ;
4733-
4734- /* The return value is special-cased: make sure it goes live for the epilog */
4735-
4736- bool jmpEpilog = block->HasFlag (BBF_HAS_JMP);
4737-
4738- if (IsFullPtrRegMapRequired () && !jmpEpilog)
4739- {
4740- if (varTypeIsGC (compiler->info .compRetNativeType ))
4741- {
4742- noway_assert (genTypeStSz (compiler->info .compRetNativeType ) == genTypeStSz (TYP_I_IMPL));
4743-
4744- gcInfo.gcMarkRegPtrVal (REG_INTRET, compiler->info .compRetNativeType );
4745-
4746- switch (compiler->info .compRetNativeType )
4747- {
4748- case TYP_REF:
4749- gcrefRegsArg |= RBM_INTRET;
4750- break ;
4751- case TYP_BYREF:
4752- byrefRegsArg |= RBM_INTRET;
4753- break ;
4754- default :
4755- break ;
4756- }
4757-
4758- JITDUMP (" Extending return value GC liveness to epilog\n " );
4759- }
4760- }
4761-
47624746 JITDUMP (" Reserving epilog IG for block " FMT_BB " \n " , block->bbNum );
47634747
47644748 assert (block != nullptr );
4765- const VARSET_TP& gcrefVarsArg (GetEmitter ()->emitThisGCrefVars );
4766- GetEmitter ()->emitCreatePlaceholderIG (IGPT_EPILOG, block, gcrefVarsArg, gcrefRegsArg, byrefRegsArg,
4767- block->IsLast ());
4749+ // We pass empty GC info, because epilog is always an extend IG and will ignore what we pass.
4750+ // Besides, at this point the GC info that we track in CodeGen is often incorrect.
4751+ // See comments in genExitCode for more info.
4752+ GetEmitter ()->emitCreatePlaceholderIG (IGPT_EPILOG, block, VarSetOps::MakeEmpty (compiler), 0 , 0 , block->IsLast ());
47684753}
47694754
47704755/* ****************************************************************************
0 commit comments