From ee9cc1ede162a46f10550db5a1824d350d982f55 Mon Sep 17 00:00:00 2001 From: Graham Chapman Date: Tue, 18 Jul 2023 12:52:12 -0400 Subject: [PATCH] Allow Object to be modifiable in extended HCR Currently, Object is marked unmodifiable if extended HCR is enabled. This change allows Object to be modified, but disallows use of the extensions on Object. Fixes: #17454 Signed-off-by: Graham Chapman --- runtime/bcutil/ROMClassCreationContext.hpp | 5 --- runtime/util/hshelp.c | 37 ++++++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/runtime/bcutil/ROMClassCreationContext.hpp b/runtime/bcutil/ROMClassCreationContext.hpp index 4a79605d1dc..602f78a8ffc 100644 --- a/runtime/bcutil/ROMClassCreationContext.hpp +++ b/runtime/bcutil/ROMClassCreationContext.hpp @@ -247,11 +247,6 @@ class ROMClassCreationContext && (isClassAnon() || isClassHidden()) ) { unmodifiable = true; - } else if (NULL == J9VMJAVALANGOBJECT_OR_NULL(_javaVM)) { - /* Object is currently only allowed to be redefined in fast HCR */ - if (areExtensionsEnabled(_javaVM)) { - unmodifiable = true; - } } } return unmodifiable; diff --git a/runtime/util/hshelp.c b/runtime/util/hshelp.c index 584f568b37b..81c93684547 100644 --- a/runtime/util/hshelp.c +++ b/runtime/util/hshelp.c @@ -84,8 +84,8 @@ static UDATA classPairEquals(void* left, void* right, void* userData); static UDATA findMethodInVTable(J9Method *method, UDATA *vTable); static jvmtiError addClassesRequiringNewITables(J9JavaVM *vm, J9HashTable *classHashTable, UDATA *addedMethodCountPtr, UDATA *addedClassCountPtr, BOOLEAN fastHCR); static jvmtiError verifyFieldsAreSame (J9VMThread * currentThread, UDATA fieldType, J9ROMClass * originalROMClass, J9ROMClass * replacementROMClass, - UDATA extensionsEnabled, UDATA * extensionsUsed); -static jvmtiError verifyMethodsAreSame (J9VMThread * currentThread, J9JVMTIClassPair * classPair, UDATA extensionsEnabled, UDATA * extensionsUsed); + UDATA extensionsEnabled, jvmtiError *extensionError); +static jvmtiError verifyMethodsAreSame (J9VMThread * currentThread, J9JVMTIClassPair * classPair, UDATA extensionsEnabled, jvmtiError *extensionError); static int compareClassDepth (const void *leftPair, const void *rightPair); static UDATA utfsAreIdentical(J9UTF8 * utf1, J9UTF8 * utf2); static UDATA areUTFPairsIdentical(J9UTF8 * leftUtf1, J9UTF8 * leftUtf2, J9UTF8 * rightUtf1, J9UTF8 * rightUtf2); @@ -2975,7 +2975,7 @@ determineClassesToRecreate(J9VMThread * currentThread, jint classCount, static jvmtiError verifyFieldsAreSame(J9VMThread * currentThread, UDATA fieldType, J9ROMClass * originalROMClass, J9ROMClass * replacementROMClass, - UDATA extensionsEnabled, UDATA * extensionsUsed) + UDATA extensionsEnabled, jvmtiError *extensionError) { jvmtiError rc = JVMTI_ERROR_NONE; UDATA originalFieldCount; @@ -3040,7 +3040,7 @@ verifyFieldsAreSame(J9VMThread * currentThread, UDATA fieldType, J9ROMClass * or if ((fieldType == J9AccStatic) && (rc != JVMTI_ERROR_NONE)) { if (extensionsEnabled) { - *extensionsUsed = 1; + *extensionError = rc; rc = JVMTI_ERROR_NONE; } } @@ -3073,9 +3073,9 @@ getOldestClassVersion(J9Class * clazz) * \brief Verify that the methods follow allowed schema change rules * \ingroup * - * @param[in] currentThread - * @param[in] classPair old and replacing class - * @param[in] extensionsEnabled boolean indicating if the extensions are enabled + * @param[in] currentThread + * @param[in] classPair old and replacing class + * @param[out] extensionError error which would occur if extensions are not enabled * @return error code * * If extensions are enabled then none of the schema verification errors matter as they are all allowed. @@ -3092,7 +3092,7 @@ getOldestClassVersion(J9Class * clazz) * */ static jvmtiError -verifyMethodsAreSame(J9VMThread * currentThread, J9JVMTIClassPair * classPair, UDATA extensionsEnabled, UDATA * extensionsUsed) +verifyMethodsAreSame(J9VMThread * currentThread, J9JVMTIClassPair * classPair, UDATA extensionsEnabled, jvmtiError *extensionError) { jvmtiError rc = JVMTI_ERROR_NONE; J9Class * oldestRAMClass; @@ -3106,7 +3106,6 @@ verifyMethodsAreSame(J9VMThread * currentThread, J9JVMTIClassPair * classPair, U originalROMClass = oldestRAMClass->romClass; - /* Verify that the methods are the same */ if (originalROMClass->romMethodCount == replacementROMClass->romMethodCount) { @@ -3244,7 +3243,7 @@ verifyMethodsAreSame(J9VMThread * currentThread, J9JVMTIClassPair * classPair, U /* If extensions are enabled, any error aside of OOM (returned with earlier) is a hint that extensions have been used * and should not be treated as an error */ if (rc != JVMTI_ERROR_NONE) { - *extensionsUsed = 1; + *extensionError = rc; } return JVMTI_ERROR_NONE; @@ -3354,7 +3353,7 @@ verifyClassesAreCompatible(J9VMThread * currentThread, jint class_count, J9JVMTI jint i; for (i = 0; i < class_count; ++i) { - UDATA classUsesExtensions = 0; + jvmtiError extensionError = JVMTI_ERROR_NONE; J9ROMClass * originalROMClass = classPairs[i].originalRAMClass->romClass; J9ROMClass * replacementROMClass = classPairs[i].replacementClass.romClass; jvmtiError rc; @@ -3429,26 +3428,32 @@ verifyClassesAreCompatible(J9VMThread * currentThread, jint class_count, J9JVMTI /* Verify that instance fields are the same */ - rc = verifyFieldsAreSame(currentThread, 0, originalROMClass, replacementROMClass, extensionsEnabled, &classUsesExtensions); + rc = verifyFieldsAreSame(currentThread, 0, originalROMClass, replacementROMClass, extensionsEnabled, &extensionError); if (rc != JVMTI_ERROR_NONE) { return rc; } - /* Verify that static fields are the same */ - rc = verifyFieldsAreSame(currentThread, J9AccStatic, originalROMClass, replacementROMClass, extensionsEnabled, &classUsesExtensions); + rc = verifyFieldsAreSame(currentThread, J9AccStatic, originalROMClass, replacementROMClass, extensionsEnabled, &extensionError); if (rc != JVMTI_ERROR_NONE) { return rc; } /* Verify that the methods are the same */ - rc = verifyMethodsAreSame(currentThread, &classPairs[i], extensionsEnabled, &classUsesExtensions); + rc = verifyMethodsAreSame(currentThread, &classPairs[i], extensionsEnabled, &extensionError); if (rc != JVMTI_ERROR_NONE) { return rc; } + /* Disallow extensions for java.lang.Object */ + if (JVMTI_ERROR_NONE != extensionError) { + if (NULL == J9ROMCLASS_SUPERCLASSNAME(originalROMClass)){ + return extensionError; + } + } + #if JAVA_SPEC_VERSION >= 15 /* Verify that records attributes are the same */ rc = verifyRecordAttributesAreSame(originalROMClass, replacementROMClass); @@ -3497,7 +3502,7 @@ verifyClassesAreCompatible(J9VMThread * currentThread, jint class_count, J9JVMTI } #endif /* JAVA_SPEC_VERSION >= 11 */ - if (0 != classUsesExtensions) { + if (JVMTI_ERROR_NONE != extensionError) { classPairs[i].flags |= J9JVMTI_CLASS_PAIR_FLAG_USES_EXTENSIONS; *extensionsUsed = 1; }