Skip to content

Commit

Permalink
Merge pull request #18180 from babsingh/fix_jvmtimounttransition
Browse files Browse the repository at this point in the history
Pass threadObject to walkContinuationStackFrames
  • Loading branch information
dmitripivkine committed Oct 5, 2023
2 parents 9f497fc + 618c2f4 commit 9036526
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 32 deletions.
44 changes: 26 additions & 18 deletions runtime/compiler/control/HookedByTheJit.cpp
Expand Up @@ -36,6 +36,7 @@
#include "vmaccess.h"
#if JAVA_SPEC_VERSION >= 19
#include "HeapIteratorAPI.h"
#include "ContinuationHelpers.hpp"
#endif /* JAVA_SPEC_VERSION >= 19 */
#include "codegen/CodeGenerator.hpp"
#include "compile/CompilationTypes.hpp"
Expand Down Expand Up @@ -6604,25 +6605,29 @@ static UDATA jitReleaseCodeStackWalkFrame(J9VMThread *vmThread, J9StackWalkState

#if JAVA_SPEC_VERSION >= 19
static void jitWalkContinuationStackFrames(J9HookInterface **hookInterface, UDATA eventNum, void *eventData, void *userData)
{
MM_ContinuationIteratingEvent *continuationIteratingEvent = (MM_ContinuationIteratingEvent *)eventData;
J9VMThread * vmThread = continuationIteratingEvent->vmThread;
J9InternalVMFunctions *vmFuncs = vmThread->javaVM->internalVMFunctions;
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, continuationIteratingEvent->object);
if (NULL != continuation) {
J9StackWalkState walkState;
walkState.flags = J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES;
walkState.skipCount = 0;
walkState.frameWalkFunction = jitReleaseCodeStackWalkFrame;

vmFuncs->walkContinuationStackFrames(vmThread, continuation, &walkState);
}
}
{
MM_ContinuationIteratingEvent *continuationIteratingEvent = (MM_ContinuationIteratingEvent *)eventData;
J9VMThread * vmThread = continuationIteratingEvent->vmThread;
J9InternalVMFunctions *vmFuncs = vmThread->javaVM->internalVMFunctions;
j9object_t continuationObj = continuationIteratingEvent->object;
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, continuationObj);
if (NULL != continuation)
{
J9StackWalkState walkState;
walkState.flags = J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES;
walkState.skipCount = 0;
walkState.frameWalkFunction = jitReleaseCodeStackWalkFrame;

j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(vmThread, continuation, continuationObj);
vmFuncs->walkContinuationStackFrames(vmThread, continuation, threadObject, &walkState);
}
}

