From 839dd653663867f770fbe4af0a57468675eb12db Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Tue, 21 Nov 2023 08:17:43 +0000 Subject: [PATCH] 8319244: implement JVMTI handshakes support for virtual threads Reviewed-by: pchilanomate, amenkov --- src/hotspot/share/prims/jvmtiEnv.cpp | 138 ++-------------- src/hotspot/share/prims/jvmtiEnvBase.cpp | 192 +++++++++++++--------- src/hotspot/share/prims/jvmtiEnvBase.hpp | 192 +++++----------------- src/hotspot/share/runtime/vmOperation.hpp | 2 - 4 files changed, 164 insertions(+), 360 deletions(-) diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 15472787f64..e02820a2beb 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1711,47 +1711,9 @@ JvmtiEnv::GetThreadGroupChildren(jthreadGroup group, jint* thread_count_ptr, jth // count_ptr - pre-checked for null jvmtiError JvmtiEnv::GetStackTrace(jthread thread, jint start_depth, jint max_frame_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) { - JavaThread* current_thread = JavaThread::current(); - HandleMark hm(current_thread); - - JvmtiVTMSTransitionDisabler disabler(thread); - ThreadsListHandle tlh(current_thread); - - JavaThread* java_thread = nullptr; - oop thread_obj = nullptr; - jvmtiError 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)) { - if (java_thread == nullptr) { // Target virtual thread is unmounted. - ResourceMark rm(current_thread); - - VM_VirtualThreadGetStackTrace op(this, Handle(current_thread, thread_obj), - start_depth, max_frame_count, - frame_buffer, count_ptr); - VMThread::execute(&op); - return op.result(); - } - VirtualThreadGetStackTraceClosure op(this, Handle(current_thread, thread_obj), - start_depth, max_frame_count, frame_buffer, count_ptr); - Handshake::execute(&op, java_thread); - return op.result(); - } - - // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a direct handshake for safety. - if (java_thread == JavaThread::current()) { - err = get_stack_trace(java_thread, start_depth, max_frame_count, frame_buffer, count_ptr); - } else { - // Get stack trace with handshake. - GetStackTraceClosure op(this, start_depth, max_frame_count, frame_buffer, count_ptr); - Handshake::execute(&op, java_thread); - err = op.result(); - } - - return err; + GetStackTraceClosure op(this, start_depth, max_frame_count, frame_buffer, count_ptr); + JvmtiHandshake::execute(&op, thread); + return op.result(); } /* end GetStackTrace */ @@ -1829,41 +1791,9 @@ JvmtiEnv::GetThreadListStackTraces(jint thread_count, const jthread* thread_list // count_ptr - pre-checked for null jvmtiError JvmtiEnv::GetFrameCount(jthread thread, jint* count_ptr) { - JavaThread* current_thread = JavaThread::current(); - HandleMark hm(current_thread); - - JvmtiVTMSTransitionDisabler disabler(thread); - ThreadsListHandle tlh(current_thread); - - JavaThread* java_thread = nullptr; - oop thread_obj = nullptr; - jvmtiError 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)) { - if (java_thread == nullptr) { // Target virtual thread is unmounted. - VM_VirtualThreadGetFrameCount op(this, Handle(current_thread, thread_obj), count_ptr); - VMThread::execute(&op); - return op.result(); - } - VirtualThreadGetFrameCountClosure op(this, Handle(current_thread, thread_obj), count_ptr); - Handshake::execute(&op, java_thread); - return op.result(); - } - - // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a direct handshake for safety. - if (java_thread == JavaThread::current()) { - err = get_frame_count(java_thread, count_ptr); - } else { - // get java stack frame count with handshake. - GetFrameCountClosure op(this, count_ptr); - Handshake::execute(&op, java_thread); - err = op.result(); - } - return err; + GetFrameCountClosure op(this, count_ptr); + JvmtiHandshake::execute(&op, thread); + return op.result(); } /* end GetFrameCount */ @@ -1923,41 +1853,9 @@ JvmtiEnv::PopFrame(jthread thread) { // location_ptr - pre-checked for null jvmtiError JvmtiEnv::GetFrameLocation(jthread thread, jint depth, jmethodID* method_ptr, jlocation* location_ptr) { - JavaThread* current_thread = JavaThread::current(); - HandleMark hm(current_thread); - - JvmtiVTMSTransitionDisabler disabler(thread); - ThreadsListHandle tlh(current_thread); - - JavaThread* java_thread = nullptr; - oop thread_obj = nullptr; - jvmtiError 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)) { - if (java_thread == nullptr) { // Target virtual thread is unmounted. - err = get_frame_location(thread_obj, depth, method_ptr, location_ptr); - return err; - } - VirtualThreadGetFrameLocationClosure op(this, Handle(current_thread, thread_obj), - depth, method_ptr, location_ptr); - Handshake::execute(&op, java_thread); - return op.result(); - } - - // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a direct handshake for safety. - if (java_thread == JavaThread::current()) { - err = get_frame_location(java_thread, depth, method_ptr, location_ptr); - } else { - // JVMTI get java stack frame location via direct handshake. - GetFrameLocationClosure op(this, depth, method_ptr, location_ptr); - Handshake::execute(&op, java_thread); - err = op.result(); - } - return err; + GetFrameLocationClosure op(this, depth, method_ptr, location_ptr); + JvmtiHandshake::execute(&op, thread); + return op.result(); } /* end GetFrameLocation */ @@ -1984,25 +1882,9 @@ JvmtiEnv::NotifyFramePop(jthread thread, jint depth) { return JVMTI_ERROR_THREAD_NOT_ALIVE; } - if (java_lang_VirtualThread::is_instance(thread_handle())) { - VirtualThreadSetFramePopClosure op(this, thread_handle, state, depth); - MutexLocker mu(current, JvmtiThreadState_lock); - if (java_thread == nullptr || java_thread == current) { - // Target virtual thread is unmounted or current. - op.doit(java_thread, true /* self */); - } else { - Handshake::execute(&op, java_thread); - } - return op.result(); - } - SetFramePopClosure op(this, state, depth); MutexLocker mu(current, JvmtiThreadState_lock); - if (java_thread == current) { - op.doit(java_thread, true /* self */); - } else { - Handshake::execute(&op, java_thread); - } + JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle); return op.result(); } /* end NotifyFramePop */ diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index c402db0cd75..709cc90d561 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -625,8 +625,9 @@ JvmtiEnvBase::get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd bool JvmtiEnvBase::is_vthread_alive(oop vt) { - return java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::NEW && - java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::TERMINATED; + oop cont = java_lang_VirtualThread::continuation(vt); + return !jdk_internal_vm_Continuation::done(cont) && + java_lang_VirtualThread::state(vt) != java_lang_VirtualThread::NEW; } // Return JavaThread if virtual thread is mounted, null otherwise. @@ -1243,9 +1244,6 @@ JvmtiEnvBase::get_frame_count(JavaThread* jt, jint *count_ptr) { jvmtiError JvmtiEnvBase::get_frame_count(oop vthread_oop, jint *count_ptr) { - if (!JvmtiEnvBase::is_vthread_alive(vthread_oop)) { - return JVMTI_ERROR_THREAD_NOT_ALIVE; - } Thread *current_thread = Thread::current(); ResourceMark rm(current_thread); javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(vthread_oop); @@ -1300,9 +1298,6 @@ JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth, jvmtiError JvmtiEnvBase::get_frame_location(oop vthread_oop, jint depth, jmethodID* method_ptr, jlocation* location_ptr) { - if (!JvmtiEnvBase::is_vthread_alive(vthread_oop)) { - return JVMTI_ERROR_THREAD_NOT_ALIVE; - } Thread* current = Thread::current(); ResourceMark rm(current); HandleMark hm(current); @@ -1944,6 +1939,74 @@ MultipleStackTracesCollector::allocate_and_fill_stacks(jint thread_count) { "the last copied frame info must be the last record"); } +// AdapterClosure is to make use of JvmtiUnitedHandshakeClosure objects from +// Handshake::execute() which is unaware of the do_vthread() member functions. +class AdapterClosure : public HandshakeClosure { + JvmtiUnitedHandshakeClosure* _hs_cl; + Handle _target_h; + + public: + AdapterClosure(JvmtiUnitedHandshakeClosure* hs_cl, Handle target_h) + : HandshakeClosure(hs_cl->name()), _hs_cl(hs_cl), _target_h(target_h) {} + + virtual void do_thread(Thread* target) { + if (java_lang_VirtualThread::is_instance(_target_h())) { + _hs_cl->do_vthread(_target_h); // virtual thread + } else { + _hs_cl->do_thread(target); // platform thread + } + } +}; + +// Supports platform and virtual threads. +// JvmtiVTMSTransitionDisabler is always set by this function. +void +JvmtiHandshake::execute(JvmtiUnitedHandshakeClosure* hs_cl, jthread target) { + JavaThread* current = JavaThread::current(); + HandleMark hm(current); + + JvmtiVTMSTransitionDisabler disabler(target); + ThreadsListHandle tlh(current); + JavaThread* java_thread = nullptr; + oop thread_obj = nullptr; + + jvmtiError err = JvmtiEnvBase::get_threadOop_and_JavaThread(tlh.list(), target, &java_thread, &thread_obj); + if (err != JVMTI_ERROR_NONE) { + hs_cl->set_result(err); + return; + } + Handle target_h(current, thread_obj); + execute(hs_cl, &tlh, java_thread, target_h); +} + +// Supports platform and virtual threads. +// A virtual thread is always identified by the target_h oop handle. +// The target_jt is always nullptr for an unmounted virtual thread. +// JvmtiVTMSTransitionDisabler has to be set before call to this function. +void +JvmtiHandshake::execute(JvmtiUnitedHandshakeClosure* hs_cl, ThreadsListHandle* tlh, + JavaThread* target_jt, Handle target_h) { + bool self = target_jt == JavaThread::current(); + + hs_cl->set_self(self); // needed when suspend is required for non-current target thread + + if (java_lang_VirtualThread::is_instance(target_h())) { // virtual thread + if (!JvmtiEnvBase::is_vthread_alive(target_h())) { + return; + } + if (target_jt == nullptr) { // unmounted virtual thread + hs_cl->do_vthread(target_h); // execute handshake closure callback on current thread directly + } + } + if (target_jt != nullptr) { // mounted virtual or platform thread + AdapterClosure acl(hs_cl, target_h); + if (self) { // target platform thread is current + acl.do_thread(target_jt); // execute handshake closure callback on current thread directly + } else { + Handshake::execute(&acl, tlh, target_jt); // delegate to Handshake implementation + } + } +} void VM_GetThreadListStackTraces::doit() { @@ -2335,16 +2398,15 @@ UpdateForPopTopFrameClosure::doit(Thread *target, bool self) { } void -SetFramePopClosure::doit(Thread *target, bool self) { - ResourceMark rm; +SetFramePopClosure::do_thread(Thread *target) { + Thread* current = Thread::current(); JavaThread* java_thread = JavaThread::cast(target); if (java_thread->is_exiting()) { - return; /* JVMTI_ERROR_THREAD_NOT_ALIVE (default) */ + return; // JVMTI_ERROR_THREAD_NOT_ALIVE (default) } - assert(_state->get_thread_or_saved() == java_thread, "Must be"); - if (!self && !java_thread->is_suspended()) { + if (!_self && !java_thread->is_suspended()) { _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED; return; } @@ -2352,6 +2414,8 @@ SetFramePopClosure::doit(Thread *target, bool self) { _result = JVMTI_ERROR_NO_MORE_FRAMES; return; } + assert(_state->get_thread_or_saved() == java_thread, "Must be"); + RegisterMap reg_map(java_thread, RegisterMap::UpdateMap::include, RegisterMap::ProcessFrames::skip, @@ -2360,6 +2424,16 @@ SetFramePopClosure::doit(Thread *target, bool self) { _result = ((JvmtiEnvBase*)_env)->set_frame_pop(_state, jvf, _depth); } +void +SetFramePopClosure::do_vthread(Handle target_h) { + if (!_self && !JvmtiVTSuspender::is_vthread_suspended(target_h())) { + _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED; + return; + } + javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h()); + _result = ((JvmtiEnvBase*)_env)->set_frame_pop(_state, jvf, _depth); +} + void GetOwnedMonitorInfoClosure::do_thread(Thread *target) { JavaThread *jt = JavaThread::cast(target); @@ -2381,22 +2455,11 @@ GetCurrentContendedMonitorClosure::do_thread(Thread *target) { } } -void -VM_VirtualThreadGetStackTrace::doit() { - if (!JvmtiEnvBase::is_vthread_alive(_vthread_h())) { - _result = JVMTI_ERROR_THREAD_NOT_ALIVE; - return; - } - ResourceMark rm; - javaVFrame* jvf = JvmtiEnvBase::get_vthread_jvf(_vthread_h()); - - _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jvf, - _start_depth, _max_count, - _frame_buffer, _count_ptr); -} - void GetStackTraceClosure::do_thread(Thread *target) { + Thread* current = Thread::current(); + ResourceMark rm(current); + JavaThread *jt = JavaThread::cast(target); if (!jt->is_exiting() && jt->threadObj() != nullptr) { _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt, @@ -2405,6 +2468,17 @@ GetStackTraceClosure::do_thread(Thread *target) { } } +void +GetStackTraceClosure::do_vthread(Handle target_h) { + Thread* current = Thread::current(); + ResourceMark rm(current); + + javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h()); + _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jvf, + _start_depth, _max_count, + _frame_buffer, _count_ptr); +} + #ifdef ASSERT void PrintStackTraceClosure::do_thread_impl(Thread *target) { @@ -2454,29 +2528,38 @@ PrintStackTraceClosure::do_thread(Thread *target) { } #endif -void -VM_VirtualThreadGetFrameCount::doit() { - _result = ((JvmtiEnvBase*)_env)->get_frame_count(_vthread_h(), _count_ptr); -} - void GetFrameCountClosure::do_thread(Thread *target) { JavaThread* jt = JavaThread::cast(target); assert(target == jt, "just checking"); + if (!jt->is_exiting() && jt->threadObj() != nullptr) { _result = ((JvmtiEnvBase*)_env)->get_frame_count(jt, _count_ptr); } } +void +GetFrameCountClosure::do_vthread(Handle target_h) { + _result = ((JvmtiEnvBase*)_env)->get_frame_count(target_h(), _count_ptr); +} + void GetFrameLocationClosure::do_thread(Thread *target) { JavaThread *jt = JavaThread::cast(target); + assert(target == jt, "just checking"); + if (!jt->is_exiting() && jt->threadObj() != nullptr) { _result = ((JvmtiEnvBase*)_env)->get_frame_location(jt, _depth, _method_ptr, _location_ptr); } } +void +GetFrameLocationClosure::do_vthread(Handle target_h) { + _result = ((JvmtiEnvBase*)_env)->get_frame_location(target_h(), _depth, + _method_ptr, _location_ptr); +} + void VirtualThreadGetOwnedMonitorInfoClosure::do_thread(Thread *target) { if (!JvmtiEnvBase::is_vthread_alive(_vthread_h())) { @@ -2506,36 +2589,6 @@ VirtualThreadGetThreadClosure::do_thread(Thread *target) { *_carrier_thread_ptr = (jthread)JNIHandles::make_local(jt, carrier_thread); } -void -VirtualThreadGetStackTraceClosure::do_thread(Thread *target) { - assert(target->is_Java_thread(), "just checking"); - if (!JvmtiEnvBase::is_vthread_alive(_vthread_h())) { - _result = JVMTI_ERROR_THREAD_NOT_ALIVE; - return; - } - Thread* cur_thread = Thread::current(); - ResourceMark rm(cur_thread); - HandleMark hm(cur_thread); - - javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(_vthread_h()); - _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jvf, - _start_depth, _max_count, - _frame_buffer, _count_ptr); -} - -void -VirtualThreadGetFrameCountClosure::do_thread(Thread *target) { - assert(target->is_Java_thread(), "just checking"); - _result = ((JvmtiEnvBase*)_env)->get_frame_count(_vthread_h(), _count_ptr); -} - -void -VirtualThreadGetFrameLocationClosure::do_thread(Thread *target) { - assert(target->is_Java_thread(), "just checking"); - _result = ((JvmtiEnvBase*)_env)->get_frame_location(_vthread_h(), _depth, - _method_ptr, _location_ptr); -} - void VirtualThreadGetThreadStateClosure::do_thread(Thread *target) { assert(target->is_Java_thread(), "just checking"); @@ -2558,18 +2611,3 @@ VirtualThreadGetThreadStateClosure::do_thread(Thread *target) { *_state_ptr = state; _result = JVMTI_ERROR_NONE; } - -void -VirtualThreadSetFramePopClosure::doit(Thread *target, bool self) { - if (!JvmtiEnvBase::is_vthread_alive(_vthread_h())) { - _result = JVMTI_ERROR_THREAD_NOT_ALIVE; - return; - } - if (!self && !JvmtiVTSuspender::is_vthread_suspended(_vthread_h())) { - _result = JVMTI_ERROR_THREAD_NOT_SUSPENDED; - return; - } - ResourceMark rm; - javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(_vthread_h()); - _result = ((JvmtiEnvBase*)_env)->set_frame_pop(_state, jvf, _depth); -} diff --git a/src/hotspot/share/prims/jvmtiEnvBase.hpp b/src/hotspot/share/prims/jvmtiEnvBase.hpp index 6fdeb11f406..30f8183924f 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.hpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp @@ -463,6 +463,32 @@ class JvmtiHandshakeClosure : public HandshakeClosure { jvmtiError result() { return _result; } }; +// Used in combination with the JvmtiHandshake class. +// It is intended to support both platform and virtual threads. +class JvmtiUnitedHandshakeClosure : public HandshakeClosure { + protected: + jvmtiError _result; + bool _self; + public: + JvmtiUnitedHandshakeClosure(const char* name) + : HandshakeClosure(name), + _result(JVMTI_ERROR_THREAD_NOT_ALIVE), + _self(false) {} + + void set_result(jvmtiError err) { _result = err; } + void set_self(bool val) { _self = val; } + jvmtiError result() { return _result; } + virtual void do_vthread(Handle target_h) = 0; +}; + +// The JvmtiHandshake supports virtual threads. +class JvmtiHandshake : public Handshake { + public: + static void execute(JvmtiUnitedHandshakeClosure* hs_cl, ThreadsListHandle* tlh, + JavaThread* target_jt, Handle target_h); + static void execute(JvmtiUnitedHandshakeClosure* hs_cl, jthread target); +}; + class SetForceEarlyReturn : public JvmtiHandshakeClosure { private: JvmtiThreadState* _state; @@ -496,7 +522,7 @@ public: }; // HandshakeClosure to set frame pop. -class SetFramePopClosure : public JvmtiHandshakeClosure { +class SetFramePopClosure : public JvmtiUnitedHandshakeClosure { private: JvmtiEnv *_env; JvmtiThreadState* _state; @@ -504,14 +530,12 @@ private: public: SetFramePopClosure(JvmtiEnv *env, JvmtiThreadState* state, jint depth) - : JvmtiHandshakeClosure("SetFramePopClosure"), + : JvmtiUnitedHandshakeClosure("SetFramePopClosure"), _env(env), _state(state), _depth(depth) {} - void do_thread(Thread *target) { - doit(target, false /* self */); - } - void doit(Thread *target, bool self); + void do_thread(Thread *target); + void do_vthread(Handle target_h); }; // HandshakeClosure to get monitor information with stack depth. @@ -574,7 +598,7 @@ public: }; // HandshakeClosure to get stack trace. -class GetStackTraceClosure : public JvmtiHandshakeClosure { +class GetStackTraceClosure : public JvmtiUnitedHandshakeClosure { private: JvmtiEnv *_env; jint _start_depth; @@ -585,13 +609,14 @@ private: public: GetStackTraceClosure(JvmtiEnv *env, jint start_depth, jint max_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr) - : JvmtiHandshakeClosure("GetStackTrace"), + : JvmtiUnitedHandshakeClosure("GetStackTrace"), _env(env), _start_depth(start_depth), _max_count(max_count), _frame_buffer(frame_buffer), _count_ptr(count_ptr) {} void do_thread(Thread *target); + void do_vthread(Handle target_h); }; #ifdef ASSERT @@ -684,54 +709,6 @@ public: jvmtiError result() { return _collector.result(); } }; -class VM_VirtualThreadGetStackTrace : public VM_Operation { -private: - JvmtiEnv *_env; - Handle _vthread_h; - jint _start_depth; - jint _max_count; - jvmtiFrameInfo* _frame_buffer; - jint* _count_ptr; - jvmtiError _result; - -public: - VM_VirtualThreadGetStackTrace(JvmtiEnv *env, Handle vthread_h, - jint start_depth, jint max_count, - jvmtiFrameInfo* frame_buffer, jint* count_ptr) - : _env(env), - _vthread_h(vthread_h), - _start_depth(start_depth), - _max_count(max_count), - _frame_buffer(frame_buffer), - _count_ptr(count_ptr), - _result(JVMTI_ERROR_NONE) - {} - - VMOp_Type type() const { return VMOp_VirtualThreadGetStackTrace; } - void doit(); - jvmtiError result() { return _result; } -}; - -class VM_VirtualThreadGetFrameCount : public VM_Operation { -private: - JvmtiEnv *_env; - Handle _vthread_h; - jint* _count_ptr; - jvmtiError _result; - -public: - VM_VirtualThreadGetFrameCount(JvmtiEnv *env, Handle vthread_h, jint* count_ptr) - : _env(env), - _vthread_h(vthread_h), - _count_ptr(count_ptr), - _result(JVMTI_ERROR_NONE) - {} - - VMOp_Type type() const { return VMOp_VirtualThreadGetFrameCount; } - void doit(); - jvmtiError result() { return _result; } -}; - // HandshakeClosure to get single stack trace. class GetSingleStackTraceClosure : public HandshakeClosure { private: @@ -753,21 +730,22 @@ public: }; // HandshakeClosure to count stack frames. -class GetFrameCountClosure : public JvmtiHandshakeClosure { +class GetFrameCountClosure : public JvmtiUnitedHandshakeClosure { private: JvmtiEnv *_env; jint *_count_ptr; public: GetFrameCountClosure(JvmtiEnv *env, jint *count_ptr) - : JvmtiHandshakeClosure("GetFrameCount"), + : JvmtiUnitedHandshakeClosure("GetFrameCount"), _env(env), _count_ptr(count_ptr) {} void do_thread(Thread *target); + void do_vthread(Handle target_h); }; // HandshakeClosure to get frame location. -class GetFrameLocationClosure : public JvmtiHandshakeClosure { +class GetFrameLocationClosure : public JvmtiUnitedHandshakeClosure { private: JvmtiEnv *_env; jint _depth; @@ -777,12 +755,13 @@ private: public: GetFrameLocationClosure(JvmtiEnv *env, jint depth, jmethodID* method_ptr, jlocation* location_ptr) - : JvmtiHandshakeClosure("GetFrameLocation"), + : JvmtiUnitedHandshakeClosure("GetFrameLocation"), _env(env), _depth(depth), _method_ptr(method_ptr), _location_ptr(location_ptr) {} void do_thread(Thread *target); + void do_vthread(Handle target_h); }; // HandshakeClosure to get virtual thread monitor information with stack depth. @@ -825,77 +804,6 @@ public: jvmtiError result() { return _result; } }; -// HandshakeClosure to get virtual thread stack trace at safepoint. -class VirtualThreadGetStackTraceClosure : public HandshakeClosure { -private: - JvmtiEnv *_env; - Handle _vthread_h; - jint _start_depth; - jint _max_count; - jvmtiFrameInfo *_frame_buffer; - jint *_count_ptr; - jvmtiError _result; - -public: - VirtualThreadGetStackTraceClosure(JvmtiEnv *env, Handle vthread_h, - jint start_depth, jint max_count, - jvmtiFrameInfo* frame_buffer, jint* count_ptr) - : HandshakeClosure("VirtualThreadGetStackTrace"), - _env(env), - _vthread_h(vthread_h), - _start_depth(start_depth), - _max_count(max_count), - _frame_buffer(frame_buffer), - _count_ptr(count_ptr), - _result(JVMTI_ERROR_NONE) {} - - void do_thread(Thread *target); - jvmtiError result() { return _result; } -}; - -// HandshakeClosure to count virtual thread stack frames at safepoint. -class VirtualThreadGetFrameCountClosure : public HandshakeClosure { -private: - JvmtiEnv *_env; - Handle _vthread_h; - jint *_count_ptr; - jvmtiError _result; - -public: - VirtualThreadGetFrameCountClosure(JvmtiEnv *env, Handle vthread_h, jint *count_ptr) - : HandshakeClosure("VirtualThreadGetFrameCount"), - _env(env), _vthread_h(vthread_h), _count_ptr(count_ptr), - _result(JVMTI_ERROR_NONE) {} - - void do_thread(Thread *target); - jvmtiError result() { return _result; } -}; - -// HandshakeClosure get to virtual thread frame location at safepoint. -class VirtualThreadGetFrameLocationClosure : public HandshakeClosure { -private: - JvmtiEnv *_env; - Handle _vthread_h; - jint _depth; - jmethodID* _method_ptr; - jlocation* _location_ptr; - jvmtiError _result; - -public: - VirtualThreadGetFrameLocationClosure(JvmtiEnv *env, Handle vthread_h, jint depth, - jmethodID* method_ptr, jlocation* location_ptr) - : HandshakeClosure("VirtualThreadGetFrameLocation"), - _env(env), - _vthread_h(vthread_h), - _depth(depth), - _method_ptr(method_ptr), - _location_ptr(location_ptr), - _result(JVMTI_ERROR_NONE) {} - - void do_thread(Thread *target); - jvmtiError result() { return _result; } -}; - // HandshakeClosure to get virtual thread state at safepoint. class VirtualThreadGetThreadStateClosure : public HandshakeClosure { private: @@ -914,28 +822,6 @@ public: jvmtiError result() { return _result; } }; -// HandshakeClosure to set frame pop for a virtual thread. -class VirtualThreadSetFramePopClosure : public JvmtiHandshakeClosure { -private: - JvmtiEnv *_env; - Handle _vthread_h; - JvmtiThreadState* _state; - jint _depth; - -public: - VirtualThreadSetFramePopClosure(JvmtiEnv *env, Handle vthread_h, JvmtiThreadState* state, jint depth) - : JvmtiHandshakeClosure("VirtualThreadSetFramePopClosure"), - _env(env), - _vthread_h(vthread_h), - _state(state), - _depth(depth) {} - - void do_thread(Thread *target) { - doit(target, false /* self */); - } - void doit(Thread *target, bool self); -}; - // ResourceTracker // diff --git a/src/hotspot/share/runtime/vmOperation.hpp b/src/hotspot/share/runtime/vmOperation.hpp index 147cf9dc977..d6fac3f14f1 100644 --- a/src/hotspot/share/runtime/vmOperation.hpp +++ b/src/hotspot/share/runtime/vmOperation.hpp @@ -81,8 +81,6 @@ template(GetObjectMonitorUsage) \ template(GetAllStackTraces) \ template(GetThreadListStackTraces) \ - template(VirtualThreadGetStackTrace) \ - template(VirtualThreadGetFrameCount) \ template(ChangeBreakpoints) \ template(GetOrSetLocal) \ template(VirtualThreadGetOrSetLocal) \