From 024edf7e062c8372f275ab79ce84ae6015bd1980 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Tue, 12 Nov 2024 15:26:01 -0500 Subject: [PATCH] Call CHelper for Class.isAssignableFrom on Z - took out inlined tests - call CHelper in OOL code section - note: while only calling the CHelper does improve perfance over inlined + JNI call, more inlined tests will added in a later PR to further improve performance Signed-off-by: Matthew Hall - enables transformation of call to Class.isAssignableFrom to Signed-off-by: Matthew Hall --- .../compiler/z/codegen/J9CodeGenerator.cpp | 5 +++ .../compiler/z/codegen/J9TreeEvaluator.cpp | 36 +++++++++++++++++++ .../compiler/z/codegen/J9TreeEvaluator.hpp | 1 + .../compiler/z/codegen/S390CHelperLinkage.cpp | 14 +++++++- .../compiler/z/codegen/S390CHelperLinkage.hpp | 1 + 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/runtime/compiler/z/codegen/J9CodeGenerator.cpp b/runtime/compiler/z/codegen/J9CodeGenerator.cpp index 39f582ca876..700ce73e442 100644 --- a/runtime/compiler/z/codegen/J9CodeGenerator.cpp +++ b/runtime/compiler/z/codegen/J9CodeGenerator.cpp @@ -3800,6 +3800,11 @@ J9::Z::CodeGenerator::inlineDirectCall( ReduceSynchronizedFieldLoad::inlineSynchronizedFieldLoad(node, cg); return true; } + else if (node->getSymbolReference()->getReferenceNumber() == TR_checkAssignable) + { + resultReg = TR::TreeEvaluator::inlineCheckAssignableFromEvaluator(node, cg); + return true; + } static const char * enableTRTRE = feGetEnv("TR_enableTRTRE"); static bool disableCAEIntrinsic = feGetEnv("TR_DisableCAEIntrinsic") != NULL; diff --git a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp index a31b14cf52e..7963aedd33c 100644 --- a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp @@ -11627,6 +11627,42 @@ static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg) return true; } +TR::Register *J9::Z::TreeEvaluator::inlineCheckAssignableFromEvaluator(TR::Node *node, TR::CodeGenerator *cg) + { + TR::Register *thisClassReg = cg->evaluate(node->getFirstChild()); + TR::Register *checkClassReg = cg->evaluate(node->getSecondChild()); + + TR::Register *resultReg = cg->allocateRegister(); + TR::LabelSymbol *helperCallLabel = generateLabelSymbol(cg); + TR::LabelSymbol *doneLabel = generateLabelSymbol(cg); + + TR::RegisterDependencyConditions* deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, 3, cg); + deps->addPostCondition(thisClassReg, TR::RealRegister::AssignAny); + deps->addPostConditionIfNotAlreadyInserted(checkClassReg, TR::RealRegister::AssignAny); + deps->addPostCondition(resultReg, TR::RealRegister::AssignAny); + + /* + * TODO: add inlined tests (classEqualityTest, SuperclassTest, etc) + * Inlined tests will be used when possible, or will jump to the OOL section + * and perform the tests using the CHelper when not possible + */ + + generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, helperCallLabel); + TR_S390OutOfLineCodeSection *outlinedSlowPath = new (cg->trHeapMemory()) TR_S390OutOfLineCodeSection(helperCallLabel, doneLabel, cg); + cg->getS390OutOfLineCodeSectionList().push_front(outlinedSlowPath); + outlinedSlowPath->swapInstructionListsWithCompilation(); + + generateS390LabelInstruction(cg, TR::InstOpCode::label, node, helperCallLabel); + resultReg = TR::TreeEvaluator::performCall(node, false, cg); + + generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, doneLabel); // exit OOL section + outlinedSlowPath->swapInstructionListsWithCompilation(); + + generateS390LabelInstruction(cg, TR::InstOpCode::label, node, doneLabel, deps); + node->setRegister(resultReg); + + return resultReg; + } bool J9::Z::TreeEvaluator::VMinlineCallEvaluator(TR::Node * node, bool indirect, TR::CodeGenerator * cg) diff --git a/runtime/compiler/z/codegen/J9TreeEvaluator.hpp b/runtime/compiler/z/codegen/J9TreeEvaluator.hpp index 7744037efb0..8b4549e1b8d 100644 --- a/runtime/compiler/z/codegen/J9TreeEvaluator.hpp +++ b/runtime/compiler/z/codegen/J9TreeEvaluator.hpp @@ -225,6 +225,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public J9::TreeEvaluator static TR::Register *resolveAndNULLCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg); static TR::Register *evaluateNULLCHKWithPossibleResolve(TR::Node *node, bool needResolution, TR::CodeGenerator *cg); static float interpreterProfilingInstanceOfOrCheckCastTopProb(TR::CodeGenerator * cg, TR::Node * node); + static TR::Register *inlineCheckAssignableFromEvaluator(TR::Node *node, TR::CodeGenerator *cg); /** * \brief diff --git a/runtime/compiler/z/codegen/S390CHelperLinkage.cpp b/runtime/compiler/z/codegen/S390CHelperLinkage.cpp index 53e105591fa..0662331ba85 100644 --- a/runtime/compiler/z/codegen/S390CHelperLinkage.cpp +++ b/runtime/compiler/z/codegen/S390CHelperLinkage.cpp @@ -250,6 +250,18 @@ class RealRegisterManager TR::CodeGenerator* _cg; }; +bool J9::Z::CHelperLinkage::getIsFastPathOnly(TR::Node * callNode) + { + auto opCode = callNode->getOpCodeValue(); + if (opCode == TR::instanceof) + { + return true; + } + + TR::SymbolReference * ref = callNode->getSymbolReference(); + return ref == cg()->comp()->getSymRefTab()->findOrCreateRuntimeHelper(TR_checkAssignable); + } + /** \brief Build a JIT helper call. * \details * It generates sequence that prepares parameters for the JIT helper function and generate a helper call. @@ -264,7 +276,7 @@ TR::Register * J9::Z::CHelperLinkage::buildDirectDispatch(TR::Node * callNode, T RealRegisterManager RealRegisters(cg()); bool isHelperCallWithinICF = deps != NULL; // TODO: Currently only jitInstanceOf is fast path helper. Need to modify following condition if we add support for other fast path only helpers - bool isFastPathOnly = callNode->getOpCodeValue() == TR::instanceof; + bool isFastPathOnly = getIsFastPathOnly(callNode); traceMsg(comp(),"%s: Internal Control Flow in OOL : %s\n",callNode->getOpCode().getName(),isHelperCallWithinICF ? "true" : "false" ); for (int i = TR::RealRegister::FirstGPR; i < TR::RealRegister::NumRegisters; i++) { diff --git a/runtime/compiler/z/codegen/S390CHelperLinkage.hpp b/runtime/compiler/z/codegen/S390CHelperLinkage.hpp index 6de4402685b..e990016c1a6 100644 --- a/runtime/compiler/z/codegen/S390CHelperLinkage.hpp +++ b/runtime/compiler/z/codegen/S390CHelperLinkage.hpp @@ -39,6 +39,7 @@ class CHelperLinkage : public TR::Linkage uint32_t _preservedRegisterMapForGC; TR::RealRegister::RegNum _methodMetaDataRegister; TR::RealRegister::RegNum _returnAddressRegister; + bool getIsFastPathOnly(TR::Node * callNode); // Following Regs are needed only in the case of zOS. #if defined(J9ZOS390) TR::RealRegister::RegNum _DSAPointerRegister;