Skip to content

Commit

Permalink
Merge pull request #3315 from tajila/LW1open5
Browse files Browse the repository at this point in the history
Pre-load instance fields that are Qtypes
  • Loading branch information
gacholio authored Oct 18, 2018
2 parents b037816 + 2d412e8 commit 0d6badb
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
8 changes: 8 additions & 0 deletions runtime/nls/j9vm/j9vm.nls
Original file line number Diff line number Diff line change
Expand Up @@ -1845,3 +1845,11 @@ J9NLS_VM_NESTMATES_CLASS_FAILED_TO_LOAD.system_action=The JVM will throw an Inco
J9NLS_VM_NESTMATES_CLASS_FAILED_TO_LOAD.user_response=Load class and nest host class with same classloader.
# END NON-TRANSLATABLE

J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE=bad class %2$.*1$s: Qtype instance field is not a value type
# START NON-TRANSLATABLE
J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE.sample_input_1=3
J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE.sample_input_2=Foo
J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE.explanation=The class has a field with a q signature which is not a value type.
J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE.system_action=The JVM will throw a IncompatibleClassChangeError.
J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE.user_response=Contact the provider of the classfile for a corrected version.
# END NON-TRANSLATABLE
65 changes: 64 additions & 1 deletion runtime/vm/createramclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#undef UT_MODULE_UNLOADED
#include "ut_j9vm.h"
#include "j9bcvnls.h"
#include "j9vmnls.h"
#include "j2sever.h"
#include "vm_internal.h"

