8328285: GetOwnedMonitorInfo functions should use JvmtiHandshake
Reviewed-by: pchilanomate, lmesnik
This commit is contained in:
parent
0efd9dc09b
commit
4d36c4adcc
@ -1363,32 +1363,17 @@ JvmtiEnv::GetOwnedMonitorInfo(jthread thread, jint* owned_monitor_count_ptr, job
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java_lang_VirtualThread::is_instance(thread_oop)) {
|
if (java_thread != nullptr) {
|
||||||
// There is no monitor info to collect if target virtual thread is unmounted.
|
Handle thread_handle(calling_thread, thread_oop);
|
||||||
if (java_thread != nullptr) {
|
|
||||||
VirtualThreadGetOwnedMonitorInfoClosure op(this,
|
|
||||||
Handle(calling_thread, thread_oop),
|
|
||||||
owned_monitors_list);
|
|
||||||
Handshake::execute(&op, java_thread);
|
|
||||||
err = op.result();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EscapeBarrier eb(true, calling_thread, java_thread);
|
EscapeBarrier eb(true, calling_thread, java_thread);
|
||||||
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
||||||
delete owned_monitors_list;
|
delete owned_monitors_list;
|
||||||
return JVMTI_ERROR_OUT_OF_MEMORY;
|
return JVMTI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
// get owned monitors info with handshake
|
||||||
if (java_thread == calling_thread) {
|
GetOwnedMonitorInfoClosure op(this, calling_thread, owned_monitors_list);
|
||||||
// It is only safe to make a direct call on the current thread.
|
JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
|
||||||
// All other usage needs to use a direct handshake for safety.
|
err = op.result();
|
||||||
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
|
|
||||||
} else {
|
|
||||||
// get owned monitors info with handshake
|
|
||||||
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
|
|
||||||
Handshake::execute(&op, java_thread);
|
|
||||||
err = op.result();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jint owned_monitor_count = owned_monitors_list->length();
|
jint owned_monitor_count = owned_monitors_list->length();
|
||||||
@ -1436,33 +1421,19 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(jthread thread, jint* monitor_info_count
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (java_lang_VirtualThread::is_instance(thread_oop)) {
|
if (java_thread != nullptr) {
|
||||||
// There is no monitor info to collect if target virtual thread is unmounted.
|
Handle thread_handle(calling_thread, thread_oop);
|
||||||
if (java_thread != nullptr) {
|
|
||||||
VirtualThreadGetOwnedMonitorInfoClosure op(this,
|
|
||||||
Handle(calling_thread, thread_oop),
|
|
||||||
owned_monitors_list);
|
|
||||||
Handshake::execute(&op, java_thread);
|
|
||||||
err = op.result();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EscapeBarrier eb(true, calling_thread, java_thread);
|
EscapeBarrier eb(true, calling_thread, java_thread);
|
||||||
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
||||||
delete owned_monitors_list;
|
delete owned_monitors_list;
|
||||||
return JVMTI_ERROR_OUT_OF_MEMORY;
|
return JVMTI_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
// get owned monitors info with handshake
|
||||||
if (java_thread == calling_thread) {
|
GetOwnedMonitorInfoClosure op(this, calling_thread, owned_monitors_list);
|
||||||
// It is only safe to make a direct call on the current thread.
|
JvmtiHandshake::execute(&op, &tlh, java_thread, thread_handle);
|
||||||
// All other usage needs to use a direct handshake for safety.
|
err = op.result();
|
||||||
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
|
|
||||||
} else {
|
|
||||||
// get owned monitors info with handshake
|
|
||||||
GetOwnedMonitorInfoClosure op(calling_thread, this, owned_monitors_list);
|
|
||||||
Handshake::execute(&op, java_thread);
|
|
||||||
err = op.result();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jint owned_monitor_count = owned_monitors_list->length();
|
jint owned_monitor_count = owned_monitors_list->length();
|
||||||
if (err == JVMTI_ERROR_NONE) {
|
if (err == JVMTI_ERROR_NONE) {
|
||||||
if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),
|
if ((err = allocate(owned_monitor_count * sizeof(jvmtiMonitorStackDepthInfo),
|
||||||
|
@ -1997,11 +1997,14 @@ JvmtiHandshake::execute(JvmtiUnitedHandshakeClosure* hs_cl, jthread target) {
|
|||||||
void
|
void
|
||||||
JvmtiHandshake::execute(JvmtiUnitedHandshakeClosure* hs_cl, ThreadsListHandle* tlh,
|
JvmtiHandshake::execute(JvmtiUnitedHandshakeClosure* hs_cl, ThreadsListHandle* tlh,
|
||||||
JavaThread* target_jt, Handle target_h) {
|
JavaThread* target_jt, Handle target_h) {
|
||||||
|
bool is_virtual = java_lang_VirtualThread::is_instance(target_h());
|
||||||
bool self = target_jt == JavaThread::current();
|
bool self = target_jt == JavaThread::current();
|
||||||
|
|
||||||
hs_cl->set_self(self); // needed when suspend is required for non-current target thread
|
hs_cl->set_target_jt(target_jt); // can be needed in the virtual thread case
|
||||||
|
hs_cl->set_is_virtual(is_virtual); // can be needed in the virtual thread case
|
||||||
|
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 (is_virtual) { // virtual thread
|
||||||
if (!JvmtiEnvBase::is_vthread_alive(target_h())) {
|
if (!JvmtiEnvBase::is_vthread_alive(target_h())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2466,6 +2469,23 @@ GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GetOwnedMonitorInfoClosure::do_vthread(Handle target_h) {
|
||||||
|
assert(_target_jt != nullptr, "sanity check");
|
||||||
|
Thread* current = Thread::current();
|
||||||
|
ResourceMark rm(current); // vframes are resource allocated
|
||||||
|
HandleMark hm(current);
|
||||||
|
|
||||||
|
javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(target_h());
|
||||||
|
|
||||||
|
if (!_target_jt->is_exiting() && _target_jt->threadObj() != nullptr) {
|
||||||
|
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
|
||||||
|
_target_jt,
|
||||||
|
jvf,
|
||||||
|
_owned_monitors_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
|
GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
|
||||||
JavaThread *jt = JavaThread::cast(target);
|
JavaThread *jt = JavaThread::cast(target);
|
||||||
@ -2582,27 +2602,6 @@ GetFrameLocationClosure::do_vthread(Handle target_h) {
|
|||||||
_method_ptr, _location_ptr);
|
_method_ptr, _location_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
VirtualThreadGetOwnedMonitorInfoClosure::do_thread(Thread *target) {
|
|
||||||
if (!JvmtiEnvBase::is_vthread_alive(_vthread_h())) {
|
|
||||||
_result = JVMTI_ERROR_THREAD_NOT_ALIVE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JavaThread* java_thread = JavaThread::cast(target);
|
|
||||||
Thread* cur_thread = Thread::current();
|
|
||||||
ResourceMark rm(cur_thread);
|
|
||||||
HandleMark hm(cur_thread);
|
|
||||||
|
|
||||||
javaVFrame *jvf = JvmtiEnvBase::get_vthread_jvf(_vthread_h());
|
|
||||||
|
|
||||||
if (!java_thread->is_exiting() && java_thread->threadObj() != nullptr) {
|
|
||||||
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors(java_thread,
|
|
||||||
java_thread,
|
|
||||||
jvf,
|
|
||||||
_owned_monitors_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VirtualThreadGetThreadClosure::do_thread(Thread *target) {
|
VirtualThreadGetThreadClosure::do_thread(Thread *target) {
|
||||||
assert(target->is_Java_thread(), "just checking");
|
assert(target->is_Java_thread(), "just checking");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -471,14 +471,21 @@ class JvmtiHandshakeClosure : public HandshakeClosure {
|
|||||||
class JvmtiUnitedHandshakeClosure : public HandshakeClosure {
|
class JvmtiUnitedHandshakeClosure : public HandshakeClosure {
|
||||||
protected:
|
protected:
|
||||||
jvmtiError _result;
|
jvmtiError _result;
|
||||||
|
// the fields below are set by the JvmtiHandshake::execute
|
||||||
|
JavaThread* _target_jt;
|
||||||
|
bool _is_virtual;
|
||||||
bool _self;
|
bool _self;
|
||||||
public:
|
public:
|
||||||
JvmtiUnitedHandshakeClosure(const char* name)
|
JvmtiUnitedHandshakeClosure(const char* name)
|
||||||
: HandshakeClosure(name),
|
: HandshakeClosure(name),
|
||||||
_result(JVMTI_ERROR_THREAD_NOT_ALIVE),
|
_result(JVMTI_ERROR_THREAD_NOT_ALIVE),
|
||||||
|
_target_jt(nullptr),
|
||||||
|
_is_virtual(false),
|
||||||
_self(false) {}
|
_self(false) {}
|
||||||
|
|
||||||
void set_result(jvmtiError err) { _result = err; }
|
void set_result(jvmtiError err) { _result = err; }
|
||||||
|
void set_target_jt(JavaThread* target_jt) { _target_jt = target_jt; }
|
||||||
|
void set_is_virtual(bool val) { _is_virtual = val; }
|
||||||
void set_self(bool val) { _self = val; }
|
void set_self(bool val) { _self = val; }
|
||||||
jvmtiError result() { return _result; }
|
jvmtiError result() { return _result; }
|
||||||
virtual void do_vthread(Handle target_h) = 0;
|
virtual void do_vthread(Handle target_h) = 0;
|
||||||
@ -542,20 +549,23 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// HandshakeClosure to get monitor information with stack depth.
|
// HandshakeClosure to get monitor information with stack depth.
|
||||||
class GetOwnedMonitorInfoClosure : public JvmtiHandshakeClosure {
|
class GetOwnedMonitorInfoClosure : public JvmtiUnitedHandshakeClosure {
|
||||||
private:
|
private:
|
||||||
JavaThread* _calling_thread;
|
|
||||||
JvmtiEnv *_env;
|
JvmtiEnv *_env;
|
||||||
|
JavaThread* _calling_thread;
|
||||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
|
GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GetOwnedMonitorInfoClosure(JavaThread* calling_thread, JvmtiEnv* env,
|
GetOwnedMonitorInfoClosure(JvmtiEnv* env,
|
||||||
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list)
|
JavaThread* calling_thread,
|
||||||
: JvmtiHandshakeClosure("GetOwnedMonitorInfo"),
|
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list)
|
||||||
_calling_thread(calling_thread),
|
: JvmtiUnitedHandshakeClosure("GetOwnedMonitorInfo"),
|
||||||
_env(env),
|
_env(env),
|
||||||
_owned_monitors_list(owned_monitor_list) {}
|
_calling_thread(calling_thread),
|
||||||
|
_owned_monitors_list(owned_monitors_list) {}
|
||||||
|
|
||||||
void do_thread(Thread *target);
|
void do_thread(Thread *target);
|
||||||
|
void do_vthread(Handle target_h);
|
||||||
};
|
};
|
||||||
|
|
||||||
// VM operation to get object monitor usage.
|
// VM operation to get object monitor usage.
|
||||||
@ -767,28 +777,6 @@ public:
|
|||||||
void do_vthread(Handle target_h);
|
void do_vthread(Handle target_h);
|
||||||
};
|
};
|
||||||
|
|
||||||
// HandshakeClosure to get virtual thread monitor information with stack depth.
|
|
||||||
class VirtualThreadGetOwnedMonitorInfoClosure : public HandshakeClosure {
|
|
||||||
private:
|
|
||||||
JvmtiEnv *_env;
|
|
||||||
Handle _vthread_h;
|
|
||||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
|
|
||||||
jvmtiError _result;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VirtualThreadGetOwnedMonitorInfoClosure(JvmtiEnv* env,
|
|
||||||
Handle vthread_h,
|
|
||||||
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list)
|
|
||||||
: HandshakeClosure("VirtualThreadGetOwnedMonitorInfo"),
|
|
||||||
_env(env),
|
|
||||||
_vthread_h(vthread_h),
|
|
||||||
_owned_monitors_list(owned_monitors_list),
|
|
||||||
_result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
|
|
||||||
|
|
||||||
void do_thread(Thread *target);
|
|
||||||
jvmtiError result() { return _result; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// HandshakeClosure to get virtual thread thread at safepoint.
|
// HandshakeClosure to get virtual thread thread at safepoint.
|
||||||
class VirtualThreadGetThreadClosure : public HandshakeClosure {
|
class VirtualThreadGetThreadClosure : public HandshakeClosure {
|
||||||
private:
|
private:
|
||||||
|
@ -75,7 +75,8 @@ bool EscapeBarrier::deoptimize_objects(int d1, int d2) {
|
|||||||
// These frames are about to be removed. We must not interfere with that and signal failure.
|
// These frames are about to be removed. We must not interfere with that and signal failure.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deoptee_thread()->has_last_Java_frame()) {
|
if (deoptee_thread()->has_last_Java_frame() &&
|
||||||
|
deoptee_thread()->last_continuation() == nullptr) {
|
||||||
assert(calling_thread() == Thread::current(), "should be");
|
assert(calling_thread() == Thread::current(), "should be");
|
||||||
KeepStackGCProcessedMark ksgcpm(deoptee_thread());
|
KeepStackGCProcessedMark ksgcpm(deoptee_thread());
|
||||||
ResourceMark rm(calling_thread());
|
ResourceMark rm(calling_thread());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user