From e7220c5e6af0d3191c96d8c67c89f761cf1026da Mon Sep 17 00:00:00 2001 From: Gengchen Tuo Date: Wed, 21 Jun 2023 16:26:30 -0400 Subject: [PATCH] Skip methods with JvmtiMountTransition annotation in findDecompileInfo Java methods tagged with the JvmtiMountTransition annotation are involved in transitioning between carrier to virtual threads, and vice-versa. These methods are not part of the thread's scope. So, they are skipped during introspection by the following JVMTI functions: - ForceEarlyReturn - NotifyFramePop - Local Variable (GetOrSetLocal) This PR allows us to match the RI in jvmti/vthread/MethodExitTest. Related #17490 Closes #17758 Co-authored-by: Gengchen Tuo Signed-off-by: Babneet Singh --- .../classes/jdk/internal/vm/Continuation.java | 5 +++- runtime/jvmti/jvmtiHelpers.c | 24 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java b/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java index b594f4368bc..aa986cd8cdc 100644 --- a/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java +++ b/jcl/src/java.base/share/classes/jdk/internal/vm/Continuation.java @@ -28,6 +28,7 @@ import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.Unsafe; +import jdk.internal.vm.annotation.JvmtiMountTransition; /** * Continuation class performing the mount/unmount operation for VirtualThread @@ -277,7 +278,9 @@ public PreemptStatus tryPreempt(Thread t) { } /* Continuation Native APIs */ + @JvmtiMountTransition private native boolean enterImpl(); - private static native boolean yieldImpl(boolean isFinished); + @JvmtiMountTransition + private static native boolean yieldImpl(boolean isFinished); } diff --git a/runtime/jvmti/jvmtiHelpers.c b/runtime/jvmti/jvmtiHelpers.c index c26867e95ae..911c5634a4a 100644 --- a/runtime/jvmti/jvmtiHelpers.c +++ b/runtime/jvmti/jvmtiHelpers.c @@ -1791,21 +1791,43 @@ static UDATA findDecompileInfoFrameIterator(J9VMThread *currentThread, J9StackWalkState *walkState) { UDATA rc = J9_STACKWALK_KEEP_ITERATING; + J9Method *method = walkState->method; + +#if JAVA_SPEC_VERSION >= 20 + J9ROMMethod *romMethod = NULL; + U_32 extendedModifiers = 0; + + /* walkState->method can never be NULL since the J9_STACKWALK_VISIBLE_ONLY flag is set. */ + Assert_JVMTI_true(NULL != method); + + romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method); + extendedModifiers = getExtendedModifiersDataFromROMMethod(romMethod); + + if (J9_ARE_ANY_BITS_SET(extendedModifiers, CFR_METHOD_EXT_JVMTIMOUNTTRANSITION_ANNOTATION)) { + goto skip; + } +#endif /* JAVA_SPEC_VERSION >= 20 */ + if (JVMTI_ERROR_NONE != (UDATA)walkState->userData1) { /* The current frame is the requested frame. Record the inline depth for the decompiler * and the method and bytecodePCOffset for the slot validator. */ walkState->userData1 = (void*)JVMTI_ERROR_NONE; walkState->userData2 = (void*)walkState->inlineDepth; - walkState->userData3 = walkState->method; + walkState->userData3 = method; walkState->userData4 = (void*)(UDATA)walkState->bytecodePCOffset; } + /* Keep walking until the outer method is reached (the inline decompiler requires that * the walkState be at this point). */ if (0 == walkState->inlineDepth) { rc = J9_STACKWALK_STOP_ITERATING; } + +#if JAVA_SPEC_VERSION >= 20 +skip: +#endif /* JAVA_SPEC_VERSION >= 20 */ return rc; }