Expand Down Expand Up @@ -144,6 +145,9 @@ static void setCurrentExceptionForBadClass(J9VMThread *vmThread, J9UTF8 *badClas
static BOOLEAN verifyClassLoadingStack(J9VMThread *vmThread, J9ClassLoader *classLoader, J9ROMClass *romClass);
static void popFromClassLoadingStack(J9VMThread *vmThread);
static VMINLINE BOOLEAN loadSuperClassAndInterfaces(J9VMThread *vmThread, J9ClassLoader *classLoader, J9ROMClass *romClass, J9Class *elementClass, UDATA packageID, BOOLEAN hotswapping, UDATA classPreloadFlags, J9Class **superclassOut, J9Module *module);
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
static BOOLEAN loadFlattenableFieldValueClasses(J9VMThread *vmThread, J9ClassLoader *classLoader, J9ROMClass *romClass, UDATA classPreloadFlags, UDATA packageID, J9Module *module);
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
static J9Class* internalCreateRAMClassDropAndReturn(J9VMThread *vmThread, J9ROMClass *romClass, J9CreateRAMClassState *state);
static J9Class* internalCreateRAMClassDoneNoMutex(J9VMThread *vmThread, J9ROMClass *romClass, UDATA options, J9CreateRAMClassState *state);
static J9Class* internalCreateRAMClassDone(J9VMThread *vmThread, J9ClassLoader *classLoader, J9ROMClass *romClass, UDATA options, J9Class *elementClass,
Expand Down Expand Up @@ -1627,6 +1631,61 @@ loadSuperClassAndInterfaces(J9VMThread *vmThread, J9ClassLoader *classLoader, J9
return TRUE;
}

#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
/**
* Attempts to pre-load classes of fields with Q signatures and no static
* access modifier set.
*
* Caller should not hold the classTableMutex.
*
* Return TRUE on success. On failure, returns FALSE and sets the
* appropriate Java error on the VM.
*/
static BOOLEAN
loadFlattenableFieldValueClasses(J9VMThread *currentThread, J9ClassLoader *classLoader, J9ROMClass *romClass, UDATA classPreloadFlags, UDATA packageID, J9Module *module)
{
J9ROMFieldWalkState fieldWalkState = {0};
J9ROMFieldShape *field = romFieldsStartDo(romClass, &fieldWalkState);
BOOLEAN result = TRUE;
/* iterate over fields and load classes of fields marked as QTypes */
while (NULL != field) {
const U_32 modifiers = field->modifiers;
J9UTF8 *signature = J9ROMFIELDSHAPE_SIGNATURE(field);
U_8 *signatureChars = J9UTF8_DATA(signature);
if (('Q' == signatureChars[0]) && J9_ARE_NO_BITS_SET(modifiers, J9AccStatic)) {
J9Class *valueClass = internalFindClassUTF8(currentThread, signatureChars + 1, J9UTF8_LENGTH(signature) - 2, classLoader, classPreloadFlags);
if (NULL == valueClass) {
result = FALSE;
goto done;
} else {
J9ROMClass *valueROMClass = valueClass->romClass;

if (J9_ARE_NO_BITS_SET(valueROMClass->modifiers, J9AccValueType)) {
J9UTF8 *badClass = NNSRP_GET(valueROMClass->className, J9UTF8*);
setCurrentExceptionNLSWithArgs(currentThread, J9NLS_VM_ERROR_QTYPE_NOT_VALUE_TYPE, J9VMCONSTANTPOOL_JAVALANGINCOMPATIBLECLASSCHANGEERROR, J9UTF8_LENGTH(badClass), J9UTF8_DATA(badClass));
result = FALSE;
goto done;
}

bool classIsPublic = J9_ARE_ALL_BITS_SET(valueROMClass->modifiers, J9AccPublic);

if ((!classIsPublic && (packageID != valueClass->packageID))
|| (classIsPublic && (J9_VISIBILITY_ALLOWED != checkModuleAccess(currentThread, currentThread->javaVM, romClass, module, valueROMClass, valueClass->module, valueClass->packageID, 0)))
) {
Trc_VM_CreateRAMClassFromROMClass_nestedValueClassNotVisible(currentThread, valueClass, valueClass->classLoader, classLoader);
setCurrentExceptionForBadClass(currentThread, J9ROMCLASS_CLASSNAME(valueROMClass), J9VMCONSTANTPOOL_JAVALANGILLEGALACCESSERROR);
result = FALSE;
goto done;
}
}
}
field = romFieldsNextDo(&fieldWalkState);
}
done:
return result;
}
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */

static J9Class*
internalCreateRAMClassDropAndReturn(J9VMThread *vmThread, J9ROMClass *romClass, J9CreateRAMClassState *state)
{
Expand Down Expand Up @@ -2811,7 +2870,11 @@ internalCreateRAMClassFromROMClass(J9VMThread *vmThread, J9ClassLoader *classLoa
}
}

if (!loadSuperClassAndInterfaces(vmThread, hostClassLoader, romClass, elementClass, packageID, hotswapping, classPreloadFlags, &superclass, module)) {
if (!loadSuperClassAndInterfaces(vmThread, hostClassLoader, romClass, elementClass, packageID, hotswapping, classPreloadFlags, &superclass, module)
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
|| !loadFlattenableFieldValueClasses(vmThread, hostClassLoader, romClass, classPreloadFlags, packageID, module)
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */
) {
omrthread_monitor_enter(javaVM->classTableMutex);
return internalCreateRAMClassDone(vmThread, classLoader, romClass, options, elementClass, className, &state);
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/vm/j9vm.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -775,3 +775,5 @@ TraceException=Trc_VM_registerOSHandler_invalidPortlibSignalFlag NoEnv Overhead=

TraceEntry=Trc_VM_sendResolveConstantDynamic_Entry Overhead=1 Level=2 Template="sendResolveConstantDynamic(ramCP=%p, cpIndex=%zu, nameAndSig=%p, bsmData=%p)"
TraceExit=Trc_VM_sendResolveConstantDynamic_Exit Overhead=1 Level=2 Template="sendResolveConstantDynamic"

TraceException=Trc_VM_CreateRAMClassFromROMClass_nestedValueClassNotVisible Overhead=1 Level=1 Template="Nested field (RAM class=%p, classloader=%p, this classloader=%p) is not visible. Throw IllegalAccessError"

0 comments on commit 0d6badb

Please sign in to comment.