diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index 9fff32f8e78..9b4ac85f220 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -1371,16 +1371,10 @@ JvmtiEnvBase::set_frame_pop(JvmtiThreadState* state, javaVFrame* jvf, jint depth return JVMTI_ERROR_OPAQUE_FRAME; } - if (state->is_virtual() && (thread == nullptr || !thread->is_vthread_mounted())) { // unmounted virtual thread - assert(fr.is_heap_frame(), "sanity check"); - fr = jvf->stack_chunk()->derelativize(fr); - jvf->stack_chunk()->force_slow_path(); - fr.deoptimize(nullptr); - } else { // platform thread or mounted virtual thread - if (fr.is_heap_frame()) { - fr = jvf->stack_chunk()->derelativize(fr); - jvf->stack_chunk()->force_slow_path(); - } + if (fr.is_heap_frame()) { + assert(state->is_virtual(), "invariant"); + fr.deoptimize(nullptr, jvf->stack_chunk()); + } else { Deoptimization::deoptimize(thread, fr); } } diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp index b983b4648d4..d99d36571ad 100644 --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -387,6 +387,22 @@ void frame::deoptimize(JavaThread* thread) { #endif // ASSERT } +void frame::deoptimize(JavaThread* thread, stackChunkOop chunk) { + assert(is_heap_frame() && _frame_index >= 0, "wrong frame type"); + + // Fast path does not expect deopted frames + chunk->force_slow_path(); + + frame fr = chunk->derelativize(*this); + fr.deoptimize(nullptr); + + // Fix chunk pc if deopted frame is the top one + bool is_top = fr.sp() == chunk->sp_address(); + if (is_top) { + chunk->set_pc(fr.raw_pc()); + } +} + frame frame::java_sender() const { RegisterMap map(JavaThread::current(), RegisterMap::UpdateMap::skip, diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp index 35d73e8ef78..a9cfacc1241 100644 --- a/src/hotspot/share/runtime/frame.hpp +++ b/src/hotspot/share/runtime/frame.hpp @@ -282,6 +282,7 @@ class frame { // Support for deoptimization void deoptimize(JavaThread* thread); + void deoptimize(JavaThread* thread, stackChunkOop chunk); // The frame's original SP, before any extension by an interpreted callee; // used for packing debug info into vframeArray objects and vframeArray lookup.