diff --git a/compiler/optimizer/OMRValuePropagation.cpp b/compiler/optimizer/OMRValuePropagation.cpp index 7862669de97..4a79d820c8f 100644 --- a/compiler/optimizer/OMRValuePropagation.cpp +++ b/compiler/optimizer/OMRValuePropagation.cpp @@ -7247,6 +7247,16 @@ bool OMR::ValuePropagation::isUnreliableSignatureType( return false; } +bool OMR::ValuePropagation::canArrayClassBeTrustedAsFixedClass(TR_OpaqueClassBlock *arrayClass, TR_OpaqueClassBlock *componentClass) + { + return true; + } + +bool OMR::ValuePropagation::canClassBeTrustedAsFixedClass(TR::SymbolReference *symRef, TR_OpaqueClassBlock *classObject) + { + return true; + } + void OMR::ValuePropagation::doDelayedTransformations() { ListIterator treesIt1(&_scalarizedArrayCopies); diff --git a/compiler/optimizer/OMRValuePropagation.hpp b/compiler/optimizer/OMRValuePropagation.hpp index c5111403928..142fadf3b2c 100644 --- a/compiler/optimizer/OMRValuePropagation.hpp +++ b/compiler/optimizer/OMRValuePropagation.hpp @@ -662,6 +662,25 @@ class ValuePropagation : public TR::Optimization virtual bool isUnreliableSignatureType( TR_OpaqueClassBlock *klass, TR_OpaqueClassBlock *&erased); + /** + * \brief Determine whether an \p arrayClass with the \p componentClass can be trusted as a fixed class + * + * \param arrayClass The array class. + * \param componentClass The component class of the array. + * + * \return true if an array with the component class can be trusted as a fixed class, and false otherwise. + */ + virtual bool canArrayClassBeTrustedAsFixedClass(TR_OpaqueClassBlock *arrayClass, TR_OpaqueClassBlock *componentClass); + /** + * \brief Determine whether a class retrieved from signature can be trusted as a fixed class + * + * \param symRef The symbol reference of the class object. + * \param classObject The class object to be checked. + * + * \return true if a class can be trusted as a fixed class, and false otherwise. + */ + virtual bool canClassBeTrustedAsFixedClass(TR::SymbolReference *symRef, TR_OpaqueClassBlock *classObject); + struct ObjCloneInfo { TR_ALLOC(TR_Memory::ValuePropagation) diff --git a/compiler/optimizer/VPConstraint.cpp b/compiler/optimizer/VPConstraint.cpp index 297e88fc659..d7ddfa66810 100644 --- a/compiler/optimizer/VPConstraint.cpp +++ b/compiler/optimizer/VPConstraint.cpp @@ -1286,7 +1286,7 @@ TR::VPResolvedClass *TR::VPResolvedClass::create(OMR::ValuePropagation *vp, TR_O // An array class is fixed if the base class for the array is final // TR_OpaqueClassBlock * baseClass = vp->fe()->getLeafComponentClassFromArrayClass(klass); - if (baseClass && TR::Compiler->cls.isClassFinal(vp->comp(), baseClass)) + if (baseClass && TR::Compiler->cls.isClassFinal(vp->comp(), baseClass) && vp->canArrayClassBeTrustedAsFixedClass(klass, baseClass)) return TR::VPFixedClass::create(vp, klass); } else @@ -6078,7 +6078,7 @@ void TR::VPResolvedClass::print(TR::Compilation *comp, TR::FILE *outFile) len = static_cast(strlen(sig)); } - trfprintf(outFile, "class %.*s", len, sig); + trfprintf(outFile, "class 0x%p %.*s", _class, len, sig); if (_typeHintClass) { trfprintf(outFile, " (hint 0x%p", _typeHintClass); diff --git a/compiler/optimizer/VPHandlers.cpp b/compiler/optimizer/VPHandlers.cpp index 61f1bb5865f..d8a549c3aab 100644 --- a/compiler/optimizer/VPHandlers.cpp +++ b/compiler/optimizer/VPHandlers.cpp @@ -1938,6 +1938,7 @@ TR::Node *constrainAload(OMR::ValuePropagation *vp, TR::Node *node) { if (classBlock != jlClass) { + isFixed = isFixed ? vp->canClassBeTrustedAsFixedClass(NULL, classBlock) : isFixed; constraint = TR::VPClassType::create(vp, sig, len, owningMethod, isFixed, classBlock); if (*sig == '[' || sig[0] == 'L') { @@ -11207,9 +11208,11 @@ static void constrainClassObjectLoadaddr( "constrainClassObjectLoadaddr: n%un loadaddr is not for a class\n", node->getGlobalIndex()); + bool isFixed = vp->canClassBeTrustedAsFixedClass(symRef, NULL); + TR::VPConstraint *constraint = TR::VPClass::create( vp, - TR::VPClassType::create(vp, symRef, true), + TR::VPClassType::create(vp, symRef, isFixed), TR::VPNonNullObject::create(vp), NULL, NULL,