diff --git a/runtime/codert_vm/arm64nathelp.m4 b/runtime/codert_vm/arm64nathelp.m4 index beeafbebc88..198b48a6409 100644 --- a/runtime/codert_vm/arm64nathelp.m4 +++ b/runtime/codert_vm/arm64nathelp.m4 @@ -178,9 +178,9 @@ define({NEW_DUAL_MODE_HELPER},{ ret x0 .L_old_slow_$1: RESTORE_C_NONVOLATILE_REGS + SWITCH_TO_JAVA_STACK .L_done_$1: RESTORE_FPLR - SWITCH_TO_JAVA_STACK ldr x0,[J9VMTHREAD,{#}J9TR_VMThread_returnValue] ret END_PROC($1) @@ -201,9 +201,9 @@ define({NEW_DUAL_MODE_HELPER_NO_RETURN_VALUE},{ ret x0 .L_old_slow_$1: RESTORE_C_NONVOLATILE_REGS + SWITCH_TO_JAVA_STACK .L_done_$1: RESTORE_FPLR - SWITCH_TO_JAVA_STACK ret END_PROC($1) }) diff --git a/runtime/compiler/aarch64/codegen/ARM64PrivateLinkage.cpp b/runtime/compiler/aarch64/codegen/ARM64PrivateLinkage.cpp index 54b5e24705c..90404c59c96 100644 --- a/runtime/compiler/aarch64/codegen/ARM64PrivateLinkage.cpp +++ b/runtime/compiler/aarch64/codegen/ARM64PrivateLinkage.cpp @@ -842,6 +842,7 @@ int32_t J9::ARM64::PrivateLinkage::buildPrivateLinkageArgs(TR::Node *callNode, int32_t argIndex = 0; int32_t numMemArgs = 0; int32_t memArgSize = 0; + int32_t firstExplicitArg = 0; int32_t from, to, step; int32_t argSize = -getOffsetToFirstParm(); int32_t totalSize = 0; @@ -909,6 +910,14 @@ int32_t J9::ARM64::PrivateLinkage::buildPrivateLinkageArgs(TR::Node *callNode, from += step; } + // C helpers have an implicit first argument (the VM thread) that we have to account for + if (linkage == TR_CHelper) + { + TR_ASSERT(numIntArgRegs > 0, "This code doesn't handle passing this implicit arg on the stack"); + numIntegerArgs++; + totalSize += TR::Compiler->om.sizeofReferenceAddress(); + } + for (int32_t i = from; (rightToLeft && i >= to) || (!rightToLeft && i <= to); i += step) { child = callNode->getChild(i); @@ -960,6 +969,19 @@ int32_t J9::ARM64::PrivateLinkage::buildPrivateLinkageArgs(TR::Node *callNode, numIntegerArgs = 0; numFloatArgs = 0; + // C helpers have an implicit first argument (the VM thread) that we have to account for + if (linkage == TR_CHelper) + { + TR_ASSERT(numIntArgRegs > 0, "This code doesn't handle passing this implicit arg on the stack"); + TR::Register *vmThreadArgRegister = cg()->allocateRegister(); + generateMovInstruction(cg(), callNode, vmThreadArgRegister, cg()->getMethodMetaDataRegister()); + dependencies->addPreCondition(vmThreadArgRegister, properties.getIntegerArgumentRegister(numIntegerArgs)); + if (resType.getDataType() == TR::NoType) + dependencies->addPostCondition(vmThreadArgRegister, properties.getIntegerArgumentRegister(numIntegerArgs)); + numIntegerArgs++; + firstExplicitArg = 1; + } + // Helper linkage preserves all argument registers except the return register // TODO: C helper linkage does not, this code needs to make sure argument registers are killed in post dependencies for (int32_t i = from; (rightToLeft && i >= to) || (!rightToLeft && i <= to); i += step) @@ -1021,7 +1043,7 @@ int32_t J9::ARM64::PrivateLinkage::buildPrivateLinkageArgs(TR::Node *callNode, generateMovInstruction(cg(), callNode, tempReg, argRegister); argRegister = tempReg; } - if (numIntegerArgs == 0) + if (numIntegerArgs == firstExplicitArg) { // the first integer argument TR::Register *resultReg; @@ -1029,8 +1051,10 @@ int32_t J9::ARM64::PrivateLinkage::buildPrivateLinkageArgs(TR::Node *callNode, resultReg = cg()->allocateCollectedReferenceRegister(); else resultReg = cg()->allocateRegister(); - dependencies->addPreCondition(argRegister, TR::RealRegister::x0); + dependencies->addPreCondition(argRegister, properties.getIntegerArgumentRegister(numIntegerArgs)); dependencies->addPostCondition(resultReg, TR::RealRegister::x0); + if (firstExplicitArg == 1) + dependencies->addPostCondition(argRegister, properties.getIntegerArgumentRegister(numIntegerArgs)); } else {