static jvmtiIterationControl jitWalkContinuationCallBack(J9VMThread *vmThread, J9MM_IterateObjectDescriptor *object, void *userData)
{
J9InternalVMFunctions *vmFuncs = vmThread->javaVM->internalVMFunctions;
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, object->object);
j9object_t continuationObj = object->object;
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, continuationObj);
if (NULL != continuation)
{
bool yieldHappened = false;
Expand All @@ -6632,7 +6637,10 @@ static jvmtiIterationControl jitWalkContinuationCallBack(J9VMThread *vmThread, J
walkState.flags = J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES;
walkState.skipCount = 0;
walkState.frameWalkFunction = jitReleaseCodeStackWalkFrame;
vmFuncs->walkContinuationStackFrames(vmThread, continuation, &walkState);

j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(vmThread, continuation, continuationObj);
vmFuncs->walkContinuationStackFrames(vmThread, continuation, threadObject, &walkState);

continuation->dropFlags = 0x1;
condYieldFromGCFunctionPtr condYield = (condYieldFromGCFunctionPtr)userData;
yieldHappened = condYield(vmThread->omrVMThread, J9_GC_METRONOME_UTILIZATION_COMPONENT_JIT);
Expand Down Expand Up @@ -6695,14 +6703,14 @@ static void jitReleaseCodeStackWalk(OMR_VMThread *omrVMThread, condYieldFromGCFu
thread->dropFlags |= 0x1;
}

if ((NULL!= thread->currentContinuation) && ((thread->currentContinuation->dropFlags & 0x1) ? false : true))
if ((NULL != thread->currentContinuation) && ((thread->currentContinuation->dropFlags & 0x1) ? false : true))
/* If a continuation is mounted, always walk the continuation as that represent the CarrierThread */
{
J9StackWalkState walkState;
walkState.flags = J9_STACKWALK_ITERATE_HIDDEN_JIT_FRAMES | J9_STACKWALK_ITERATE_FRAMES | J9_STACKWALK_SKIP_INLINES;
walkState.skipCount = 0;
walkState.frameWalkFunction = jitReleaseCodeStackWalkFrame;
vmFuncs->walkContinuationStackFrames(vmThread, thread->currentContinuation, &walkState);
vmFuncs->walkContinuationStackFrames(vmThread, thread->currentContinuation, thread->carrierThreadObject, &walkState);
thread->currentContinuation->dropFlags |= 0x1;
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/gc_base/RootScanner.cpp
Expand Up @@ -546,7 +546,7 @@ MM_RootScanner::scanOneThread(MM_EnvironmentBase *env, J9VMThread* walkThread, v
{
/* At this point we know that a virtual thread is mounted. We previously scanned its stack,
* and now we will scan carrier's stack, that continuation struct is currently pointing to. */
GC_VMThreadStackSlotIterator::scanSlots(currentThread, walkThread->currentContinuation, localData, stackSlotIterator, isStackFrameClassWalkNeeded(), _trackVisibleStackFrameDepth);
GC_VMThreadStackSlotIterator::scanSlots(currentThread, walkThread, walkThread->currentContinuation, localData, stackSlotIterator, isStackFrameClassWalkNeeded(), _trackVisibleStackFrameDepth);
}
#endif /* JAVA_SPEC_VERSION >= 19 */
return false;
Expand Down
2 changes: 1 addition & 1 deletion runtime/gc_glue_java/ConcurrentMarkingDelegate.cpp
Expand Up @@ -157,7 +157,7 @@ MM_ConcurrentMarkingDelegate::scanThreadRoots(MM_EnvironmentBase *env)

#if JAVA_SPEC_VERSION >= 19
if (NULL != vmThread->currentContinuation) {
GC_VMThreadStackSlotIterator::scanSlots(vmThread, vmThread->currentContinuation, (void *)&localData, concurrentStackSlotIterator, true, false);
GC_VMThreadStackSlotIterator::scanSlots(vmThread, vmThread, vmThread->currentContinuation, (void *)&localData, concurrentStackSlotIterator, true, false);
}
#endif /* JAVA_SPEC_VERSION >= 19 */

Expand Down
10 changes: 8 additions & 2 deletions runtime/gc_structs/VMThreadStackSlotIterator.cpp
Expand Up @@ -34,6 +34,10 @@
#include "VMThreadStackSlotIterator.hpp"
#include "VMHelpers.hpp"

#if JAVA_SPEC_VERSION >= 19
#include "ContinuationHelpers.hpp"
#endif /* JAVA_SPEC_VERSION >= 19 */

extern "C" {

/**
Expand Down Expand Up @@ -144,14 +148,16 @@ GC_VMThreadStackSlotIterator::scanContinuationSlots(

#if JAVA_SPEC_VERSION >= 19
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, continuationObjectPtr);
vmThread->javaVM->internalVMFunctions->walkContinuationStackFrames(vmThread, continuation, &stackWalkState);
j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(vmThread, continuation, continuationObjectPtr);
vmThread->javaVM->internalVMFunctions->walkContinuationStackFrames(vmThread, continuation, threadObject, &stackWalkState);
#endif /* JAVA_SPEC_VERSION >= 19 */
}

#if JAVA_SPEC_VERSION >= 19
void
GC_VMThreadStackSlotIterator::scanSlots(
J9VMThread *vmThread,
J9VMThread *walkThread,
J9VMContinuation *continuation,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
Expand All @@ -162,6 +168,6 @@ GC_VMThreadStackSlotIterator::scanSlots(
J9StackWalkState stackWalkState;
initializeStackWalkState(&stackWalkState, vmThread, userData, oSlotIterator, includeStackFrameClassReferences, trackVisibleFrameDepth);

vmThread->javaVM->internalVMFunctions->walkContinuationStackFrames(vmThread, continuation, &stackWalkState);
vmThread->javaVM->internalVMFunctions->walkContinuationStackFrames(vmThread, continuation, walkThread->carrierThreadObject, &stackWalkState);
}
#endif /* JAVA_SPEC_VERSION >= 19 */
1 change: 1 addition & 0 deletions runtime/gc_structs/VMThreadStackSlotIterator.hpp
Expand Up @@ -71,6 +71,7 @@ class GC_VMThreadStackSlotIterator
#if JAVA_SPEC_VERSION >= 19
static void scanSlots(
J9VMThread *vmThread,
J9VMThread *walkThread,
J9VMContinuation *continuation,
void *userData,
J9MODRON_OSLOTITERATOR *oSlotIterator,
Expand Down
2 changes: 1 addition & 1 deletion runtime/jcl/common/getstacktrace.c
Expand Up @@ -79,7 +79,7 @@ getStackTraceForThread(J9VMThread *currentThread, J9VMThread *targetThread, UDAT
* then the carrier thread's stacktrace is retrieved through the cached state in the continuation.
*/
walkState.skipCount = 0;
rc = vmfns->walkContinuationStackFrames(currentThread, targetThread->currentContinuation, &walkState);
rc = vmfns->walkContinuationStackFrames(currentThread, targetThread->currentContinuation, threadObject, &walkState);
} else if (isVirtual && (threadObject != targetThread->threadObject)) {
/* If the virtual thread object doesn't match the current thread object, it must have unmounted
* from this carrier thread, return NULL and the JCL code will handle the retry.
Expand Down
4 changes: 2 additions & 2 deletions runtime/jvmti/jvmtiHelpers.c
Expand Up @@ -2035,15 +2035,15 @@ genericWalkStackFramesHelper(J9VMThread *currentThread, J9VMThread *targetThread
} else {
j9object_t contObject = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CONT(currentThread, threadObject);
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(currentThread, contObject);
vm->internalVMFunctions->walkContinuationStackFrames(currentThread, continuation, walkState);
vm->internalVMFunctions->walkContinuationStackFrames(currentThread, continuation, threadObject, walkState);
}
} else
#endif /* JAVA_SPEC_VERSION >= 19 */
{
#if JAVA_SPEC_VERSION >= 19
J9VMContinuation *currentContinuation = targetThread->currentContinuation;
if (NULL != currentContinuation) {
rc = vm->internalVMFunctions->walkContinuationStackFrames(currentThread, currentContinuation, walkState);
rc = vm->internalVMFunctions->walkContinuationStackFrames(currentThread, currentContinuation, threadObject, walkState);
} else
#endif /* JAVA_SPEC_VERSION >= 19 */
{
Expand Down
26 changes: 26 additions & 0 deletions runtime/oti/ContinuationHelpers.hpp
Expand Up @@ -223,6 +223,32 @@ class VM_ContinuationHelpers {
{
*continuationStatePtr &= ~J9_GC_CONTINUATION_STATE_CARRIERID_MASK;
}

/**
* Return the thread object whose state is stored in the J9VMContinuation.
*
* @param[in] vmThread the current thread
* @param[in] continuation the native continuation structure
* @param[in] continuationObject the continuation object
* @return the thread object whose state is stored in the continuation
*/
static VMINLINE j9object_t
getThreadObjectForContinuation(J9VMThread *vmThread, J9VMContinuation *continuation, j9object_t continuationObject)
{
/* threadObject points to the virtual thread. */
j9object_t threadObject = (j9object_t)J9VMJDKINTERNALVMCONTINUATION_VTHREAD(vmThread, continuationObject);
ContinuationState volatile *continuationStatePtr = getContinuationStateAddress(vmThread, continuationObject);
ContinuationState continuationState = *continuationStatePtr;

if (isFullyMounted(continuationState)) {
/* If the continuation is fully mounted, then the continuation stores the state of the carrier thread.
* Below, threadObject points to the carrier thread.
*/
threadObject = (j9object_t)J9VMJAVALANGVIRTUALTHREAD_CARRIERTHREAD(vmThread, threadObject);
}

return threadObject;
}
};

#endif /* CONTINUATIONHELPERS_HPP_ */
2 changes: 1 addition & 1 deletion runtime/oti/j9nonbuilder.h
Expand Up @@ -5047,7 +5047,7 @@ typedef struct J9InternalVMFunctions {
void (*freeContinuation)(struct J9VMThread *currentThread, j9object_t continuationObject, BOOLEAN skipLocalCache);
void (*recycleContinuation)(struct J9JavaVM *vm, struct J9VMThread *vmThread, struct J9VMContinuation *continuation, BOOLEAN skipLocalCache);
void (*freeTLS)(struct J9VMThread *currentThread, j9object_t threadObj);
UDATA (*walkContinuationStackFrames)(struct J9VMThread *currentThread, struct J9VMContinuation *continuation, J9StackWalkState *walkState);
UDATA (*walkContinuationStackFrames)(struct J9VMThread *currentThread, struct J9VMContinuation *continuation, j9object_t threadObject, J9StackWalkState *walkState);
UDATA (*walkAllStackFrames)(struct J9VMThread *currentThread, J9StackWalkState *walkState);
BOOLEAN (*acquireVThreadInspector)(struct J9VMThread *currentThread, jobject thread, BOOLEAN spin);
void (*releaseVThreadInspector)(struct J9VMThread *currentThread, jobject thread);
Expand Down
3 changes: 2 additions & 1 deletion runtime/oti/vm_api.h
Expand Up @@ -4470,10 +4470,11 @@ copyFieldsFromContinuation(J9VMThread *currentThread, J9VMThread *vmThread, J9VM
*
* @param currentThread current thread
* @param continuation the continuation to be walked
* @param threadObject the thread object whose state is stored in the continuation
* @return 0 on success and non-zero on failure
*/
UDATA
walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continuation, J9StackWalkState *walkState);
walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continuation, j9object_t threadObject, J9StackWalkState *walkState);

/**
* @brief Walk all stackframes in the VM.
Expand Down
2 changes: 1 addition & 1 deletion runtime/vm/BytecodeInterpreter.hpp
Expand Up @@ -3194,7 +3194,7 @@ class INTERPRETER_CLASS
) {
continuationWalkState.flags = walkFlags;
continuationWalkRC = _vm->internalVMFunctions->walkContinuationStackFrames(
_currentThread, _currentThread->currentContinuation, &continuationWalkState);
_currentThread, _currentThread->currentContinuation, _currentThread->carrierThreadObject, &continuationWalkState);
}
#endif /* JAVA_SPEC_VERSION >= 19 */
/* No need for VMStructHasBeenUpdated as the above walk cannot change the roots */
Expand Down
10 changes: 6 additions & 4 deletions runtime/vm/ContinuationHelpers.cpp
Expand Up @@ -456,7 +456,7 @@ copyFieldsFromContinuation(J9VMThread *currentThread, J9VMThread *vmThread, J9VM
}

UDATA
walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continuation, J9StackWalkState *walkState)
walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continuation, j9object_t threadObject, J9StackWalkState *walkState)
{
Assert_VM_notNull(currentThread);

Expand All @@ -467,7 +467,7 @@ walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continu
J9VMEntryLocalStorage els = {0};

copyFieldsFromContinuation(currentThread, &stackThread, &els, continuation);

stackThread.threadObject = threadObject;
walkState->walkThread = &stackThread;
rc = currentThread->javaVM->walkStackFrames(currentThread, walkState);
}
Expand All @@ -479,11 +479,13 @@ walkContinuationStackFrames(J9VMThread *currentThread, J9VMContinuation *continu
jvmtiIterationControl
walkContinuationCallBack(J9VMThread *vmThread, J9MM_IterateObjectDescriptor *object, void *userData)
{
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, object->object);
j9object_t continuationObj = object->object;
J9VMContinuation *continuation = J9VMJDKINTERNALVMCONTINUATION_VMREF(vmThread, continuationObj);
if (NULL != continuation) {
J9StackWalkState localWalkState = *(J9StackWalkState*)userData;
/* Walk non-null continuation's stack */
walkContinuationStackFrames(vmThread, continuation, &localWalkState);
j9object_t threadObject = VM_ContinuationHelpers::getThreadObjectForContinuation(vmThread, continuation, continuationObj);
walkContinuationStackFrames(vmThread, continuation, threadObject, &localWalkState);
}
return JVMTI_ITERATION_CONTINUE;
}
Expand Down

0 comments on commit 9036526

Please sign in to comment.