From 3ae9c409a9b254a8369e1eb69f1d12c5720429c0 Mon Sep 17 00:00:00 2001 From: akshayben <50454737+akshayben@users.noreply.github.com> Date: Thu, 25 Jul 2019 11:58:59 -0400 Subject: [PATCH] Fix Object References: (#33) * Fix Object References: - fixup object refs for classes found inside hashtable - two pathways related to jcldefine and resolvesupport - created function initializeImageClassObject Signed-off-by: akshayben --- runtime/jcl/common/jcldefine.c | 9 ++++++- runtime/oti/j9nonbuilder.h | 1 + runtime/oti/jvmimage_api.h | 13 +++++++++- runtime/vm/JVMImage.cpp | 43 ++++++++++++++++++++++++++++++++++ runtime/vm/JVMImage.hpp | 1 + runtime/vm/classsupport.c | 6 +++++ runtime/vm/intfunc.c | 1 + 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/runtime/jcl/common/jcldefine.c b/runtime/jcl/common/jcldefine.c index 6c616023a20..d8e21777045 100644 --- a/runtime/jcl/common/jcldefine.c +++ b/runtime/jcl/common/jcldefine.c @@ -131,8 +131,15 @@ defineClassCommon(JNIEnv *env, jobject classLoaderObject, if (vmFuncs->hashClassTableAt(classLoader, utf8Name, utf8Length) != NULL) { /* Bad, we have already defined this class - fail */ omrthread_monitor_exit(vm->classTableMutex); + if (J9_ARE_NO_BITS_SET(options, J9_FINDCLASS_FLAG_NAME_IS_INVALID)) { - vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGLINKAGEERROR, (UDATA *)*(j9object_t*)className); + /* TODO: Incorrect pathway for loading already cached class */ + if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_RAMSTATE_WARM_RUN)) { + clazz = vmFuncs->hashClassTableAt(classLoader, utf8Name, utf8Length); + clazz = vmFuncs->initializeImageClassObject(currentThread, classLoader, clazz); + } else { + vmFuncs->setCurrentException(currentThread, J9VMCONSTANTPOOL_JAVALANGLINKAGEERROR, (UDATA*)* (j9object_t*)className); + } } goto done; } diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 6f8ca6fa2fa..4d6f8e0fcf7 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -4789,6 +4789,7 @@ typedef struct J9InternalVMFunctions { void ( *deregisterCPEntry)(struct J9JavaVM *javaVM, struct J9ClassPathEntry *cpEntry); J9ClassLoader* (*findClassLoader)(struct J9JavaVM *javaVM, uint32_t classLoaderCategory); void (*initializeImageClassLoaderObject)(struct J9JavaVM *javaVM, struct J9ClassLoader *classLoader, j9object_t classLoaderObject); + struct J9Class* (*initializeImageClassObject)(struct J9VMThread *vmThread, struct J9ClassLoader *classLoader, struct J9Class *clazz); } J9InternalVMFunctions; /* Jazz 99339: define a new structure to replace JavaVM so as to pass J9NativeLibrary to JVMTIEnv */ diff --git a/runtime/oti/jvmimage_api.h b/runtime/oti/jvmimage_api.h index ab01f12c389..64a91af6ee5 100644 --- a/runtime/oti/jvmimage_api.h +++ b/runtime/oti/jvmimage_api.h @@ -138,8 +138,19 @@ UDATA* findEntryLocationInTable(ImageTableHeader *table, UDATA entry); J9ClassLoader* findClassLoader(J9JavaVM *javaVM, uint32_t classLoaderCategory); /* -* Initializes class loader object. Mimics behaviour of internalAllocateClassLoader +* Initializes class object. Mimics behaviour of internalCreateRAMClass +* +* @param javaVM[in] the java vm +* @param classLoader the class loader loading the class +* @param clazz the class being loader * +* @return class object if object allocation passes otherwise null +*/ +J9Class* initializeImageClassObject(J9VMThread *vmThread, J9ClassLoader *classLoader, J9Class *clazz); + +/* +* Initializes class loader object. Mimics behaviour of internalAllocateClassLoader +* * @param javaVM[in] the java vm * @param classLoader the class loader * @param classLoaderObject unwrapped class loader object ref diff --git a/runtime/vm/JVMImage.cpp b/runtime/vm/JVMImage.cpp index 6474e2ff41d..f73b6d5465a 100644 --- a/runtime/vm/JVMImage.cpp +++ b/runtime/vm/JVMImage.cpp @@ -705,6 +705,49 @@ initializeImageClassLoaderObject(J9JavaVM *javaVM, J9ClassLoader *classLoader, j omrthread_monitor_exit(javaVM->classLoaderBlocksMutex); } +extern "C" J9Class * +initializeImageClassObject(J9VMThread *vmThread, J9ClassLoader *classLoader, J9Class *clazz) +{ + J9JavaVM *javaVM = vmThread->javaVM; + + /* Allocate class object */ + J9Class *jlClass = J9VMCONSTANTPOOL_CLASSREF_AT(javaVM, J9VMCONSTANTPOOL_JAVALANGCLASS)->value; + + if (NULL == jlClass) { + return NULL; + } + J9Class *lockClass = J9VMJAVALANGJ9VMINTERNALSCLASSINITIALIZATIONLOCK_OR_NULL(javaVM); + + j9object_t classObject = javaVM->memoryManagerFunctions->J9AllocateObject(vmThread, jlClass, J9_GC_ALLOCATE_OBJECT_TENURED | J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE | J9_GC_ALLOCATE_OBJECT_HASHED); + if (NULL == classObject) { + setHeapOutOfMemoryError(vmThread); + return NULL; + } + + /* Allocate lock object if lock class already allocated */ + if (NULL != lockClass) { + j9object_t lockObject; + UDATA allocateFlags = J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE; + + PUSH_OBJECT_IN_SPECIAL_FRAME(vmThread, (j9object_t)classObject); + lockObject = javaVM->memoryManagerFunctions->J9AllocateObject(vmThread, lockClass, allocateFlags); + classObject = POP_OBJECT_IN_SPECIAL_FRAME(vmThread); + + if (NULL == lockObject) { + setHeapOutOfMemoryError(vmThread); + return NULL; + } + J9VMJAVALANGJ9VMINTERNALSCLASSINITIALIZATIONLOCK_SET_THECLASS(vmThread, lockObject, classObject); + J9VMJAVALANGCLASS_SET_INITIALIZATIONLOCK(vmThread, classObject, lockObject); + } + + J9VMJAVALANGCLASS_SET_CLASSLOADER(vmThread, classObject, classLoader->classLoaderObject); + J9VMJAVALANGCLASS_SET_VMREF(vmThread, classObject, clazz); + J9STATIC_OBJECT_STORE(vmThread, clazz, (j9object_t*)&clazz->classObject, (j9object_t)classObject); + + return clazz; +} + extern "C" void shutdownJVMImage(J9JavaVM *javaVM) { diff --git a/runtime/vm/JVMImage.hpp b/runtime/vm/JVMImage.hpp index de7befe97e9..aa6df13b057 100644 --- a/runtime/vm/JVMImage.hpp +++ b/runtime/vm/JVMImage.hpp @@ -31,6 +31,7 @@ #include "j9comp.h" #include "j9protos.h" #include "ut_j9vm.h" +#include "objhelp.h" class JVMImage { diff --git a/runtime/vm/classsupport.c b/runtime/vm/classsupport.c index 7896f8d2850..5b954a2321a 100644 --- a/runtime/vm/classsupport.c +++ b/runtime/vm/classsupport.c @@ -953,6 +953,12 @@ loadNonArrayClass(J9VMThread* vmThread, J9Module *j9module, U_8* className, UDAT foundClass = hashClassTableAt(classLoader, className, classNameLength); if (NULL != foundClass) { + if (IS_WARM_RUN(vmThread->javaVM) + && J9_ARE_ALL_BITS_SET(vmThread->javaVM->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_CLASS_OBJECT_ASSIGNED) + && foundClass->classObject == NULL) { + foundClass = initializeImageClassObject(vmThread, classLoader, foundClass); + } + if (!fastMode) { omrthread_monitor_exit(vmThread->javaVM->classTableMutex); } diff --git a/runtime/vm/intfunc.c b/runtime/vm/intfunc.c index d27feba9fe8..683368f2ea2 100644 --- a/runtime/vm/intfunc.c +++ b/runtime/vm/intfunc.c @@ -378,4 +378,5 @@ J9InternalVMFunctions J9InternalFunctions = { deregisterCPEntry, findClassLoader, initializeImageClassLoaderObject, + initializeImageClassObject, };