diff --git a/runtime/compiler/p/codegen/J9TreeEvaluator.cpp b/runtime/compiler/p/codegen/J9TreeEvaluator.cpp index 461e26e25f6..66f37dc7fc5 100644 --- a/runtime/compiler/p/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/p/codegen/J9TreeEvaluator.cpp @@ -5175,7 +5175,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(); @@ -5247,10 +5248,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; @@ -7579,7 +7581,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); @@ -7588,11 +7590,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(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); } @@ -7606,7 +7610,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(); @@ -7678,10 +7683,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; diff --git a/runtime/compiler/p/codegen/J9TreeEvaluator.hpp b/runtime/compiler/p/codegen/J9TreeEvaluator.hpp index 8093b9cc0f5..b5856418966 100644 --- a/runtime/compiler/p/codegen/J9TreeEvaluator.hpp +++ b/runtime/compiler/p/codegen/J9TreeEvaluator.hpp @@ -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);