diff --git a/runtime/oti/j9.h b/runtime/oti/j9.h index 3889ba65569..94a03842ab1 100644 --- a/runtime/oti/j9.h +++ b/runtime/oti/j9.h @@ -362,6 +362,7 @@ static const struct { \ #define J9_IS_NULL_RESTRICTED_FIELD_FLATTENED(fieldClazz, romFieldShape) FALSE #define J9_VALUETYPE_FLATTENED_SIZE(clazz)((UDATA) 0) /* It is not possible for this macro to be used since we always check J9_IS_J9CLASS_FLATTENED before ever using it. */ #define J9_IS_J9ARRAYCLASS_NULL_RESTRICTED(clazz) FALSE +#define J9CLASS_GET_NULLRESTRICTED_ARRAY(clazz) NULL #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ #define IS_REF_OR_VAL_SIGNATURE(firstChar) ('L' == (firstChar)) diff --git a/runtime/vm/classsupport.c b/runtime/vm/classsupport.c index 322e59f402c..9ae37bf1980 100644 --- a/runtime/vm/classsupport.c +++ b/runtime/vm/classsupport.c @@ -188,20 +188,8 @@ findPrimitiveArrayClass(J9JavaVM* vm, jchar sigChar) } } - -/** - * @internal - * - * Allocates and fills in the relevant fields of an array class - */ -J9Class * -internalCreateArrayClass(J9VMThread *vmThread, J9ROMArrayClass *romClass, J9Class *elementClass) -{ - return internalCreateArrayClassWithOptions(vmThread, romClass, elementClass, 0); -} - -J9Class * -internalCreateArrayClassWithOptions(J9VMThread *vmThread, J9ROMArrayClass *romClass, J9Class *elementClass, UDATA options) +static J9Class * +internalCreateArrayClassHelper(J9VMThread *vmThread, J9ROMArrayClass *romClass, J9Class *elementClass, UDATA options) { J9Class *result = NULL; j9object_t heapClass = J9VM_J9CLASS_TO_HEAPCLASS(elementClass); @@ -217,8 +205,12 @@ internalCreateArrayClassWithOptions(J9VMThread *vmThread, J9ROMArrayClass *romCl * creating an instance of the array. Element class init must be done * before the arrayClass is created so that in the case of an init failure * the arrayClass is not temporarily exposed. + * Don't try to initialize class for null-restricted array creation since + * the regular arrayClass will always be created first. */ - if (J9_IS_J9CLASS_ALLOW_DEFAULT_VALUE(elementClass)) { + if (J9_IS_J9CLASS_ALLOW_DEFAULT_VALUE(elementClass) + && J9_ARE_NO_BITS_SET(options, J9_FINDCLASS_FLAG_CLASS_OPTION_NULL_RESTRICTED_ARRAY) + ) { UDATA initStatus = elementClass->initializeStatus; if ((J9ClassInitSucceeded != initStatus) && ((UDATA)vmThread != initStatus)) { initializeClass(vmThread, elementClass); @@ -267,6 +259,31 @@ internalCreateArrayClassWithOptions(J9VMThread *vmThread, J9ROMArrayClass *romCl return result; } +/** + * @internal + * + * Allocates and fills in the relevant fields of an array class + */ +J9Class * +internalCreateArrayClass(J9VMThread *vmThread, J9ROMArrayClass *romClass, J9Class *elementClass) +{ + return internalCreateArrayClassHelper(vmThread, romClass, elementClass, 0); +} + +J9Class * +internalCreateArrayClassWithOptions(J9VMThread *vmThread, J9ROMArrayClass *romClass, J9Class *elementClass, UDATA options) +{ + /* Create elementClass's arrayClass as a prerequisite to nullRestrictedArrayClass */ + if (J9_ARE_ALL_BITS_SET(options, J9_FINDCLASS_FLAG_CLASS_OPTION_NULL_RESTRICTED_ARRAY) + && (NULL == elementClass->arrayClass) + ) { + if (NULL == internalCreateArrayClassHelper(vmThread, romClass, elementClass, 0)) { + return NULL; + } + } + return internalCreateArrayClassHelper(vmThread, romClass, elementClass, options); +} + /** * Peek the classHashTable to see if the `className` class has already been loaded by `classLoader`. * diff --git a/runtime/vm/createramclass.cpp b/runtime/vm/createramclass.cpp index f0e840b3a62..5b0bb1422cc 100644 --- a/runtime/vm/createramclass.cpp +++ b/runtime/vm/createramclass.cpp @@ -2404,18 +2404,14 @@ internalCreateRAMClassDone(J9VMThread *vmThread, J9ClassLoader *classLoader, J9C if (J9ROMCLASS_IS_ARRAY(romClass)) { #if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) if (J9_ARE_ALL_BITS_SET(options, J9_FINDCLASS_FLAG_CLASS_OPTION_NULL_RESTRICTED_ARRAY)) { + ((J9ArrayClass *)state->ramClass)->companionArray = elementClass->arrayClass; elementClass->nullRestrictedArrayClass = state->ramClass; + ((J9ArrayClass *)elementClass->arrayClass)->companionArray = elementClass->nullRestrictedArrayClass; } else #endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ { ((J9ArrayClass *)elementClass)->arrayClass = state->ramClass; } -#if defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) - if ((NULL != elementClass->nullRestrictedArrayClass) && (NULL != elementClass->arrayClass)) { - ((J9ArrayClass *)elementClass->arrayClass)->companionArray = elementClass->nullRestrictedArrayClass; - ((J9ArrayClass *)elementClass->nullRestrictedArrayClass)->companionArray = elementClass->arrayClass; - } -#endif /* defined(J9VM_OPT_VALHALLA_FLATTENABLE_VALUE_TYPES) */ /* Assigning into the arrayClass field creates an implicit reference to the class from its class loader */ javaVM->memoryManagerFunctions->j9gc_objaccess_postStoreClassToClassLoader(vmThread, classLoader, state->ramClass); }