diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index e4a9a7ebe6f..14030c1f8d3 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1678,39 +1678,22 @@ JvmtiEnv::GetAllStackTraces(jint max_frame_count, jvmtiStackInfo** stack_info_pt jvmtiError JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list, jint max_frame_count, jvmtiStackInfo** stack_info_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - JvmtiVTMSTransitionDisabler disabler; if (thread_count == 1) { - // Use direct handshake if we need to get only one stack trace. JavaThread *current_thread = JavaThread::current(); - ThreadsListHandle tlh(current_thread); jthread thread = thread_list[0]; - JavaThread *java_thread; - oop thread_obj = nullptr; - err = get_threadOop_and_JavaThread(tlh.list(), thread, &java_thread, &thread_obj); - if (err != JVMTI_ERROR_NONE) { - return err; - } - - if (java_lang_VirtualThread::is_instance(thread_obj) && java_thread == nullptr) { - // Target virtual thread is unmounted. - ResourceMark rm(current_thread); - MultipleStackTracesCollector collector(this, max_frame_count); - collector.fill_frames(thread, java_thread, thread_obj); - collector.allocate_and_fill_stacks(/* thread_count */ 1); - *stack_info_ptr = collector.stack_info(); - return collector.result(); - } GetSingleStackTraceClosure op(this, current_thread, thread, max_frame_count); - Handshake::execute(&op, &tlh, java_thread); + JvmtiHandshake::execute(&op, thread); err = op.result(); if (err == JVMTI_ERROR_NONE) { *stack_info_ptr = op.stack_info(); } } else { + JvmtiVTMSTransitionDisabler disabler; + // JVMTI get stack traces at safepoint. VM_GetThreadListStackTraces op(this, thread_count, thread_list, max_frame_count); VMThread::execute(&op); diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index 483426d9b59..9b9197aa888 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -2053,17 +2053,30 @@ VM_GetThreadListStackTraces::doit() { } void -GetSingleStackTraceClosure::do_thread(Thread *target) { - JavaThread *jt = JavaThread::cast(target); +GetSingleStackTraceClosure::doit() { + JavaThread *jt = _target_jt; oop thread_oop = JNIHandles::resolve_external_guard(_jthread); - if (!jt->is_exiting() && thread_oop != nullptr) { + if ((jt == nullptr || !jt->is_exiting()) && thread_oop != nullptr) { ResourceMark rm; _collector.fill_frames(_jthread, jt, thread_oop); _collector.allocate_and_fill_stacks(1); + set_result(_collector.result()); } } +void +GetSingleStackTraceClosure::do_thread(Thread *target) { + assert(_target_jt == JavaThread::cast(target), "sanity check"); + doit(); +} + +void +GetSingleStackTraceClosure::do_vthread(Handle target_h) { + assert(_target_jt == nullptr || _target_jt->vthread() == target_h(), "sanity check"); + doit(); +} + void VM_GetAllStackTraces::doit() { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); diff --git a/src/hotspot/share/prims/jvmtiEnvBase.hpp b/src/hotspot/share/prims/jvmtiEnvBase.hpp index a1ed16b85ea..57fa059b2d8 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.hpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp @@ -724,7 +724,7 @@ public: }; // HandshakeClosure to get single stack trace. -class GetSingleStackTraceClosure : public HandshakeClosure { +class GetSingleStackTraceClosure : public JvmtiUnitedHandshakeClosure { private: JavaThread *_calling_thread; jthread _jthread; @@ -733,14 +733,16 @@ private: public: GetSingleStackTraceClosure(JvmtiEnv *env, JavaThread *calling_thread, jthread thread, jint max_frame_count) - : HandshakeClosure("GetSingleStackTrace"), + : JvmtiUnitedHandshakeClosure("GetSingleStackTrace"), _calling_thread(calling_thread), _jthread(thread), _collector(env, max_frame_count) { } void do_thread(Thread *target); + void do_vthread(Handle target_h); + void doit(); jvmtiStackInfo *stack_info() { return _collector.stack_info(); } - jvmtiError result() { return _collector.result(); } + jvmtiError result() { return _result; } }; // HandshakeClosure to count stack frames.