8329491: GetThreadListStackTraces function should use JvmtiHandshake

Reviewed-by: pchilanomate, lmesnik
This commit is contained in:
Serguei Spitsyn 2024-04-11 04:19:02 +00:00
parent 643dd48a2a
commit 5e544f1510
3 changed files with 24 additions and 26 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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.