From 2969a8a9eaed0081cda5c259f2a34862431f7d60 Mon Sep 17 00:00:00 2001 From: Matthew Hall Date: Wed, 4 Dec 2024 16:29:43 -0500 Subject: [PATCH] Generate inline class equality test for Class.isAssignableFrom on Z adds class equality check as first check; calls C Helper in OOL section on fail Signed-off-by: Matthew Hall --- .../compiler/z/codegen/J9TreeEvaluator.cpp | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp index 1fbf9caaad8..80d722efcc0 100644 --- a/runtime/compiler/z/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/z/codegen/J9TreeEvaluator.cpp @@ -4486,6 +4486,12 @@ genInstanceOfOrCheckCastNullTest(TR::Node* node, TR::CodeGenerator* cg, TR::Regi } } +static void genInlineClassEqualityTest(TR::Node * node, TR::CodeGenerator * cg, TR::Compilation * comp, TR::Register * toClassReg, TR::Register * fromClassReg, TR::LabelSymbol * successLabel) { + cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "checkCastStats/(%s)/Equal", comp->signature()),1,TR::DebugCounter::Undetermined); + generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::getCmpRegOpCode(), node, toClassReg, fromClassReg, TR::InstOpCode::COND_BE, successLabel, false, false); + cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "checkCastStats/(%s)/EqualFail", comp->signature()),1,TR::DebugCounter::Undetermined); +} + /////////////////////////////////////////////////////////////////////////////////////// // checkcastEvaluator - checkcast /////////////////////////////////////////////////////////////////////////////////////// @@ -4599,9 +4605,7 @@ J9::Z::TreeEvaluator::checkcastEvaluator(TR::Node * node, TR::CodeGenerator * cg } else { - cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "checkCastStats/(%s)/Equal", comp->signature()),1,TR::DebugCounter::Undetermined); - generateS390CompareAndBranchInstruction(cg, TR::InstOpCode::getCmpRegOpCode(), node, castClassReg, objClassReg, TR::InstOpCode::COND_BE, doneLabel, false, false); - cg->generateDebugCounter(TR::DebugCounter::debugCounterName(comp, "checkCastStats/(%s)/EqualFail", comp->signature()),1,TR::DebugCounter::Undetermined); + genInlineClassEqualityTest(node, cg, comp, castClassReg, objClassReg, doneLabel); } break; case SuperClassTest: @@ -11633,8 +11637,6 @@ J9::Z::TreeEvaluator::VMarrayCheckEvaluator(TR::Node *node, TR::CodeGenerator *c return 0; } - - ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg) @@ -11789,23 +11791,21 @@ static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg) 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 *fromClassReg = cg->evaluate(node->getFirstChild()); + TR::Register *toClassReg = cg->evaluate(node->getSecondChild()); TR::Register *resultReg = cg->allocateRegister(); TR::LabelSymbol *helperCallLabel = generateLabelSymbol(cg); TR::LabelSymbol *doneLabel = generateLabelSymbol(cg); + TR::LabelSymbol *successLabel = 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); + genInlineClassEqualityTest(node, cg, cg->comp(), toClassReg, fromClassReg, successLabel); /* - * TODO: add inlined tests (classEqualityTest, SuperclassTest, etc) + * TODO: add inlined tests (SuperclassTest, cast class cache, 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); @@ -11818,9 +11818,16 @@ TR::Register *J9::Z::TreeEvaluator::inlineCheckAssignableFromEvaluator(TR::Node generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BRC, node, doneLabel); // exit OOL section outlinedSlowPath->swapInstructionListsWithCompilation(); + TR::RegisterDependencyConditions* deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, 3, cg); + deps->addPostCondition(fromClassReg, TR::RealRegister::AssignAny); + deps->addPostConditionIfNotAlreadyInserted(toClassReg, TR::RealRegister::AssignAny); + deps->addPostCondition(resultReg, TR::RealRegister::AssignAny); + + generateS390LabelInstruction(cg, TR::InstOpCode::label, node, successLabel, deps); + generateRIInstruction(cg, TR::InstOpCode::getLoadHalfWordImmOpCode(), node, resultReg, 1); + generateS390LabelInstruction(cg, TR::InstOpCode::label, node, doneLabel, deps); node->setRegister(resultReg); - return resultReg; }