Skip to content

Commit

Permalink
Power: Handle monitor enter/exit on value based instances
Browse files Browse the repository at this point in the history
Related to JEP390

Signed-off-by: Annabelle Huo <Annabelle.Huo@ibm.com>
  • Loading branch information
a7ehuo committed Dec 17, 2020
1 parent b58ed1b commit 81af61a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 14 deletions.
32 changes: 19 additions & 13 deletions runtime/compiler/p/codegen/J9TreeEvaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5314,7 +5314,8 @@ TR::Register *J9::Power::TreeEvaluator::VMmonexitEvaluator(TR::Node *node, TR::C

if (comp->getOption(TR_OptimizeForSpace) ||
comp->getOption(TR_FullSpeedDebug) ||
(TR::Compiler->om.areValueTypesEnabled() && cg->isMonitorValueType(node) == TR_yes) ||
((TR::Compiler->om.areValueTypesEnabled() || TR::Compiler->om.areValueBasedMonitorChecksEnabled()) &&
(cg->isMonitorValueBasedOrValueType(node) == TR_yes)) ||
comp->getOption(TR_DisableInlineMonExit))
{
TR::ILOpCodes opCode = node->getOpCodeValue();
Expand Down Expand Up @@ -5386,10 +5387,11 @@ TR::Register *J9::Power::TreeEvaluator::VMmonexitEvaluator(TR::Node *node, TR::C
generateLabelInstruction(cg, TR::InstOpCode::label, node, startLabel, NULL);
startLabel->setStartInternalControlFlow();

//If object is not known to be value type at compile time, check at run time
if (TR::Compiler->om.areValueTypesEnabled() && cg->isMonitorValueType(node) == TR_maybe)
//If object is not known to be value type or value based class at compile time, check at run time
if ((TR::Compiler->om.areValueTypesEnabled() || TR::Compiler->om.areValueBasedMonitorChecksEnabled())
&& (cg->isMonitorValueBasedOrValueType(node) == TR_maybe))
{
generateCheckForValueTypeMonitorEnterOrExit(node, callLabel, objReg, objectClassReg, tempReg, condReg, cg);
generateCheckForValueMonitorEnterOrExit(node, callLabel, objReg, objectClassReg, tempReg, threadReg, condReg, cg, J9_CLASS_DISALLOWS_LOCKING_FLAGS);
}

bool simpleLocking = false;
Expand Down Expand Up @@ -7718,7 +7720,7 @@ static bool simpleReadMonitor(TR::Node *node, TR::CodeGenerator *cg, TR::Node *o
return true;
}

void J9::Power::TreeEvaluator::generateCheckForValueTypeMonitorEnterOrExit(TR::Node *node, TR::LabelSymbol *helperCallLabel, TR::Register *objReg, TR::Register *objectClassReg, TR::Register *tempReg, TR::Register *condReg, TR::CodeGenerator *cg)
void J9::Power::TreeEvaluator::generateCheckForValueMonitorEnterOrExit(TR::Node *node, TR::LabelSymbol *helperCallLabel, TR::Register *objReg, TR::Register *objectClassReg, TR::Register *temp1Reg, TR::Register *temp2Reg, TR::Register *condReg, TR::CodeGenerator *cg, int32_t classFlag)
{
//get class of object
generateLoadJ9Class(node, objectClassReg, objReg, cg);
Expand All @@ -7727,11 +7729,13 @@ void J9::Power::TreeEvaluator::generateCheckForValueTypeMonitorEnterOrExit(TR::N
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg->fe());
TR::MemoryReference *classFlagsMemRef = TR::MemoryReference::createWithDisplacement(cg, objectClassReg, static_cast<uintptr_t>(fej9->getOffsetOfClassFlags()), 4);

//check J9ClassIsValueType flag
generateTrg1MemInstruction(cg,TR::InstOpCode::lwz, node, tempReg, classFlagsMemRef);
generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::andi_r, node, tempReg, tempReg, condReg, J9ClassIsValueType);
//check J9_CLASS_DISALLOWS_LOCKING_FLAGS (J9ClassIsValueType | J9ClassIsValueBased)
generateTrg1MemInstruction(cg, TR::InstOpCode::lwz, node, temp1Reg, classFlagsMemRef);

//If obj is value type, call VM helper and throw IllegalMonitorState exception, else continue as usual
loadConstant(cg, node, classFlag, temp2Reg);
generateTrg1Src2Instruction(cg, TR::InstOpCode::and_r, node, temp1Reg, temp1Reg, temp2Reg);

//If obj is value type or value based class instance, call VM helper and throw IllegalMonitorState exception, else continue as usual
generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, helperCallLabel, condReg);
}

Expand All @@ -7745,7 +7749,8 @@ TR::Register *J9::Power::TreeEvaluator::VMmonentEvaluator(TR::Node *node, TR::Co
if (comp->getOption(TR_OptimizeForSpace) ||
comp->getOption(TR_MimicInterpreterFrameShape) ||
(comp->getOption(TR_FullSpeedDebug) && node->isSyncMethodMonitor()) ||
(TR::Compiler->om.areValueTypesEnabled() && cg->isMonitorValueType(node) == TR_yes) ||
((TR::Compiler->om.areValueTypesEnabled() || TR::Compiler->om.areValueBasedMonitorChecksEnabled()) &&
(cg->isMonitorValueBasedOrValueType(node) == TR_yes)) ||
comp->getOption(TR_DisableInlineMonEnt))
{
TR::ILOpCodes opCode = node->getOpCodeValue();
Expand Down Expand Up @@ -7817,10 +7822,11 @@ TR::Register *J9::Power::TreeEvaluator::VMmonentEvaluator(TR::Node *node, TR::Co
generateLabelInstruction(cg, TR::InstOpCode::label, node, startLabel, NULL);
startLabel->setStartInternalControlFlow();

//If object is not known to be value type at compile time, check at run time
if (TR::Compiler->om.areValueTypesEnabled() && cg->isMonitorValueType(node) == TR_maybe)
//If object is not known to be value type or value based class at compile time, check at run time
if ((TR::Compiler->om.areValueTypesEnabled() || TR::Compiler->om.areValueBasedMonitorChecksEnabled())
&& (cg->isMonitorValueBasedOrValueType(node) == TR_maybe))
{
generateCheckForValueTypeMonitorEnterOrExit(node, callLabel, objReg, objectClassReg, tempReg, condReg, cg);
generateCheckForValueMonitorEnterOrExit(node, callLabel, objReg, objectClassReg, tempReg, offsetReg, condReg, cg, J9_CLASS_DISALLOWS_LOCKING_FLAGS);
}

bool simpleLocking = false;
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/p/codegen/J9TreeEvaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class OMR_EXTENSIBLE TreeEvaluator: public J9::TreeEvaluator
static TR::Register *ardbarEvaluator(TR::Node *node, TR::CodeGenerator *cg);
static TR::Register *ardbariEvaluator(TR::Node *node, TR::CodeGenerator *cg);

static void generateCheckForValueTypeMonitorEnterOrExit(TR::Node *node, TR::LabelSymbol *helperCallLabel, TR::Register *objReg, TR::Register *objectClassReg, TR::Register *tempReg, TR::Register *condReg, TR::CodeGenerator *cg);
static void generateCheckForValueMonitorEnterOrExit(TR::Node *node, TR::LabelSymbol *helperCallLabel, TR::Register *objReg, TR::Register *objectClassReg, TR::Register *temp1Reg, TR::Register *temp2Reg, TR::Register *condReg, TR::CodeGenerator *cg, int32_t classFlag);
static void restoreTOCRegister(TR::Node *node, TR::CodeGenerator *cg, TR::RegisterDependencyConditions *dependencies);
static void buildArgsProcessFEDependencies(TR::Node *node, TR::CodeGenerator *cg, TR::RegisterDependencyConditions *dependencies);
static TR::Register *retrieveTOCRegister(TR::Node *node, TR::CodeGenerator *cg, TR::RegisterDependencyConditions *dependencies);
Expand Down

0 comments on commit 81af61a

Please sign in to comment.