diff --git a/runtime/bcutil/ROMClassWriter.cpp b/runtime/bcutil/ROMClassWriter.cpp index e04c6d0a366..56ecb210e38 100644 --- a/runtime/bcutil/ROMClassWriter.cpp +++ b/runtime/bcutil/ROMClassWriter.cpp @@ -1244,7 +1244,7 @@ ROMClassWriter::writeMethods(Cursor *cursor, Cursor *lineNumberCursor, Cursor *v * - nextROMMethod() in util/mthutil.c * - allSlotsInROMMethodsSectionDo() in util/romclasswalk.c * - dbgNextROMMethod() in dbgext/j9dbgext.c - * - createBreakpointedMethod() in jvmti/jvmtiHelpers.c + * - createBreakpointedMethod() in jvmti/jvmtiHelpers.cpp * All the above are involved in walking or walking over ROMMethods. * */ diff --git a/runtime/codert_vm/decomp.cpp b/runtime/codert_vm/decomp.cpp index fc0d3c61a92..226e5d2dfc8 100644 --- a/runtime/codert_vm/decomp.cpp +++ b/runtime/codert_vm/decomp.cpp @@ -38,6 +38,11 @@ #include "VMHelpers.hpp" #include "OMR/Bytes.hpp" +#if JAVA_SPEC_VERSION >= 19 +#include "HeapIteratorAPI.h" +#include "ContinuationHelpers.hpp" +#endif /* JAVA_SPEC_VERSION >= 19 */ + extern "C" { /* Generic rounding macro - result is a UDATA */ @@ -113,7 +118,8 @@ static J9OSRFrame* findOSRFrameAtInlineDepth(J9OSRBuffer *osrBuffer, UDATA inlin static void jitFramePopNotificationAdded(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA inlineDepth); static void decompPrintMethod(J9VMThread * currentThread, J9Method * method); static UDATA decompileAllFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState); -static J9JITDecompilationInfo * deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompilationInfo * info); +static J9JITDecompilationInfo *deleteDecompilationForExistingFrame(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo *info); +static J9JITDecompilationInfo *addDecompilationHelper(J9VMThread *currentThread, J9StackWalkState *walkState, UDATA reason, J9JITDecompilationInfo **previous); static J9JITDecompilationInfo * addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason); static void removeAllBreakpoints(J9VMThread * currentThread); static void buildBytecodeFrame(J9VMThread *currentThread, J9OSRFrame *osrFrame); @@ -127,7 +133,8 @@ static void markMethodUnbreakpointed(J9VMThread * currentThread, J9JITBreakpoint static void reinstallAllBreakpoints(J9VMThread * currentThread); static UDATA decompileMethodFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkState); static void deleteAllDecompilations(J9VMThread * currentThread, UDATA reason, J9Method * method); -static void freeDecompilationRecord(J9VMThread * decompileThread, J9JITDecompilationInfo * info, UDATA retain); +static void freeDecompilations(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo **previous, UDATA reason, J9Method *method); +static void freeDecompilationRecord(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo *info, UDATA retain); static UDATA osrAllFramesSize(J9VMThread *currentThread, J9JITExceptionTable *metaData, void *jitPC, UDATA resolveFrameFlags); static UDATA performOSR(J9VMThread *currentThread, J9StackWalkState *walkState, J9OSRBuffer *osrBuffer, U_8 *osrScratchBuffer, UDATA scratchBufferSize, UDATA jitStackFrameSize, UDATA *mustDecompile); static UDATA* jitLocalSlotAddress(J9VMThread * currentThread, J9StackWalkState *walkState, UDATA slot, UDATA inlineDepth); @@ -144,6 +151,12 @@ static J9JITDecompilationInfo* fetchAndUnstackDecompilationInfo(J9VMThread *curr static void fixSavedPC(J9VMThread *currentThread, J9JITDecompilationInfo *decompRecord); static void dumpStack(J9VMThread *currentThread, char const *msg); static J9ROMNameAndSignature* getNASFromInvoke(U_8 *bytecodePC, J9ROMClass *romClass); +#if JAVA_SPEC_VERSION >= 19 +static jvmtiIterationControl codeBreakpointAddedCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData); +static jvmtiIterationControl deleteDecompCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData); +static jvmtiIterationControl decompileAllCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData); +static J9JITDecompilationInfo * addDecompilationForContinuation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason, J9VMContinuation *continuation); +#endif /* JAVA_SPEC_VERSION >= 19 */ /** @@ -342,7 +355,7 @@ jitCleanUpDecompilationStack(J9VMThread * currentThread, J9StackWalkState * walk } } current = current->next; - freeDecompilationRecord(currentThread, temp, FALSE); + freeDecompilationRecord(currentThread, currentThread, temp, FALSE); } currentThread->decompilationStack = current; @@ -352,15 +365,38 @@ jitCleanUpDecompilationStack(J9VMThread * currentThread, J9StackWalkState * walk #endif /* J9VM_INTERP_HOT_CODE_REPLACEMENT (autogen) */ +#if JAVA_SPEC_VERSION >= 19 +static jvmtiIterationControl +codeBreakpointAddedCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData) +{ + J9JavaVM *vm = currentThread->javaVM; + j9object_t continuationObj = object->object; + j9object_t vthread = J9VMJDKINTERNALVMCONTINUATION_VTHREAD(currentThread, continuationObj); + ContinuationState continuationState = J9VMJDKINTERNALVMCONTINUATION_STATE(currentThread, continuationObj); + + if ((NULL != vthread) && J9_ARE_NO_BITS_SET(continuationState, J9_GC_CONTINUATION_STATE_LAST_UNMOUNT)) { + J9StackWalkState *walkState = (J9StackWalkState*)userData; + J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj); + j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(currentThread, continuation, continuationObj); + + vm->internalVMFunctions->walkContinuationStackFrames(currentThread, continuation, threadObject, walkState); + } + return JVMTI_ITERATION_CONTINUE; +} +#endif /* JAVA_SPEC_VERSION >= 19 */ + + void jitCodeBreakpointAdded(J9VMThread * currentThread, J9Method * method) { PORT_ACCESS_FROM_VMC(currentThread); - J9JITConfig * jitConfig = currentThread->javaVM->jitConfig; + J9JavaVM *vm = currentThread->javaVM; + J9JITConfig * jitConfig = vm->jitConfig; J9JITBreakpointedMethod * breakpointedMethod; J9JITBreakpointedMethod * breakpointedMethods = jitConfig->breakpointedMethods; J9VMThread * loopThread; - + J9StackWalkState walkState; + /* Called under exclusive access, so no mutex required */ Trc_Decomp_jitCodeBreakpointAdded_Entry(currentThread, method); @@ -393,18 +429,21 @@ jitCodeBreakpointAdded(J9VMThread * currentThread, J9Method * method) Trc_Decomp_jitCodeBreakpointAdded_hasBeenTranslated(currentThread, breakpointedMethod->hasBeenTranslated); + walkState.userData1 = method; + walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP; + walkState.skipCount = 0; + walkState.frameWalkFunction = codeBreakpointAddedFrameIterator; loopThread = currentThread; do { - J9StackWalkState walkState; - - walkState.userData1 = method; - walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP; - walkState.skipCount = 0; - walkState.frameWalkFunction = codeBreakpointAddedFrameIterator; walkState.walkThread = loopThread; currentThread->javaVM->walkStackFrames(currentThread, &walkState); } while ((loopThread = loopThread->linkNext) != currentThread); +#if JAVA_SPEC_VERSION >= 19 + vm->memoryManagerFunctions->j9gc_flush_nonAllocationCaches_for_walk(vm); + vm->memoryManagerFunctions->j9mm_iterate_all_continuation_objects(currentThread, PORTLIB, 0, codeBreakpointAddedCallBack, (void*)&walkState); +#endif /* JAVA_SPEC_VERSION >= 19 */ + Trc_Decomp_jitCodeBreakpointAdded_Exit(currentThread); } @@ -509,7 +548,7 @@ jitDecompileMethod(J9VMThread * currentThread, J9JITDecompilationInfo * decompRe performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames); - freeDecompilationRecord(currentThread, decompRecord, TRUE); + freeDecompilationRecord(currentThread, currentThread, decompRecord, TRUE); } /** @@ -1096,13 +1135,11 @@ fixStackForNewDecompilation(J9VMThread * currentThread, J9StackWalkState * walkS static J9JITDecompilationInfo * -addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason) +addDecompilationHelper(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason, J9JITDecompilationInfo **previous) { PORT_ACCESS_FROM_VMC(currentThread); J9JavaVM* vm = currentThread->javaVM; - J9VMThread * decompileThread = walkState->walkThread; J9JITDecompilationInfo * info; - J9JITDecompilationInfo ** previous; J9JITDecompilationInfo * current; J9JITExceptionTable *metaData = walkState->jitInfo; UDATA allocSize = sizeof(J9JITDecompilationInfo); @@ -1126,7 +1163,6 @@ addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA /* The decompilation is ordered by frame, with lesser frame values appearing at the beginning */ - previous = &(decompileThread->decompilationStack); while ((current = *previous) != NULL) { /* If a decompilation for this frame already exists, tag it with the new reason and return */ @@ -1209,6 +1245,14 @@ addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA return info; } +static J9JITDecompilationInfo * +addDecompilation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason) +{ + J9VMThread *decompileThread = walkState->walkThread; + + return addDecompilationHelper(currentThread, walkState, reason, &decompileThread->decompilationStack); +} + void c_jitDecompileAtExceptionCatch(J9VMThread * currentThread) { @@ -1283,7 +1327,7 @@ c_jitDecompileAtExceptionCatch(J9VMThread * currentThread) performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames); - freeDecompilationRecord(currentThread, decompRecord, TRUE); + freeDecompilationRecord(currentThread, currentThread, decompRecord, TRUE); /* Push the exception */ UDATA *sp = currentThread->sp - 1; @@ -1328,7 +1372,7 @@ jitDecompileMethodForFramePop(J9VMThread * currentThread, UDATA skipCount) /* Now decompile the frame */ performDecompile(currentThread, &decompileState, decompRecord, osrFrame, numberOfFrames); - freeDecompilationRecord(currentThread, decompRecord, TRUE); + freeDecompilationRecord(currentThread, currentThread, decompRecord, TRUE); dumpStack(currentThread, "after jitDecompileMethodForFramePop"); @@ -1339,9 +1383,8 @@ jitDecompileMethodForFramePop(J9VMThread * currentThread, UDATA skipCount) static J9JITDecompilationInfo * -deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompilationInfo * info) +deleteDecompilationForExistingFrame(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo *info) { - PORT_ACCESS_FROM_VMC(decompileThread); J9JITDecompilationInfo * next = info->next; Trc_Decomp_deleteDecompilationForExistingFrame_Entry(); @@ -1350,7 +1393,7 @@ deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompila Trc_Decomp_deleteDecompilationForExistingFrame_freeDecomp(info, info->bp); - freeDecompilationRecord(decompileThread, info, FALSE); + freeDecompilationRecord(currentThread, decompileThread, info, FALSE); Trc_Decomp_deleteDecompilationForExistingFrame_Exit(); @@ -1359,19 +1402,24 @@ deleteDecompilationForExistingFrame(J9VMThread * decompileThread, J9JITDecompila static void -freeDecompilationRecord(J9VMThread * decompileThread, J9JITDecompilationInfo * info, UDATA retain) +freeDecompilationRecord(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo *info, UDATA retain) { - PORT_ACCESS_FROM_VMC(decompileThread); + PORT_ACCESS_FROM_VMC(currentThread); - j9mem_free_memory(decompileThread->lastDecompilation); - decompileThread->lastDecompilation = NULL; - if (info->reason & JITDECOMP_OSR_GLOBAL_BUFFER_USED) { - omrthread_monitor_exit(decompileThread->javaVM->osrGlobalBufferLock); + if (NULL == decompileThread) { + Assert_CodertVM_false(retain); + j9mem_free_memory(info); } else { - if (retain) { - decompileThread->lastDecompilation = info; + j9mem_free_memory(decompileThread->lastDecompilation); + decompileThread->lastDecompilation = NULL; + if (J9_ARE_ANY_BITS_SET(info->reason, JITDECOMP_OSR_GLOBAL_BUFFER_USED)) { + omrthread_monitor_exit(decompileThread->javaVM->osrGlobalBufferLock); } else { - j9mem_free_memory(info); + if (0 != retain) { + decompileThread->lastDecompilation = info; + } else { + j9mem_free_memory(info); + } } } } @@ -1473,24 +1521,102 @@ jitDataBreakpointRemoved(J9VMThread * currentThread) } +static void +freeDecompilations(J9VMThread *currentThread, J9VMThread *decompileThread, J9JITDecompilationInfo **previous, UDATA reason, J9Method *method) +{ + J9JITDecompilationInfo * current = NULL; + + while (NULL != (current = *previous)) { + if (J9_ARE_ANY_BITS_SET(current->reason, reason) && ((NULL == method) || (current->method == method))) { + current->reason &= ~reason; + if (0 != current->reason) { + Trc_Decomp_deleteAllDecompilations_notFreeingRecord(currentThread, current, current->reason); + previous = &(current->next); + } else { + *previous = deleteDecompilationForExistingFrame(currentThread, decompileThread, current); + } + } else { + previous = &(current->next); + } + } +} + + +#if JAVA_SPEC_VERSION >= 19 + +typedef struct { + UDATA reason; + J9Method *method; +} J9DeleteDecompData; + +static jvmtiIterationControl +deleteDecompCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData) +{ + j9object_t continuationObj = object->object; + j9object_t vthread = J9VMJDKINTERNALVMCONTINUATION_VTHREAD(currentThread, continuationObj); + ContinuationState continuationState = J9VMJDKINTERNALVMCONTINUATION_STATE(currentThread, continuationObj); + + if ((NULL != vthread) && J9_ARE_NO_BITS_SET(continuationState, J9_GC_CONTINUATION_STATE_LAST_UNMOUNT)) { + J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj); + J9DeleteDecompData *data = (J9DeleteDecompData*)userData; + + freeDecompilations(currentThread, NULL, &(continuation->decompilationStack), data->reason, data->method); + } + return JVMTI_ITERATION_CONTINUE; +} + +static jvmtiIterationControl +decompileAllCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData) +{ + J9JavaVM *vm = currentThread->javaVM; + j9object_t continuationObj = object->object; + j9object_t vthread = J9VMJDKINTERNALVMCONTINUATION_VTHREAD(currentThread, continuationObj); + ContinuationState continuationState = J9VMJDKINTERNALVMCONTINUATION_STATE(currentThread, continuationObj); + + if ((NULL != vthread) && J9_ARE_NO_BITS_SET(continuationState, J9_GC_CONTINUATION_STATE_LAST_UNMOUNT)) { + J9StackWalkState *walkState = (J9StackWalkState*)userData; + J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj); + j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(currentThread, continuation, continuationObj); + + walkState->userData2 = (void*)continuation; + vm->internalVMFunctions->walkContinuationStackFrames(currentThread, continuation, threadObject, walkState); + } + return JVMTI_ITERATION_CONTINUE; +} + +static J9JITDecompilationInfo * +addDecompilationForContinuation(J9VMThread * currentThread, J9StackWalkState * walkState, UDATA reason, J9VMContinuation *continuation) +{ + return addDecompilationHelper(currentThread, walkState, reason, &continuation->decompilationStack); +} + +#endif /* JAVA_SPEC_VERSION >= 19 */ + + static void decompileAllMethodsInAllStacks(J9VMThread * currentThread, UDATA reason) { + J9JavaVM *vm = currentThread->javaVM; J9VMThread * loopThread; + J9StackWalkState walkState; /* Mark every JIT method in every stack for decompilation */ + walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP; + walkState.skipCount = 0; + walkState.frameWalkFunction = decompileAllFrameIterator; + walkState.userData1 = (void *) reason; + walkState.userData2 = NULL; loopThread = currentThread; do { - J9StackWalkState walkState; - - walkState.flags = J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES | J9_STACKWALK_VISIBLE_ONLY | J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_MAINTAIN_REGISTER_MAP; - walkState.skipCount = 0; - walkState.frameWalkFunction = decompileAllFrameIterator; walkState.walkThread = loopThread; - walkState.userData1 = (void *) reason; - currentThread->javaVM->walkStackFrames(currentThread, &walkState); + vm->walkStackFrames(currentThread, &walkState); } while ((loopThread = loopThread->linkNext) != currentThread); + +#if JAVA_SPEC_VERSION >= 19 + vm->memoryManagerFunctions->j9gc_flush_nonAllocationCaches_for_walk(vm); + vm->memoryManagerFunctions->j9mm_iterate_all_continuation_objects(currentThread, vm->portLibrary, 0, decompileAllCallBack, (void*)&walkState); +#endif /* JAVA_SPEC_VERSION >= 19 */ } @@ -1499,8 +1625,16 @@ decompileAllFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkSta { /* Decompile all JIT frames */ - if (walkState->jitInfo) { - addDecompilation(currentThread, walkState, (UDATA) walkState->userData1); + if (NULL != walkState->jitInfo) { +#if JAVA_SPEC_VERSION >= 19 + J9VMContinuation *continuation = (J9VMContinuation*)walkState->userData2; + if (NULL != continuation) { + addDecompilationForContinuation(currentThread, walkState, (UDATA)walkState->userData1, continuation); + } else +#endif /* JAVA_SPEC_VERSION >= 19 */ + { + addDecompilation(currentThread, walkState, (UDATA) walkState->userData1); + } } return J9_STACKWALK_KEEP_ITERATING; @@ -1508,33 +1642,23 @@ decompileAllFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkSta static void -deleteAllDecompilations(J9VMThread * currentThread, UDATA reason, J9Method * method) +deleteAllDecompilations(J9VMThread *currentThread, UDATA reason, J9Method * method) { - J9VMThread * loopThread; + J9VMThread * loopThread = currentThread; Trc_Decomp_deleteAllDecompilations_Entry(currentThread); - loopThread = currentThread; do { - J9JITDecompilationInfo ** previous; - J9JITDecompilationInfo * current; - - previous = &(loopThread->decompilationStack); - while ((current = *previous) != NULL) { - if ((current->reason & reason) && (!method || (current->method == method))) { - current->reason &= ~reason; - if (current->reason) { - Trc_Decomp_deleteAllDecompilations_notFreeingRecord(currentThread, current, current->reason); - previous = &(current->next); - } else { - *previous = deleteDecompilationForExistingFrame(loopThread, current); - } - } else { - previous = &(current->next); - } - } + freeDecompilations(currentThread, loopThread, &loopThread->decompilationStack, reason, method); } while ((loopThread = loopThread->linkNext) != currentThread); +#if JAVA_SPEC_VERSION >= 19 + J9JavaVM *vm = currentThread->javaVM; + J9DeleteDecompData data = { reason, method }; + vm->memoryManagerFunctions->j9gc_flush_nonAllocationCaches_for_walk(vm); + vm->memoryManagerFunctions->j9mm_iterate_all_continuation_objects(currentThread, vm->portLibrary, 0, deleteDecompCallBack, (void*)&data); +#endif /* JAVA_SPEC_VERSION >= 19 */ + Trc_Decomp_deleteAllDecompilations_Exit(currentThread); } @@ -2335,7 +2459,7 @@ induceOSROnCurrentThread(J9VMThread * currentThread) if (OSR_OK != osrReturnCode) { outOfMemory: decompilationRecord->reason = reason; - freeDecompilationRecord(currentThread, decompilationRecord, FALSE); + freeDecompilationRecord(currentThread, currentThread, decompilationRecord, FALSE); } else { fixStackForNewDecompilation(currentThread, &walkState, decompilationRecord, reason, ¤tThread->decompilationStack); } diff --git a/runtime/jvmti/CMakeLists.txt b/runtime/jvmti/CMakeLists.txt index a54044e4973..b7b11aa420f 100644 --- a/runtime/jvmti/CMakeLists.txt +++ b/runtime/jvmti/CMakeLists.txt @@ -37,7 +37,7 @@ j9vm_add_library(j9jvmti SHARED jvmtiGeneral.c jvmtiHeap.c jvmtiHeap10.c - jvmtiHelpers.c + jvmtiHelpers.cpp jvmtiHook.c jvmtiJNIFunctionInterception.c jvmtiLocalVariable.c diff --git a/runtime/jvmti/jvmtiHelpers.c b/runtime/jvmti/jvmtiHelpers.cpp similarity index 93% rename from runtime/jvmti/jvmtiHelpers.c rename to runtime/jvmti/jvmtiHelpers.cpp index 8555dceecb5..3f0b28d1373 100644 --- a/runtime/jvmti/jvmtiHelpers.c +++ b/runtime/jvmti/jvmtiHelpers.cpp @@ -24,6 +24,13 @@ #include "jvmti_internal.h" #include "j9cp.h" +#if JAVA_SPEC_VERSION >= 19 +#include "HeapIteratorAPI.h" +#include "ContinuationHelpers.hpp" +#endif /* JAVA_SPEC_VERSION >= 19 */ + +extern "C" { + extern jvmtiNativeInterface jvmtiFunctionTable; /* Jazz 99339: Map JVMTI event number to the reason code for zAAP switching on zOS. @@ -86,7 +93,7 @@ static jvmtiError createSingleBreakpoint (J9VMThread * currentThread, J9Method * static UDATA hashObjectTag (void *entry, void *userData); static void deleteBreakpointedMethodReference (J9VMThread * currentThread, J9JVMTIBreakpointedMethod * breakpointedMethod); static UDATA fixBytecodesFrameIterator (J9VMThread * currentThread, J9StackWalkState * walkState); -static void fixBytecodesInAllStacks (J9JavaVM * vm, J9Method * method, UDATA delta); +static void fixBytecodesInAllStacks (J9VMThread *currentThread, J9Method * method, UDATA delta); static void clearSingleBreakpoint (J9VMThread * currentThread, J9JVMTIGlobalBreakpoint * globalBreakpoint); static J9JVMTIGlobalBreakpoint * findGlobalBreakpoint (J9JVMTIData * jvmtiData, J9Method * ramMethod, IDATA location); static J9JVMTIBreakpointedMethod * createBreakpointedMethod (J9VMThread * currentThread, J9Method * ramMethod); @@ -95,6 +102,9 @@ static UDATA findDecompileInfoFrameIterator(J9VMThread *currentThread, J9StackWa static UDATA watchedClassHash (void *entry, void *userData); static UDATA watchedClassEqual (void *lhsEntry, void *rhsEntry, void *userData); static jint getThreadStateHelper(J9VMThread *currentThread, j9object_t threadObject, J9VMThread *vmThread); +#if JAVA_SPEC_VERSION >= 19 +static jvmtiIterationControl fixBytecodesCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData); +#endif /* JAVA_SPEC_VERSION >= 19 */ jvmtiError getVMThread(J9VMThread *currentThread, jthread thread, J9VMThread **vmThreadPtr, jvmtiError vThreadError, UDATA flags) @@ -251,10 +261,10 @@ disposeEnvironment(J9JVMTIEnv * j9env, UDATA freeData) pool_state poolState; J9JVMTIAgentBreakpoint * agentBreakpoint = NULL; - agentBreakpoint = pool_startDo(j9env->breakpoints, &poolState); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_startDo(j9env->breakpoints, &poolState); while (agentBreakpoint != NULL) { deleteAgentBreakpoint(currentThread, j9env, agentBreakpoint); - agentBreakpoint = pool_nextDo(&poolState); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_nextDo(&poolState); } } @@ -303,12 +313,12 @@ disposeEnvironment(J9JVMTIEnv * j9env, UDATA freeData) if (NULL != j9env->watchedClasses) { J9HashTableState walkState; - J9JVMTIWatchedClass *watchedClass = hashTableStartDo(j9env->watchedClasses, &walkState); + J9JVMTIWatchedClass *watchedClass = (J9JVMTIWatchedClass*)hashTableStartDo(j9env->watchedClasses, &walkState); while (NULL != watchedClass) { if (J9JVMTI_CLASS_REQUIRES_ALLOCATED_J9JVMTI_WATCHED_FIELD_ACCESS_BITS(watchedClass->clazz)) { j9mem_free_memory(watchedClass->watchBits); } - watchedClass = hashTableNextDo(&walkState); + watchedClass = (J9JVMTIWatchedClass*)hashTableNextDo(&walkState); } hashTableFree(j9env->watchedClasses); j9env->watchedClasses = NULL; @@ -348,7 +358,7 @@ allocateEnvironment(J9InvocationJavaVM * invocationJavaVM, jint version, void ** rc = JNI_ENOMEM; - j9env = pool_newElement(jvmtiData->environments); + j9env = (J9JVMTIEnv*)pool_newElement(jvmtiData->environments); if (j9env != NULL) { J9HookInterface ** vmHook = vm->internalVMFunctions->getVMHookInterface(vm); J9HookInterface ** gcHook = vm->memoryManagerFunctions->j9gc_get_hook_interface(vm); @@ -590,7 +600,7 @@ cStringFromUTFChars(jvmtiEnv * env, U_8 * data, UDATA length, char ** cString) jvmtiError rc = JVMTI_ERROR_NONE; PORT_ACCESS_FROM_JVMTI(env); - *cString = j9mem_allocate_memory(length + 1, J9MEM_CATEGORY_JVMTI_ALLOCATE); + *cString = (char*)j9mem_allocate_memory(length + 1, J9MEM_CATEGORY_JVMTI_ALLOCATE); if (*cString == NULL) { rc = JVMTI_ERROR_OUT_OF_MEMORY; } else { @@ -841,12 +851,12 @@ getVirtualThreadState(J9VMThread *currentThread, jthread thread) jclass jlThread = NULL; vm->internalVMFunctions->internalExitVMToJNI(currentThread); - jlThread = (*env)->FindClass(env, "java/lang/Thread"); + jlThread = env->FindClass("java/lang/Thread"); if (NULL != jlThread) { - fid = (*env)->GetFieldID(env, jlThread, "container", "Ljdk/internal/vm/ThreadContainer;"); + fid = env->GetFieldID(jlThread, "container", "Ljdk/internal/vm/ThreadContainer;"); } if ((NULL != fid) - && (NULL == (*env)->GetObjectField(env, thread, fid)) + && (NULL == env->GetObjectField(thread, fid)) ) { rc = JVMTI_JAVA_LANG_THREAD_STATE_NEW; } else { @@ -1037,12 +1047,12 @@ findAgentBreakpoint(J9VMThread * currentThread, J9JVMTIEnv * j9env, J9Method * r jmethodID currentMethod; currentMethod = getCurrentMethodID(currentThread, ramMethod); - agentBreakpoint = pool_startDo(j9env->breakpoints, &poolState); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_startDo(j9env->breakpoints, &poolState); while (agentBreakpoint != NULL) { if ((agentBreakpoint->method == currentMethod) && (agentBreakpoint->location == location)) { break; } - agentBreakpoint = pool_nextDo(&poolState); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_nextDo(&poolState); } return agentBreakpoint; } @@ -1055,12 +1065,12 @@ findBreakpointedMethod(J9JVMTIData * jvmtiData, J9Method * ramMethod) pool_state poolState; J9JVMTIBreakpointedMethod * breakpointedMethod; - breakpointedMethod = pool_startDo(jvmtiData->breakpointedMethods, &poolState); + breakpointedMethod = (J9JVMTIBreakpointedMethod*)pool_startDo(jvmtiData->breakpointedMethods, &poolState); while (breakpointedMethod != NULL) { if (breakpointedMethod->method == ramMethod) { break; } - breakpointedMethod = pool_nextDo(&poolState); + breakpointedMethod = (J9JVMTIBreakpointedMethod*)pool_nextDo(&poolState); } return breakpointedMethod; } @@ -1196,7 +1206,7 @@ createBreakpointedMethod(J9VMThread * currentThread, J9Method * ramMethod) * in the original ROMMethod and not the copy that is about to be made. */ - breakpointedMethod = pool_newElement(jvmtiData->breakpointedMethods); + breakpointedMethod = (J9JVMTIBreakpointedMethod*)pool_newElement(jvmtiData->breakpointedMethods); if (breakpointedMethod == NULL) { return NULL; } @@ -1243,7 +1253,7 @@ createBreakpointedMethod(J9VMThread * currentThread, J9Method * ramMethod) } } #endif - copiedROMMethod = j9mem_allocate_memory(allocSize, J9MEM_CATEGORY_JVMTI); + copiedROMMethod = (J9ROMMethod*)j9mem_allocate_memory(allocSize, J9MEM_CATEGORY_JVMTI); if (copiedROMMethod == NULL) { pool_removeElement(jvmtiData->breakpointedMethods, breakpointedMethod); return NULL; @@ -1308,7 +1318,7 @@ createBreakpointedMethod(J9VMThread * currentThread, J9Method * ramMethod) /* Fix the method and stacks to point to the new bytecodes */ - fixBytecodesInAllStacks(vm, ramMethod, delta); + fixBytecodesInAllStacks(currentThread, ramMethod, delta); /* Add the delta to point at the copied bytecodes. This effectively changes this RAM Method's ROM Method to the copy when accessed using J9_ROM_METHOD_FROM_RAM_METHOD */ @@ -1347,7 +1357,7 @@ createSingleBreakpoint(J9VMThread * currentThread, J9Method * ramMethod, IDATA l /* Create a new breakpoint */ - globalBreakpoint = pool_newElement(jvmtiData->breakpoints); + globalBreakpoint = (J9JVMTIGlobalBreakpoint*)pool_newElement(jvmtiData->breakpoints); if (globalBreakpoint == NULL) { deleteBreakpointedMethodReference(currentThread, breakpointedMethod); return JVMTI_ERROR_OUT_OF_MEMORY; @@ -1383,7 +1393,7 @@ deleteBreakpointedMethodReference(J9VMThread * currentThread, J9JVMTIBreakpointe ramMethod = breakpointedMethod->method; copiedROMMethod = breakpointedMethod->copiedROMMethod; delta = ((UDATA) breakpointedMethod->originalROMMethod) - (UDATA) copiedROMMethod; - fixBytecodesInAllStacks(vm, ramMethod, delta); + fixBytecodesInAllStacks(currentThread, ramMethod, delta); ramMethod->bytecodes += delta; /* Free the copied method */ @@ -1410,12 +1420,12 @@ findGlobalBreakpoint(J9JVMTIData * jvmtiData, J9Method * ramMethod, IDATA locati pool_state poolState; J9JVMTIGlobalBreakpoint * globalBreakpoint; - globalBreakpoint = pool_startDo(jvmtiData->breakpoints, &poolState); + globalBreakpoint = (J9JVMTIGlobalBreakpoint*)pool_startDo(jvmtiData->breakpoints, &poolState); while (globalBreakpoint != NULL) { if ((globalBreakpoint->breakpointedMethod->method == ramMethod) && (globalBreakpoint->location == location)) { break; } - globalBreakpoint = pool_nextDo(&poolState); + globalBreakpoint = (J9JVMTIGlobalBreakpoint*)pool_nextDo(&poolState); } return globalBreakpoint; } @@ -1442,24 +1452,47 @@ fixBytecodesFrameIterator(J9VMThread * currentThread, J9StackWalkState * walkSta } +#if JAVA_SPEC_VERSION >= 19 +static jvmtiIterationControl +fixBytecodesCallBack(J9VMThread *currentThread, J9MM_IterateObjectDescriptor *object, void *userData) +{ + J9JavaVM *vm = currentThread->javaVM; + j9object_t continuationObj = object->object; + j9object_t vthread = J9VMJDKINTERNALVMCONTINUATION_VTHREAD(currentThread, continuationObj); + ContinuationState continuationState = J9VMJDKINTERNALVMCONTINUATION_STATE(currentThread, continuationObj); + + if ((NULL != vthread) && J9_ARE_NO_BITS_SET(continuationState, J9_GC_CONTINUATION_STATE_LAST_UNMOUNT)) { + J9StackWalkState *walkState = (J9StackWalkState*)userData; + J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, continuationObj); + j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(currentThread, continuation, continuationObj); + + vm->internalVMFunctions->walkContinuationStackFrames(currentThread, continuation, threadObject, walkState); + } + return JVMTI_ITERATION_CONTINUE; +} +#endif /* JAVA_SPEC_VERSION >= 19 */ + static void -fixBytecodesInAllStacks(J9JavaVM * vm, J9Method * method, UDATA delta) +fixBytecodesInAllStacks(J9VMThread *currentThread, J9Method * method, UDATA delta) { - J9VMThread * currentThread; - - currentThread = vm->mainThread; + J9JavaVM *vm = currentThread->javaVM; + J9VMThread *walkThread = currentThread; + J9StackWalkState walkState; + + walkState.skipCount = 0; + walkState.flags = J9_STACKWALK_ITERATE_FRAMES; + walkState.frameWalkFunction = fixBytecodesFrameIterator; + walkState.userData1 = method; + walkState.userData2 = (void *) delta; do { - J9StackWalkState walkState; - - walkState.walkThread = currentThread; - walkState.skipCount = 0; - walkState.flags = J9_STACKWALK_ITERATE_FRAMES; - walkState.frameWalkFunction = fixBytecodesFrameIterator; - walkState.userData1 = method; - walkState.userData2 = (void *) delta; + walkState.walkThread = walkThread; vm->walkStackFrames(currentThread, &walkState); - } while ((currentThread = currentThread->linkNext) != vm->mainThread); + } while ((walkThread = walkThread->linkNext) != currentThread); +#if JAVA_SPEC_VERSION >= 19 + vm->memoryManagerFunctions->j9gc_flush_nonAllocationCaches_for_walk(vm); + vm->memoryManagerFunctions->j9mm_iterate_all_continuation_objects(currentThread, vm->portLibrary, 0, fixBytecodesCallBack, (void*)&walkState); +#endif /* JAVA_SPEC_VERSION >= 19 */ } jmethodID @@ -1503,13 +1536,13 @@ allAgentBreakpointsNextDo(J9JVMTIAgentBreakpointDoState * state) { J9JVMTIAgentBreakpoint * agentBreakpoint; - agentBreakpoint = pool_nextDo(&(state->breakpointState)); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_nextDo(&(state->breakpointState)); if (agentBreakpoint != NULL) { return agentBreakpoint; } - while ((state->j9env = pool_nextDo(&(state->environmentState))) != NULL) { - agentBreakpoint = pool_startDo(state->j9env->breakpoints, &(state->breakpointState)); + while ((state->j9env = (J9JVMTIEnv*)pool_nextDo(&(state->environmentState))) != NULL) { + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_startDo(state->j9env->breakpoints, &(state->breakpointState)); if (agentBreakpoint != NULL) { return agentBreakpoint; } @@ -1523,30 +1556,29 @@ allAgentBreakpointsNextDo(J9JVMTIAgentBreakpointDoState * state) J9JVMTIAgentBreakpoint * allAgentBreakpointsStartDo(J9JVMTIData * jvmtiData, J9JVMTIAgentBreakpointDoState * state) { - state->j9env = pool_startDo(jvmtiData->environments, &(state->environmentState)); + state->j9env = (J9JVMTIEnv*)pool_startDo(jvmtiData->environments, &(state->environmentState)); while (state->j9env != NULL) { /* CMVC 196966: only inspect live (not disposed) environments */ if (0 == (state->j9env->flags & J9JVMTIENV_FLAG_DISPOSED)) { J9JVMTIAgentBreakpoint * agentBreakpoint; - agentBreakpoint = pool_startDo(state->j9env->breakpoints, &(state->breakpointState)); + agentBreakpoint = (J9JVMTIAgentBreakpoint*)pool_startDo(state->j9env->breakpoints, &(state->breakpointState)); if (agentBreakpoint != NULL) { return agentBreakpoint; } } - state->j9env = pool_nextDo(&(state->environmentState)); + state->j9env = (J9JVMTIEnv*)pool_nextDo(&(state->environmentState)); } return NULL; } - #if defined(J9VM_INTERP_NATIVE_SUPPORT) J9JVMTICompileEvent * queueCompileEvent(J9JVMTIData * jvmtiData, jmethodID methodID, void * startPC, UDATA length, void * metaData, UDATA isLoad) { - J9JVMTICompileEvent * compEvent = pool_newElement(jvmtiData->compileEvents); + J9JVMTICompileEvent * compEvent = (J9JVMTICompileEvent*)pool_newElement(jvmtiData->compileEvents); if (compEvent != NULL) { compEvent->methodID = methodID; @@ -1602,9 +1634,9 @@ createThreadData(J9JVMTIEnv *j9env, J9VMThread *vmThread, j9object_t thread) if (0 == j9env->tlsKey) { omrthread_monitor_enter(j9env->threadDataPoolMutex); if (0 == j9env->tlsKey) { - rc = jvmtiTLSAlloc(vmThread->javaVM, &j9env->tlsKey); - if (JVMTI_ERROR_NONE != rc) { + if (0 != jvmtiTLSAlloc(vmThread->javaVM, &j9env->tlsKey)) { omrthread_monitor_exit(j9env->threadDataPoolMutex); + rc = JVMTI_ERROR_OUT_OF_MEMORY; goto exit; } goto allocate_thread_data_locked; @@ -1621,7 +1653,7 @@ createThreadData(J9JVMTIEnv *j9env, J9VMThread *vmThread, j9object_t thread) if (NULL == threadData) { /* We are the first to access the thread data for the given thread. */ allocate_thread_data_locked: - threadData = pool_newElement(j9env->threadDataPool); + threadData = (J9JVMTIThreadData*)pool_newElement(j9env->threadDataPool); if (NULL == threadData) { rc = JVMTI_ERROR_OUT_OF_MEMORY; } else { @@ -1940,10 +1972,10 @@ jvmtiTLSFree(J9JavaVM *vm, UDATA key) J9JVMTIThreadData **each = NULL; omrthread_monitor_enter(vm->tlsPoolMutex); - each = pool_startDo(vm->tlsPool, &state); + each = (J9JVMTIThreadData**)pool_startDo(vm->tlsPool, &state); while (NULL != each) { each[key - 1] = NULL; - each = pool_nextDo(&state); + each = (J9JVMTIThreadData**)pool_nextDo(&state); } omrthread_monitor_exit(vm->tlsPoolMutex); @@ -2085,3 +2117,5 @@ getJ9VMContinuationToWalk(J9VMThread *currentThread, J9VMThread *targetThread, j return continuation; } #endif /* JAVA_SPEC_VERSION >= 19 */ + +} /* extern "C" */ diff --git a/runtime/jvmti/jvmti_internal.h b/runtime/jvmti/jvmti_internal.h index 94346d41d51..c8487641bbc 100644 --- a/runtime/jvmti/jvmti_internal.h +++ b/runtime/jvmti/jvmti_internal.h @@ -898,7 +898,7 @@ jvmtiIterateOverReachableObjects(jvmtiEnv* env, const void * user_data); -/* ---------------- jvmtiHelpers.c ---------------- */ +/* ---------------- jvmtiHelpers.cpp ---------------- */ /** * @brief Allocate a thread local storage key (which represents a jvmtiEnv) to index into a thread