From 877a403fd4a0d4700b0e95c40ecec019782c3a31 Mon Sep 17 00:00:00 2001 From: Rahil Shah Date: Tue, 28 Oct 2025 14:17:35 -0400 Subject: [PATCH] Mark GPR15 unpreserved for Helper call on z/OS On z/OS when returning from interpreter back to JIT compiled code, a branch is made through GPR15. For XPLINK, GPR15 is considered preserved register so JIT compiled code when dispatching the helper call would consider it as preserved register. In cases when we return back to JIT compiled code from interpreter, it could clobber GPR15 to branch back to JIT. This is a unique issue uncovered with synchronized virtual thread where helper call to jitMonitorEnter from JIT compiled code can return back from interpreter. Changes in this commit would mark GPR15 not preserved so it will be preserved as helper dispatch sequence. Signed-off-by: Rahil Shah --- runtime/compiler/z/codegen/S390CHelperLinkage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/compiler/z/codegen/S390CHelperLinkage.cpp b/runtime/compiler/z/codegen/S390CHelperLinkage.cpp index 0662331ba85..bc63a958f3c 100644 --- a/runtime/compiler/z/codegen/S390CHelperLinkage.cpp +++ b/runtime/compiler/z/codegen/S390CHelperLinkage.cpp @@ -66,7 +66,6 @@ J9::Z::CHelperLinkage::CHelperLinkage(TR::CodeGenerator * codeGen,TR_LinkageConv setRegisterFlag(TR::RealRegister::GPR10, Preserved); setRegisterFlag(TR::RealRegister::GPR11, Preserved); setRegisterFlag(TR::RealRegister::GPR13, Preserved); - setRegisterFlag(TR::RealRegister::GPR15, Preserved); #if defined(ENABLE_PRESERVED_FPRS) // In case of 32bit Linux on Z, System Linkage only preserves FPR4 and FPR6. For all other targets, FPR8-FPR15 is @@ -95,6 +94,7 @@ J9::Z::CHelperLinkage::CHelperLinkage(TR::CodeGenerator * codeGen,TR_LinkageConv setRegisterFlag(TR::RealRegister::GPR6, Preserved); setRegisterFlag(TR::RealRegister::GPR7, Preserved); setRegisterFlag(TR::RealRegister::GPR12, Preserved); + setRegisterFlag(TR::RealRegister::GPR15, Preserved); setReturnAddressRegister(TR::RealRegister::GPR14); setIntegerReturnRegister(TR::RealRegister::GPR2);