From 4b5152e11651f80a08efeebadbab4c10c51041d6 Mon Sep 17 00:00:00 2001 From: Annabelle Huo Date: Tue, 17 Dec 2024 13:26:33 -0500 Subject: [PATCH] Add methods to check if array class can be trusted as fixed class If null-restricted array is enabled and the class is an array class, the null-restricted array class and the nullable array class share the same signature. The null-restricted array can be viewed as a sub-type of the nullable array. Therefore, the constraint cannot be fixed class. Related: #20522 Signed-off-by: Annabelle Huo --- .../compiler/optimizer/J9ValuePropagation.cpp | 48 +++++++++++++++++++ .../compiler/optimizer/J9ValuePropagation.hpp | 19 ++++++++ 2 files changed, 67 insertions(+) diff --git a/runtime/compiler/optimizer/J9ValuePropagation.cpp b/runtime/compiler/optimizer/J9ValuePropagation.cpp index ede01a33826..b08a07020c8 100644 --- a/runtime/compiler/optimizer/J9ValuePropagation.cpp +++ b/runtime/compiler/optimizer/J9ValuePropagation.cpp @@ -3835,6 +3835,54 @@ bool J9::ValuePropagation::isUnreliableSignatureType( return true; } +bool J9::ValuePropagation::canArrayClassBeTrustedAsFixedClass(TR_OpaqueClassBlock *arrayClass, TR_OpaqueClassBlock *componentClass) + { + if (TR::Compiler->om.areFlattenableValueTypesEnabled() && + !TR::Compiler->cls.isArrayNullRestricted(comp(), arrayClass) && // If the array is null-restricted array, we know it is a fixed class + TR::Compiler->cls.isValueTypeClass(componentClass)) + return false; + + return true; + } + +bool J9::ValuePropagation::canClassBeTrustedAsFixedClass(TR::SymbolReference *symRef, TR_OpaqueClassBlock *classObject) + { + if (!TR::Compiler->om.areFlattenableValueTypesEnabled()) + return true; + + if (!classObject && symRef && symRef->getSymbol()->isClassObject()) + { + if (!symRef->isUnresolved()) + { + classObject = (TR_OpaqueClassBlock*)symRef->getSymbol()->getStaticSymbol()->getStaticAddress(); + } + else + { + int32_t len; + const char *name = TR::Compiler->cls.classNameChars(comp(), symRef, len); + char *sig = TR::Compiler->cls.classNameToSignature(name, len, comp()); + classObject = fe()->getClassFromSignature(sig, len, symRef->getOwningMethod(comp())); + } + } + + if (classObject) + { + // If null-restricted array is enabled and the class is an array class, the null-restricted array + // class and the nullable array class share the same signature. The null-restricted array can be + // viewed as a sub-type of the nullable array. Therefore, if the array is not a null-restricted array, + // it can't be trusted as a fixed class. + int32_t numDims = 0; + TR_OpaqueClassBlock *klass = comp()->fej9()->getBaseComponentClass(classObject, numDims); + + if ((numDims > 0) && + !TR::Compiler->cls.isArrayNullRestricted(comp(), classObject) && // If the array is null-restricted array, we know it is a fixed class + TR::Compiler->cls.isValueTypeClass(klass)) + return false; + } + + return true; + } + static void getHelperSymRefs(OMR::ValuePropagation *vp, TR::Node *curCallNode, TR::SymbolReference *&getHelpersSymRef, TR::SymbolReference *&helperSymRef, const char *helperSig, int32_t helperSigLen, TR::MethodSymbol::Kinds helperCallKind) { //Function to retrieve the JITHelpers.getHelpers and JITHelpers. method symbol references. diff --git a/runtime/compiler/optimizer/J9ValuePropagation.hpp b/runtime/compiler/optimizer/J9ValuePropagation.hpp index 3f11d45871a..a0eb67e6bc3 100644 --- a/runtime/compiler/optimizer/J9ValuePropagation.hpp +++ b/runtime/compiler/optimizer/J9ValuePropagation.hpp @@ -61,6 +61,25 @@ class ValuePropagation : public OMR::ValuePropagation bool isKnownStringObject(TR::VPConstraint *constraint); TR_YesNoMaybe isStringObject(TR::VPConstraint *constraint); + /** + * \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); + /** * Determine whether the type is, or might be, a value type. Note that * a null reference can be cast to a value type that is not a primitive