From 15acde95e64ceb464cffb3b1efdcf474ea26fa46 Mon Sep 17 00:00:00 2001 From: Abdulrahman Alattas Date: Mon, 30 Sep 2024 13:07:30 -0400 Subject: [PATCH] Use baseObj for Unsafe.CAS CardMarking for OffHeap on AArch64 When evaluating Unsafe.CAS while running with Balanced GC and OffHeap enabled, if the object child is the dataAddrPointer load, pass the baseObj to VMCardCheckEvaluator for correct card marking. The dstReg and temp2Reg in VMCardCheckEvaluator can share a reg, adding the argument clobberDstReg to indicate if dstReg can be used as the temp2Reg. Not allocating temp2Reg and adding a dep for baseObjReg uses the same number of registers. Signed-off-by: Abdulrahman Alattas --- .../aarch64/codegen/J9TreeEvaluator.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp b/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp index 6f580e306ad..236790e6fda 100644 --- a/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/aarch64/codegen/J9TreeEvaluator.cpp @@ -987,7 +987,8 @@ VMCardCheckEvaluator( TR::Register *dstReg, TR_ARM64ScratchRegisterManager *srm, TR::LabelSymbol *doneLabel, - TR::CodeGenerator *cg) + TR::CodeGenerator *cg, + bool clobberDstReg=false) { TR::Compilation *comp = cg->comp(); @@ -1014,7 +1015,11 @@ VMCardCheckEvaluator( cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "wrtbarEvaluator:020VMCardCheckEvaluator:01markThreadActiveCheckDone"), *srm); } - TR::Register *temp2Reg = srm->findOrCreateScratchRegister(); + TR::Register *temp2Reg; + if (clobberDstReg) + temp2Reg = dstReg; + else + temp2Reg = srm->findOrCreateScratchRegister(); /* * Generating code checking whether an object is in heap * @@ -5037,7 +5042,13 @@ static TR::Register *VMinlineCompareAndSwapObject(TR::Node *node, TR::CodeGenera fourthChild = node->getChild(3); fifthChild = node->getChild(4); - objReg = cg->evaluate(secondChild); +#if defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) + bool isObjOffHeapDataAddr = (gcMode == gc_modron_wrtbar_cardmark_incremental && TR::Compiler->om.isOffHeapAllocationEnabled() && secondChild->isDataAddrPointer()); + TR::Register *baseObjReg = NULL; + if (isObjOffHeapDataAddr) + TR::TreeEvaluator::stopUsingCopyReg(secondChild->getFirstChild(), baseObjReg, cg); +#endif /* defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) */ + objReg = cg->evaluate(secondChild); if (thirdChild->getOpCode().isLoadConst() && thirdChild->getRegister() == NULL) { @@ -5200,11 +5211,20 @@ static TR::Register *VMinlineCompareAndSwapObject(TR::Node *node, TR::CodeGenera generateCompareBranchInstruction(cg, TR::InstOpCode::cbzx, node, wrtBarSrcReg, doneLabel); cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "wrtbarEvaluator:000srcNullChk:NonNull"), *srm); } - VMCardCheckEvaluator(node, objReg, srm, doneLabel, cg); +#if defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) + if (isObjOffHeapDataAddr) + VMCardCheckEvaluator(node, baseObjReg, srm, doneLabel, cg, true); + else +#endif /* defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) */ + VMCardCheckEvaluator(node, objReg, srm, doneLabel, cg); } TR_ARM64ScratchRegisterDependencyConditions scratchDeps; scratchDeps.addDependency(cg, objReg, doWrtBar ? TR::RealRegister::x0 : TR::RealRegister::NoReg); +#if defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) + if (isObjOffHeapDataAddr) + scratchDeps.addDependency(cg, baseObjReg, TR::RealRegister::NoReg); +#endif /* defined(J9VM_GC_ENABLE_SPARSE_HEAP_ALLOCATION) */ scratchDeps.addDependency(cg, wrtBarSrcReg, doWrtBar ? TR::RealRegister::x1 : TR::RealRegister::NoReg); if (offsetInReg) {