Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MemberName fields after Fast HCR and FSD #12799

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions runtime/jcl/common/java_lang_invoke_MethodHandleNatives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ extern "C" {
* These constants are validated by the MethodHandleNatives$Constants.verifyConstants()
* method when Java assertions are enabled
*/
#define MN_IS_METHOD 0x00010000
#define MN_IS_CONSTRUCTOR 0x00020000
#define MN_IS_FIELD 0x00040000
#define MN_IS_TYPE 0x00080000
#define MN_CALLER_SENSITIVE 0x00100000

#define MN_REFERENCE_KIND_SHIFT 24
#define MN_REFERENCE_KIND_MASK 0xF /* (flag >> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK */
Expand Down
10 changes: 10 additions & 0 deletions runtime/jvmti/jvmtiClass.c
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,11 @@ redefineClassesCommon(jvmtiEnv* env,
/* Fix JNI */
fixJNIRefs(currentThread, classPairs, TRUE, extensionsUsed);

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
/* Fix MemberNames (vmtarget) */
fixMemberNames(currentThread, classPairs);
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

/* Fix resolved constant pool references to point to new methods. */
fixConstantPoolsForFastHCR(currentThread, classPairs, methodPairs);

Expand Down Expand Up @@ -1254,6 +1259,11 @@ redefineClassesCommon(jvmtiEnv* env,
fixVTables_forNormalRedefine(currentThread, classPairs, methodPairs, FALSE, &methodEquivalences);
}

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
/* Fix MemberNames (vmtarget) */
fixMemberNames(currentThread, classPairs);
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

/* Restore breakpoints in the implicitly replaced classes */
restoreBreakpointsInClasses(currentThread, classPairs);

Expand Down
10 changes: 10 additions & 0 deletions runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,16 @@ typedef struct J9ROMMethodHandleRef {
#define MH_REF_INVOKEVIRTUAL 5
#define MH_REF_PUTFIELD 3

/* Constants mapped from java.lang.invoke.MethodHandleNatives$Constants
* These constants are validated by the MethodHandleNatives$Constants.verifyConstants()
* method when Java assertions are enabled
*/
#define MN_IS_METHOD 0x00010000
#define MN_IS_CONSTRUCTOR 0x00020000
#define MN_IS_FIELD 0x00040000
#define MN_IS_TYPE 0x00080000
#define MN_CALLER_SENSITIVE 0x00100000

typedef struct J9ROMMethodRef {
U_32 classRefCPIndex;
J9SRP nameAndSignature;
Expand Down
5 changes: 5 additions & 0 deletions runtime/oti/util_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2174,6 +2174,11 @@ fixArrayClasses(J9VMThread * currentThread, J9HashTable* classHashTable);
void
fixJNIRefs (J9VMThread * currentThread, J9HashTable* classHashTable, BOOLEAN fastHCR, UDATA extensionsUsed);

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
void
fixMemberNames(J9VMThread * currentThread, J9HashTable * classHashTable);
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

void
fixConstantPoolsForFastHCR(J9VMThread *currentThread, J9HashTable *classPairs, J9HashTable *methodPair);

Expand Down
72 changes: 72 additions & 0 deletions runtime/util/hshelp.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ 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);
static jvmtiError fixJNIMethodID(J9VMThread *currentThread, J9Method *oldMethod, J9Method *newMethod, BOOLEAN equivalent, UDATA extensionsUsed);
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
static jvmtiIterationControl fixMemberNamesObjectIteratorCallback(J9JavaVM *vm, J9MM_IterateObjectDescriptor *objectDesc, void *userData);
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */

static jvmtiIterationControl fixHeapRefsHeapIteratorCallback(J9JavaVM *vm, J9MM_IterateHeapDescriptor *heapDesc, void *userData);
static jvmtiIterationControl fixHeapRefsSpaceIteratorCallback(J9JavaVM *vm, J9MM_IterateSpaceDescriptor *spaceDesc, void *userData);
Expand Down Expand Up @@ -1701,6 +1704,75 @@ fixJNIRefs(J9VMThread * currentThread, J9HashTable * classPairs, BOOLEAN fastHCR
}


typedef struct J9ThreadHashPair {
J9VMThread *currentThread;
void *userData;
} J9ThreadHashPair;
EricYangIBM marked this conversation as resolved.
Show resolved Hide resolved

#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
void
fixMemberNames(J9VMThread * currentThread, J9HashTable * classHashTable)
{
PORT_ACCESS_FROM_JAVAVM(currentThread->javaVM);

J9ThreadHashPair data;
data.currentThread = currentThread;
data.userData = classHashTable;

/* iterate over all objects fixing up vmtarget refs if object is a MemberName */
currentThread->javaVM->memoryManagerFunctions->j9mm_iterate_all_objects(currentThread->javaVM, PORTLIB, 0, fixMemberNamesObjectIteratorCallback, &data);
}

static jvmtiIterationControl
fixMemberNamesObjectIteratorCallback(J9JavaVM *vm, J9MM_IterateObjectDescriptor *objectDesc, void *userData)
{
J9ThreadHashPair *data = userData;
J9VMThread *currentThread = data->currentThread;
J9HashTable *classHashTable = data->userData;
j9object_t object = objectDesc->object;
J9Class *clazz = J9OBJECT_CLAZZ_VM(vm, object);

if (NULL != classHashTable) {
gacholio marked this conversation as resolved.
Show resolved Hide resolved
if (clazz == J9VMJAVALANGINVOKEMEMBERNAME(vm) && 0 != J9OBJECT_U64_LOAD(currentThread, object, vm->vmindexOffset)) {
gacholio marked this conversation as resolved.
Show resolved Hide resolved
U_64 vmindex = J9OBJECT_U64_LOAD(currentThread, object, vm->vmindexOffset);

J9JVMTIClassPair exemplar;
J9JVMTIClassPair *result = NULL;

j9object_t membernameClazz = J9VMJAVALANGINVOKEMEMBERNAME_CLAZZ(currentThread, object);
exemplar.replacementClass.ramClass = J9VM_J9CLASS_FROM_HEAPCLASS(currentThread, membernameClazz);
result = hashTableFind(classHashTable, &exemplar);
if (NULL != result) {
jint flags = J9VMJAVALANGINVOKEMEMBERNAME_FLAGS(currentThread, object);
if (J9_ARE_ANY_BITS_SET(flags, MN_IS_FIELD)) {
/* Update vmtarget to vmindex->offset */
J9JNIFieldID *fieldID = (J9JNIFieldID *)vmindex;
gacholio marked this conversation as resolved.
Show resolved Hide resolved
J9ROMFieldShape *romField = fieldID->field;
UDATA offset = fieldID->offset;

if (J9_ARE_ANY_BITS_SET(romField->modifiers, J9AccStatic)) {
offset |= J9_SUN_STATIC_FIELD_OFFSET_TAG;
if (J9_ARE_ANY_BITS_SET(romField->modifiers, J9AccFinal)) {
offset |= J9_SUN_FINAL_FIELD_OFFSET_TAG;
}
}
J9OBJECT_U64_STORE(currentThread, object, vm->vmtargetOffset, (U_64)offset);

gacholio marked this conversation as resolved.
Show resolved Hide resolved
} else if (J9_ARE_ANY_BITS_SET(flags, MN_IS_METHOD | MN_IS_CONSTRUCTOR)) {
/* Update vmtarget to vmindex->method */
J9JNIMethodID *methodID = (J9JNIMethodID *)vmindex;
gacholio marked this conversation as resolved.
Show resolved Hide resolved
J9OBJECT_U64_STORE(currentThread, object, vm->vmtargetOffset, (U_64)methodID->method);
gacholio marked this conversation as resolved.
Show resolved Hide resolved

gacholio marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}

return JVMTI_ITERATION_CONTINUE;
}
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */


/**
* \brief Reresolve the passed in constant pool
* \ingroup jvmtiClass
Expand Down