Skip to content

Commit

Permalink
Merge pull request #20590 from matthewhall2/assignableFrom_useCHelper
Browse files Browse the repository at this point in the history
Change Class.isAssignableFrom to use CHelper instead of JNI call on Z
  • Loading branch information
r30shah authored Nov 25, 2024
2 parents 3aff572 + 024edf7 commit fc778d6
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions runtime/compiler/z/codegen/J9CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3815,6 +3815,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;
Expand Down
36 changes: 36 additions & 0 deletions runtime/compiler/z/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11740,6 +11740,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)
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/z/codegen/J9TreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,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
Expand Down
14 changes: 13 additions & 1 deletion runtime/compiler/z/codegen/S390CHelperLinkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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++)
{
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/z/codegen/S390CHelperLinkage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit fc778d6

Please sign in to comment.