8308614: Enabling JVMTI ClassLoad event slows down vthread creation by factor 10

Reviewed-by: dcubed, cjplummer, amenkov
This commit is contained in:
Serguei Spitsyn 2023-12-01 20:54:13 +00:00
parent 1839433bff
commit 42af8ce1f6
2 changed files with 22 additions and 11 deletions

View File

@ -52,6 +52,7 @@ static const int UNKNOWN_STACK_DEPTH = -99;
//
JvmtiThreadState *JvmtiThreadState::_head = nullptr;
bool JvmtiThreadState::_seen_interp_only_mode = false;
JvmtiThreadState::JvmtiThreadState(JavaThread* thread, oop thread_oop)
: _thread_event_enable() {
@ -553,11 +554,14 @@ JvmtiVTMSTransitionDisabler::VTMS_vthread_start(jobject vthread) {
assert(!thread->is_in_VTMS_transition(), "sanity check");
assert(!thread->is_in_tmp_VTMS_transition(), "sanity check");
JvmtiEventController::thread_started(thread);
if (JvmtiExport::can_support_virtual_threads()) {
if (JvmtiExport::should_post_vthread_start()) {
JvmtiExport::post_vthread_start(vthread);
}
// If interp_only_mode has been enabled then we must eagerly create JvmtiThreadState
// objects for globally enabled virtual thread filtered events. Otherwise,
// it is an important optimization to create JvmtiThreadState objects lazily.
if (JvmtiThreadState::seen_interp_only_mode()) {
JvmtiEventController::thread_started(thread);
}
if (JvmtiExport::should_post_vthread_start()) {
JvmtiExport::post_vthread_start(vthread);
}
// post VirtualThreadMount event after VirtualThreadStart
if (JvmtiExport::should_post_vthread_mount()) {
@ -576,10 +580,8 @@ JvmtiVTMSTransitionDisabler::VTMS_vthread_end(jobject vthread) {
if (JvmtiExport::should_post_vthread_unmount()) {
JvmtiExport::post_vthread_unmount(vthread);
}
if (JvmtiExport::can_support_virtual_threads()) {
if (JvmtiExport::should_post_vthread_end()) {
JvmtiExport::post_vthread_end(vthread);
}
if (JvmtiExport::should_post_vthread_end()) {
JvmtiExport::post_vthread_end(vthread);
}
VTMS_unmount_begin(vthread, /* last_unmount */ true);
if (thread->jvmti_thread_state() != nullptr) {
@ -629,9 +631,10 @@ JvmtiVTMSTransitionDisabler::VTMS_mount_end(jobject vthread) {
thread->rebind_to_jvmti_thread_state_of(vt);
{
JvmtiThreadState* state = thread->jvmti_thread_state();
if (state != nullptr && state->is_pending_interp_only_mode()) {
MutexLocker mu(JvmtiThreadState_lock);
JvmtiThreadState* state = thread->jvmti_thread_state();
state = thread->jvmti_thread_state();
if (state != nullptr && state->is_pending_interp_only_mode()) {
JvmtiEventController::enter_interp_only_mode();
}
@ -770,6 +773,7 @@ void JvmtiThreadState::add_env(JvmtiEnvBase *env) {
void JvmtiThreadState::enter_interp_only_mode() {
assert(_thread != nullptr, "sanity check");
_seen_interp_only_mode = true;
_thread->increment_interp_only_mode();
invalidate_cur_stack_depth();
}

View File

@ -240,6 +240,8 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
inline JvmtiEnvThreadState* head_env_thread_state();
inline void set_head_env_thread_state(JvmtiEnvThreadState* ets);
static bool _seen_interp_only_mode; // interp_only_mode was requested at least once
public:
~JvmtiThreadState();
@ -259,6 +261,11 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
static void periodic_clean_up();
// Return true if any thread has entered interp_only_mode at any point during the JVMs execution.
static bool seen_interp_only_mode() {
return _seen_interp_only_mode;
}
void add_env(JvmtiEnvBase *env);
// The pending_interp_only_mode is set when the interp_only_mode is triggered.