Skip to content

Commit

Permalink
Enable new Class.isAssignableFrom evaluator on Z
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Hall <[email protected]>
  • Loading branch information
matthewhall2 committed Dec 19, 2024
1 parent 85b9c02 commit 6d61188
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 156 deletions.
7 changes: 7 additions & 0 deletions runtime/compiler/z/codegen/J9CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4252,3 +4252,10 @@ J9::Z::CodeGenerator::supportsTrapsInTMRegion()
{
return self()->comp()->target().isZOS();
}

bool
J9::Z::CodeGenerator::supportsInliningOfIsAssignableFrom()
{
static const bool disableInliningOfIsAssignableFrom = feGetEnv("TR_disableInlineIsAssignableFrom") != NULL;
return !disableInliningOfIsAssignableFrom;
}
1 change: 1 addition & 0 deletions runtime/compiler/z/codegen/J9CodeGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class OMR_EXTENSIBLE CodeGenerator : public J9::CodeGenerator
bool constLoadNeedsLiteralFromPool(TR::Node *node);

bool supportsTrapsInTMRegion();
bool supportsInliningOfIsAssignableFrom();

using J9::CodeGenerator::addAllocatedRegister;
void addAllocatedRegister(TR_PseudoRegister * temp);
Expand Down
156 changes: 0 additions & 156 deletions runtime/compiler/z/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11573,157 +11573,6 @@ J9::Z::TreeEvaluator::VMarrayCheckEvaluator(TR::Node *node, TR::CodeGenerator *c
return 0;
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
static bool inlineIsAssignableFrom(TR::Node *node, TR::CodeGenerator *cg)
{
static char *disable = feGetEnv("TR_disableInlineIsAssignableFrom");
TR::Compilation *comp = cg->comp();
TR_J9VMBase *fej9 = (TR_J9VMBase *)(comp->fe());

if (disable)
return false;

TR::Node *thisClass = node->getFirstChild();
if (thisClass->getOpCodeValue() == TR::aloadi &&
thisClass->getFirstChild()->getOpCodeValue() == TR::loadaddr)
{
TR::SymbolReference *thisClassSymRef = thisClass->getFirstChild()->getSymbolReference();

if (thisClassSymRef->isClassInterface(comp) || thisClassSymRef->isClassAbstract(comp))
{
return false;
}
}

int32_t classDepth = -1;
TR::Node *javaLangClassFrom = node->getFirstChild();
if((javaLangClassFrom->getOpCodeValue() == TR::aloadi
&& javaLangClassFrom->getSymbolReference() == comp->getSymRefTab()->findJavaLangClassFromClassSymbolRef()
&& javaLangClassFrom->getFirstChild()->getOpCodeValue() == TR::loadaddr))
{
TR::Node *castClassRef =javaLangClassFrom->getFirstChild();

TR::SymbolReference *castClassSymRef = NULL;
if(castClassRef->getOpCode().hasSymbolReference())
castClassSymRef= castClassRef->getSymbolReference();

TR::StaticSymbol *castClassSym = NULL;
if (castClassSymRef && !castClassSymRef->isUnresolved())
castClassSym= castClassSymRef ? castClassSymRef->getSymbol()->getStaticSymbol() : NULL;

TR_OpaqueClassBlock * clazz = NULL;
if (castClassSym)
clazz = (TR_OpaqueClassBlock *) castClassSym->getStaticAddress();

if(clazz)
classDepth = (int32_t)TR::Compiler->cls.classDepthOf(clazz);
}

TR::Register *returnRegister = NULL;
TR::SymbolReference *symRef = node->getSymbolReference();
TR::MethodSymbol *callSymbol = symRef->getSymbol()->castToMethodSymbol();

TR::LabelSymbol *startLabel = generateLabelSymbol(cg);
// startLabel->setStartInternalControlFlow();
TR::LabelSymbol *doneLabel = generateLabelSymbol(cg);
TR::LabelSymbol *failLabel = generateLabelSymbol(cg);
TR::LabelSymbol *outlinedCallLabel = generateLabelSymbol(cg);
// doneLabel->setEndInternalControlFlow();

TR::Register *thisClassReg = cg->evaluate(node->getFirstChild());
TR::Register *checkClassReg = cg->evaluate(node->getSecondChild());

TR::RegisterDependencyConditions * deps = NULL;


TR::Register *tempReg = cg->allocateRegister();
TR::Register *objClassReg, *castClassReg, *scratch1Reg,*scratch2Reg;
int8_t numOfPostDepConditions = (thisClassReg == checkClassReg)? 2 : 3;


if (classDepth != -1)
{
deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, numOfPostDepConditions+4, cg);
objClassReg = cg->allocateRegister();
castClassReg = cg->allocateRegister();
scratch1Reg = cg->allocateRegister();
scratch2Reg = cg->allocateRegister();
deps->addPostCondition(scratch1Reg, TR::RealRegister::AssignAny);
deps->addPostCondition(scratch2Reg, TR::RealRegister::AssignAny);
deps->addPostCondition(castClassReg, TR::RealRegister::AssignAny);
deps->addPostCondition(objClassReg, TR::RealRegister::AssignAny);

}
else
{
deps = new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0, numOfPostDepConditions, cg);
objClassReg = tempReg;
}

