diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 2bc6e2aba47..fb3b470c219 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -4950,6 +4950,9 @@ typedef struct J9InternalVMFunctions { void ( *printThreadInfo)(struct J9JavaVM *vm, struct J9VMThread *self, char *toFile, BOOLEAN allThreads) ; void (JNICALL *initializeAttachedThread)(struct J9VMThread *vmContext, const char *name, j9object_t *group, UDATA daemon, struct J9VMThread *initializee) ; void ( *initializeMethodRunAddressNoHook)(struct J9JavaVM* vm, J9Method *method) ; +#if defined(J9VM_OPT_SNAPSHOTS) + void ( *initializeMethodRunAddressForSnapshot)(struct J9JavaVM *vm, struct J9Method *method) ; +#endif /* defined(J9VM_OPT_SNAPSHOTS) */ void (JNICALL *sidecarInvokeReflectMethod)(struct J9VMThread *vmContext, jobject methodRef, jobject recevierRef, jobjectArray argsRef) ; void (JNICALL *sidecarInvokeReflectConstructor)(struct J9VMThread *vmContext, jobject constructorRef, jobject recevierRef, jobjectArray argsRef) ; struct J9MemorySegmentList* ( *allocateMemorySegmentListWithSize)(struct J9JavaVM * javaVM, U_32 numberOfMemorySegments, UDATA sizeOfElements, U_32 memoryCategory) ; diff --git a/runtime/oti/vm_api.h b/runtime/oti/vm_api.h index bea8ce5ed55..2856d361866 100644 --- a/runtime/oti/vm_api.h +++ b/runtime/oti/vm_api.h @@ -1261,7 +1261,6 @@ growJavaStack(J9VMThread * vmThread, UDATA newStackSize); * @brief * @param *vmThread * @param *method -* @param *jxeDescription * @return void */ void @@ -1274,7 +1273,26 @@ initializeMethodRunAddress(J9VMThread *vmThread, J9Method *method); * @return void */ void -initializeMethodRunAddressNoHook(J9JavaVM* vm, J9Method *method); +initializeMethodRunAddressNoHook(J9JavaVM *vm, J9Method *method); + +#if defined(J9VM_OPT_SNAPSHOTS) +/** + * @brief This function is similar to initializeMethodRunAddress but without the hook call. + * + * Prior to writing a VM snapshot, J9Method::methodRunAddress and J9Method::extra need to be + * reinitialized to a state that is restore friendly (i.e. set to appropriate interpreter entries). + * initializeMethodRunAddress should not be used; it may run the J9HOOK_VM_INITIALIZE_SEND_TARGET + * hook that initializes invocation counts and sets J9Method::methodRunAddress's to JIT specific + * send targets. initializeMethodRunAddressNoHook should not be used because it does not perform + * MethodHandle and VarHandle send target initialization, nor does it reset J9Method::extra + * appropriately. + * + * @param vm pointer to the J9JavaVM + * @param method pointer to the J9Method + */ +void +initializeMethodRunAddressForSnapshot(J9JavaVM *vm, J9Method *method); +#endif /* defined(J9VM_OPT_SNAPSHOTS) */ /** * @brief diff --git a/runtime/vm/VMSnapshotImpl.cpp b/runtime/vm/VMSnapshotImpl.cpp index 3b5e6455014..cf639be703a 100644 --- a/runtime/vm/VMSnapshotImpl.cpp +++ b/runtime/vm/VMSnapshotImpl.cpp @@ -718,12 +718,12 @@ VMSnapshotImpl::fixupMethodRunAddresses(J9Class *ramClass) { J9ROMClass *romClass = ramClass->romClass; - /* for all ramMethods call initializeMethodRunAdress for special methods */ + /* Call initializeMethodRunAddressForSnapshot on all for J9Methods in a J9Class. */ if (0 != romClass->romMethodCount) { UDATA count = romClass->romMethodCount; J9Method *ramMethod = ramClass->ramMethods; for (UDATA i = 0; i < count; i++) { - initializeMethodRunAddressNoHook(_vm, ramMethod); + initializeMethodRunAddressForSnapshot(_vm, ramMethod); ramMethod++; } } diff --git a/runtime/vm/initsendtarget.cpp b/runtime/vm/initsendtarget.cpp index 31b34a4d775..13d076eccf3 100644 --- a/runtime/vm/initsendtarget.cpp +++ b/runtime/vm/initsendtarget.cpp @@ -292,6 +292,27 @@ initializeMethodRunAddressNoHook(J9JavaVM* vm, J9Method *method) method->methodRunAddress = J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_NON_SYNC); } +#if defined(J9VM_OPT_SNAPSHOTS) +void +initializeMethodRunAddressForSnapshot(J9JavaVM *vm, J9Method *method) +{ + method->extra = (void *)J9_STARTPC_NOT_TRANSLATED; + +#if defined(J9VM_OPT_OPENJDK_METHODHANDLE) + if (initializeMethodRunAddressMethodHandle(method)) { + return; + } +#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */ + +#if defined(J9VM_OPT_METHOD_HANDLE) + if (initializeMethodRunAddressVarHandle(method)) { + return; + } +#endif /* defined(J9VM_OPT_METHOD_HANDLE) */ + initializeMethodRunAddressNoHook(vm, method); +} +#endif /* defined(J9VM_OPT_SNAPSHOTS) */ + #if !defined(J9VM_OPT_SNAPSHOTS) J9Method cInitialStaticMethod = { 0, 0, J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_INITIAL_STATIC), 0 }; J9Method cInitialSpecialMethod = { 0, 0, J9_BCLOOP_ENCODE_SEND_TARGET(J9_BCLOOP_SEND_TARGET_INITIAL_SPECIAL), 0 }; diff --git a/runtime/vm/intfunc.c b/runtime/vm/intfunc.c index a83992522a8..75a9bc72126 100644 --- a/runtime/vm/intfunc.c +++ b/runtime/vm/intfunc.c @@ -155,6 +155,9 @@ J9InternalVMFunctions J9InternalFunctions = { printThreadInfo, initializeAttachedThread, initializeMethodRunAddressNoHook, +#if defined(J9VM_OPT_SNAPSHOTS) + initializeMethodRunAddressForSnapshot, +#endif /* defined(J9VM_OPT_SNAPSHOTS) */ sidecarInvokeReflectMethod, sidecarInvokeReflectConstructor, allocateMemorySegmentListWithSize,