From 24ea9c92f7a947a59d66d6a04fab70deca695684 Mon Sep 17 00:00:00 2001 From: Tobi Ajila Date: Mon, 24 Feb 2020 17:27:29 -0500 Subject: [PATCH] Fix bug in resolution of VT arrays and fields When creating an array the elements of the array are set to the default value. For arrays of regular identity types this is NULL. For arrays of valueTypes this is the defaultValue of the valueType. As a result, if the element type of the array is a valueType, the element type must be fully initialized before the array can be created. This PR addresses this problem. Also, in the resolve field code, it is incorrectly fetching the flattened field cache from the class where the fieldref is stored instead of the class that defined the field. We havent noticed this because the existing tests only fetches fields using getter methods. Signed-off-by: Tobi Ajila --- runtime/vm/classsupport.c | 61 +++++++++++++++++++++++------------ runtime/vm/resolvesupport.cpp | 4 +-- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/runtime/vm/classsupport.c b/runtime/vm/classsupport.c index 6596eab8fb0..1988c54a707 100644 --- a/runtime/vm/classsupport.c +++ b/runtime/vm/classsupport.c @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2019 IBM Corp. and others + * Copyright (c) 1991, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -197,35 +197,56 @@ findPrimitiveArrayClass(J9JavaVM* vm, jchar sigChar) J9Class* internalCreateArrayClass(J9VMThread* vmThread, J9ROMArrayClass* romClass, J9Class* elementClass) { - J9Class *result; + J9Class *result = NULL; j9object_t heapClass = J9VM_J9CLASS_TO_HEAPCLASS(elementClass); j9object_t protectionDomain = NULL; J9ROMClass* arrayRomClass = (J9ROMClass*) romClass; J9JavaVM *const javaVM = vmThread->javaVM; UDATA options = 0; - - if (J9_ARE_ANY_BITS_SET(elementClass->classFlags, J9ClassIsAnonymous)) { - options = J9_FINDCLASS_FLAG_ANON; + BOOLEAN elementInitSuccess = TRUE; + +#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) + /* When creating an array of valuetype elements, the array elements are initialized to the defaultValue of the + * element type. As a result the element type must be fully initialized (if its a valuetype) before 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. + */ + if (J9_IS_J9CLASS_VALUETYPE(elementClass)) { + UDATA initStatus = elementClass->initializeStatus; + if ((J9ClassInitSucceeded != initStatus) && ((UDATA)vmThread != initStatus)) { + initializeClass(vmThread, elementClass); + if (NULL != vmThread->currentException) { + elementInitSuccess = FALSE; + } + } } +#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */ - omrthread_monitor_enter(javaVM->classTableMutex); + if (elementInitSuccess) { + if (J9_ARE_ANY_BITS_SET(elementClass->classFlags, J9ClassIsAnonymous)) { + options = J9_FINDCLASS_FLAG_ANON; + } + + omrthread_monitor_enter(javaVM->classTableMutex); + + if (NULL != heapClass) { + protectionDomain = J9VMJAVALANGCLASS_PROTECTIONDOMAIN(vmThread, heapClass); + } - if (NULL != heapClass) { - protectionDomain = J9VMJAVALANGCLASS_PROTECTIONDOMAIN(vmThread, heapClass); + result = internalCreateRAMClassFromROMClass( + vmThread, + elementClass->classLoader, + arrayRomClass, + options, /* options */ + elementClass, + protectionDomain, + NULL, + J9_CP_INDEX_NONE, + LOAD_LOCATION_UNKNOWN, + NULL, + NULL); } - result = internalCreateRAMClassFromROMClass( - vmThread, - elementClass->classLoader, - arrayRomClass, - options, /* options */ - elementClass, - protectionDomain, - NULL, - J9_CP_INDEX_NONE, - LOAD_LOCATION_UNKNOWN, - NULL, - NULL); return result; } diff --git a/runtime/vm/resolvesupport.cpp b/runtime/vm/resolvesupport.cpp index 9b4ca86fe24..1bf38d96b8a 100644 --- a/runtime/vm/resolvesupport.cpp +++ b/runtime/vm/resolvesupport.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 1991, 2019 IBM Corp. and others + * Copyright (c) 1991, 2020 IBM Corp. and others * * This program and the accompanying materials are made available under * the terms of the Eclipse Public License 2.0 which accompanies this @@ -977,7 +977,7 @@ resolveInstanceFieldRefInto(J9VMThread *vmStruct, J9Method *method, J9ConstantPo #if defined(J9VM_OPT_VALHALLA_VALUE_TYPES) if ('Q' == J9UTF8_DATA(signature)[0]) { if (fccEntryFieldNotSet) { - flattenedClassCache = classFromCP->flattenedClassCache; + flattenedClassCache = definingClass->flattenedClassCache; fieldIndex = findIndexInFlattenedClassCache(flattenedClassCache, nameAndSig); flattenableClass = J9_VM_FCC_ENTRY_FROM_FCC(flattenedClassCache, fieldIndex)->clazz; }