deps->addPostCondition(thisClassReg, TR::RealRegister::AssignAny);
if (thisClassReg != checkClassReg)
{
deps->addPostCondition(checkClassReg, TR::RealRegister::AssignAny);
}
deps->addPostCondition(tempReg, TR::RealRegister::AssignAny);

generateS390LabelInstruction(cg, TR::InstOpCode::label, node, startLabel);

generateRRInstruction(cg, TR::InstOpCode::getLoadTestRegOpCode(), node, thisClassReg, thisClassReg);
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BE, node, outlinedCallLabel);
generateRRInstruction(cg, TR::InstOpCode::getLoadTestRegOpCode(), node, checkClassReg, checkClassReg);
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BE, node, outlinedCallLabel);

generateRXInstruction(cg, TR::InstOpCode::getLoadOpCode(), node, objClassReg,
generateS390MemoryReference(checkClassReg, fej9->getOffsetOfClassFromJavaLangClassField(), cg));

generateRXInstruction(cg, TR::InstOpCode::getCmpLogicalOpCode(), node, objClassReg,
generateS390MemoryReference(thisClassReg, fej9->getOffsetOfClassFromJavaLangClassField(), cg));

generateRIInstruction(cg, TR::InstOpCode::LHI, node, tempReg, 1);

TR_Debug * debugObj = cg->getDebug();
if (classDepth != -1)
{
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BE, node, doneLabel);
generateRXInstruction(cg, TR::InstOpCode::getLoadOpCode(), node, castClassReg,
generateS390MemoryReference(thisClassReg, fej9->getOffsetOfClassFromJavaLangClassField(), cg));

genTestIsSuper(cg, node, objClassReg, castClassReg, scratch1Reg, scratch2Reg, tempReg, NULL, classDepth, failLabel, doneLabel, NULL, deps, NULL, false, NULL, NULL);

generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BE, node, doneLabel);
}
else
{
generateS390BranchInstruction(cg, TR::InstOpCode::BRC, TR::InstOpCode::COND_BNE, node, outlinedCallLabel);
}


TR_S390OutOfLineCodeSection *outlinedHelperCall = new (cg->trHeapMemory()) TR_S390OutOfLineCodeSection(node, TR::icall, tempReg, outlinedCallLabel, doneLabel, cg);
cg->getS390OutOfLineCodeSectionList().push_front(outlinedHelperCall);
outlinedHelperCall->generateS390OutOfLineCodeSectionDispatch();


cg->decReferenceCount(node->getFirstChild());
cg->decReferenceCount(node->getSecondChild());

node->setRegister(tempReg);

if (classDepth != -1)
{
generateS390LabelInstruction(cg, TR::InstOpCode::label, node, failLabel, deps);
generateRIInstruction(cg, TR::InstOpCode::LHI, node, tempReg, 0);

cg->stopUsingRegister(objClassReg);
cg->stopUsingRegister(castClassReg);
cg->stopUsingRegister(scratch1Reg);
cg->stopUsingRegister(scratch2Reg);
}
generateS390LabelInstruction(cg, TR::InstOpCode::label, node, doneLabel, deps);

return true;
}

TR::Register *J9::Z::TreeEvaluator::inlineCheckAssignableFromEvaluator(TR::Node *node, TR::CodeGenerator *cg)
{
Expand Down Expand Up @@ -11792,11 +11641,6 @@ J9::Z::TreeEvaluator::VMinlineCallEvaluator(TR::Node * node, bool indirect, TR::
{
switch (methodSymbol->getRecognizedMethod())
{
case TR::java_lang_Class_isAssignableFrom:
{
callWasInlined = inlineIsAssignableFrom(node, cg);
break;
}
default:
break;
}
Expand Down

0 comments on commit 6d61188

Please sign in to comment.