Skip to content

Commit 2834926

Browse files
jakobbotschpull[bot]
authored andcommitted
JIT: Fix profiler enter callback init reg trash logic (#100637)
During prolog generation we sometimes generate code to call the profiler enter callback. This may trash the "initReg" that we expect to keep zeroed during the prolog. The logic to check if the initReg was being trashed was wrong in a couple of cases: - Most backends did not take into account that the logic also trashes the registers used for arguments to the enter callback - SysV x64 thought that the enter callback trashed the parameter registers, but it does not This generally did not cause issues because `genFnPrologCalleeRegArgs` is unnecessarily conservative around whether or not it trashes `initReg`, and it comes after the profiler callback in the prolog. However, with the rewrite of the homing function that is not going to be the case anymore.
1 parent 919ef15 commit 2834926

File tree

6 files changed

+36
-14
lines changed

6 files changed

+36
-14
lines changed

src/coreclr/jit/codegenarm.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,10 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
17101710
0, // argSize. Again, we have to lie about it
17111711
EA_UNKNOWN); // retSize
17121712

1713-
if (initReg == argReg)
1713+
// If initReg is trashed, either because it was an arg to the enter
1714+
// callback, or because the enter callback itself trashes it, then it needs
1715+
// to be zero'ed again before using.
1716+
if (((RBM_PROFILER_ENTER_TRASH | RBM_PROFILER_ENTER_ARG) & genRegMask(initReg)) != RBM_NONE)
17141717
{
17151718
*pInitRegZeroed = false;
17161719
}

src/coreclr/jit/codegenarm64.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5455,7 +5455,11 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
54555455

54565456
genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN);
54575457

5458-
if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE)
5458+
// If initReg is trashed, either because it was an arg to the enter
5459+
// callback, or because the enter callback itself trashes it, then it needs
5460+
// to be zero'ed again before using.
5461+
if (((RBM_PROFILER_ENTER_TRASH | RBM_PROFILER_ENTER_ARG_FUNC_ID | RBM_PROFILER_ENTER_ARG_CALLER_SP) &
5462+
genRegMask(initReg)) != RBM_NONE)
54595463
{
54605464
*pInitRegZeroed = false;
54615465
}

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8551,7 +8551,11 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
85518551

85528552
genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN);
85538553

8554-
if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE)
8554+
// If initReg is trashed, either because it was an arg to the enter
8555+
// callback, or because the enter callback itself trashes it, then it needs
8556+
// to be zero'ed again before using.
8557+
if (((RBM_PROFILER_ENTER_TRASH | RBM_PROFILER_ENTER_ARG_FUNC_ID | RBM_PROFILER_ENTER_ARG_CALLER_SP) &
8558+
genRegMask(initReg)) != RBM_NONE)
85558559
{
85568560
*pInitRegZeroed = false;
85578561
}

src/coreclr/jit/codegenriscv64.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8541,7 +8541,11 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
85418541

85428542
genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN);
85438543

8544-
if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH))
8544+
// If initReg is trashed, either because it was an arg to the enter
8545+
// callback, or because the enter callback itself trashes it, then it needs
8546+
// to be zero'ed again before using.
8547+
if (((RBM_PROFILER_ENTER_TRASH | RBM_PROFILER_ENTER_ARG_FUNC_ID | RBM_PROFILER_ENTER_ARG_CALLER_SP) &
8548+
genRegMask(initReg)) != RBM_NONE)
85458549
{
85468550
*pInitRegZeroed = false;
85478551
}

src/coreclr/jit/codegenxarch.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9491,8 +9491,10 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
94919491
}
94929492
}
94939493

9494-
// If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using.
9495-
if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0)
9494+
// If initReg is trashed, either because it was an arg to the enter
9495+
// callback, or because the enter callback itself trashes it, then it needs
9496+
// to be zero'ed again before using.
9497+
if (((RBM_PROFILER_ENTER_TRASH | RBM_ARG_0 | RBM_ARG_1) & genRegMask(initReg)) != 0)
94969498
{
94979499
*pInitRegZeroed = false;
94989500
}
@@ -9528,8 +9530,10 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
95289530
// "mov r11, helper addr; call r11"
95299531
genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN, REG_DEFAULT_PROFILER_CALL_TARGET);
95309532

9531-
// If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using.
9532-
if ((RBM_CALLEE_TRASH & genRegMask(initReg)) != 0)
9533+
// If initReg is trashed, either because it was an arg to the enter
9534+
// callback, or because the enter callback itself trashes it, then it needs
9535+
// to be zero'ed again before using.
9536+
if (((RBM_PROFILER_ENTER_TRASH | RBM_PROFILER_ENTER_ARG_0 | RBM_PROFILER_ENTER_ARG_1) & genRegMask(initReg)) != 0)
95339537
{
95349538
*pInitRegZeroed = false;
95359539
}

src/coreclr/jit/targetamd64.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,6 @@
511511
#define RBM_FLTARG_REGS (RBM_FLTARG_0|RBM_FLTARG_1|RBM_FLTARG_2|RBM_FLTARG_3)
512512
#endif // !UNIX_AMD64_ABI
513513

514-
// The registers trashed by profiler enter/leave/tailcall hook
515-
// See vm\amd64\asmhelpers.asm for more details.
516-
#define RBM_PROFILER_ENTER_TRASH RBM_CALLEE_TRASH
517-
518-
#define RBM_PROFILER_TAILCALL_TRASH RBM_PROFILER_LEAVE_TRASH
519-
520514
// The registers trashed by the CORINFO_HELP_STOP_FOR_GC helper.
521515
#ifdef UNIX_AMD64_ABI
522516
// See vm\amd64\unixasmhelpers.S for more details.
@@ -525,11 +519,20 @@
525519
// The return registers could be any two from the set { RAX, RDX, XMM0, XMM1 }.
526520
// STOP_FOR_GC helper preserves all the 4 possible return registers.
527521
#define RBM_STOP_FOR_GC_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET | RBM_FLOATRET_1 | RBM_INTRET_1))
522+
523+
// The registers trashed by profiler enter/leave/tailcall hook
524+
// See vm\amd64\asmhelpers.S for more details.
525+
#define RBM_PROFILER_ENTER_TRASH (RBM_CALLEE_TRASH & ~(RBM_ARG_REGS|RBM_FLTARG_REGS))
528526
#define RBM_PROFILER_LEAVE_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET | RBM_FLOATRET_1 | RBM_INTRET_1))
527+
#define RBM_PROFILER_TAILCALL_TRASH RBM_PROFILER_LEAVE_TRASH
528+
529529
#else
530530
// See vm\amd64\asmhelpers.asm for more details.
531531
#define RBM_STOP_FOR_GC_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
532+
533+
#define RBM_PROFILER_ENTER_TRASH RBM_CALLEE_TRASH
532534
#define RBM_PROFILER_LEAVE_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
535+
#define RBM_PROFILER_TAILCALL_TRASH RBM_PROFILER_LEAVE_TRASH
533536
#endif
534537

535538
// The registers trashed by the CORINFO_HELP_INIT_PINVOKE_FRAME helper.

0 commit comments

Comments
 (0)