RFR: 8369609: Continuations preempt_epilog is missing a call to invalidate_jvmti_stack [v3]

Serguei Spitsyn sspitsyn at openjdk.org
Thu Oct 23 17:36:32 UTC 2025


On Thu, 23 Oct 2025 17:17:16 GMT, Serguei Spitsyn <sspitsyn at openjdk.org> wrote:

>> Ah, we need to call `invalidate_jvmti_stack` at the end in `jvmti_yield_cleanup`! The problem is that in `JvmtiExport::continuation_yield_cleanup` we are setting again the stack depth when calling `state->cur_stack_depth()`. We count the enterSpecial frame at the top but we don’t decrement the depth when removing it (done in assembly code).
>
> Okay, thanks! Did you verify it with run of test `serviceability/jvmti/vthread/ContStackDepthTest`? I see it is still failing with the call to `invalidate_jvmti_stack()` at the end of `jvmti_yield_cleanup()`.

This test does not fail with the following patch:

diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
index 0750f611876..a12e99903af 100644
--- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp
+++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp
@@ -1626,12 +1626,17 @@ static void invalidate_jvmti_stack(JavaThread* thread) {
 }
 
 static void jvmti_yield_cleanup(JavaThread* thread, ContinuationWrapper& cont) {
-  if (!cont.entry()->is_virtual_thread() && JvmtiExport::has_frame_pops(thread)) {
+  if (cont.entry()->is_virtual_thread()) {
+    return;
+  }
+  invalidate_jvmti_stack(thread);
+  if (JvmtiExport::has_frame_pops(thread)) {
     int num_frames = num_java_frames(cont);
 
     ContinuationWrapper::SafepointOp so(Thread::current(), cont);
-    JvmtiExport::continuation_yield_cleanup(JavaThread::current(), num_frames);
+    JvmtiExport::continuation_yield_cleanup(thread, num_frames);
   }
+  invalidate_jvmti_stack(thread);
 }
 
 static void jvmti_mount_end(JavaThread* current, ContinuationWrapper& cont, frame top) {
@@ -1685,7 +1690,6 @@ static inline freeze_result freeze_epilog(ContinuationWrapper& cont) {
 
   log_develop_debug(continuations)("=== End of freeze cont ### #" INTPTR_FORMAT, cont.hash());
 
-  JVMTI_ONLY(invalidate_jvmti_stack(JavaThread::current()));
   return freeze_ok;
 }
 
@@ -2311,7 +2315,7 @@ NOINLINE intptr_t* Thaw<ConfigT>::thaw_slow(stackChunkOop chunk, Continuation::t
 
   assert(_cont.chunk_invariant(), "");
 
-  JVMTI_ONLY(invalidate_jvmti_stack(_thread));
+  JVMTI_ONLY(if (!_cont.entry()->is_virtual_thread()) invalidate_jvmti_stack(_thread));
 
   _thread->set_cont_fastpath(_fastpath);


The call to `invalidate_jvmti_stack()` is still needed in the `thaw_slow()`.
I can go ahead with this update if you are okay with it.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27878#discussion_r2456310256


More information about the hotspot-runtime-dev mailing list