8319244: implement JVMTI handshakes support for virtual threads
Reviewed-by: pchilanomate, amenkov
This commit is contained in:
parent
46e4028adf
commit
839dd65366
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -81,8 +81,6 @@
|
||||
template(GetObjectMonitorUsage) \
|
||||
template(GetAllStackTraces) \
|
||||
template(GetThreadListStackTraces) \
|
||||
template(VirtualThreadGetStackTrace) \
|
||||
template(VirtualThreadGetFrameCount) \
|
||||
template(ChangeBreakpoints) \
|
||||
template(GetOrSetLocal) \
|
||||
template(VirtualThreadGetOrSetLocal) \
|
||||
|
Loading…
Reference in New Issue
Block a user