--- old/src/hotspot/share/prims/jvmtiEnv.cpp 2020-04-10 16:57:03.513254900 +0900 +++ new/src/hotspot/share/prims/jvmtiEnv.cpp 2020-04-10 16:57:03.196471800 +0900 @@ -1201,21 +1201,19 @@ jvmtiError JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - JavaThread* calling_thread = JavaThread::current(); // growable array of jvmti monitors info on the C-heap GrowableArray *owned_monitors_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(1, true); // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a vm-safepoint-op for safety. - if (java_thread == calling_thread) { - err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); + // thread. All other usage needs to use a direct handshake for safety. + if (java_thread == JavaThread::current()) { + err = get_owned_monitors(java_thread, owned_monitors_list); } else { - // JVMTI get monitors info at safepoint. Do not require target thread to - // be suspended. - VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list); - VMThread::execute(&op); + // get owned monitors info with handshake + GetOwnedMonitorInfoClosure op(this, owned_monitors_list); + Handshake::execute_direct(&op, java_thread); err = op.result(); } jint owned_monitor_count = owned_monitors_list->length(); @@ -1247,21 +1245,19 @@ jvmtiError JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - JavaThread* calling_thread = JavaThread::current(); // growable array of jvmti monitors info on the C-heap GrowableArray *owned_monitors_list = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(1, true); // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a vm-safepoint-op for safety. - if (java_thread == calling_thread) { - err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list); + // thread. All other usage needs to use a direct handshake for safety. + if (java_thread == JavaThread::current()) { + err = get_owned_monitors(java_thread, owned_monitors_list); } else { - // JVMTI get owned monitors info at safepoint. Do not require target thread to - // be suspended. - VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list); - VMThread::execute(&op); + // get owned monitors info with handshake + GetOwnedMonitorInfoClosure op(this, owned_monitors_list); + Handshake::execute_direct(&op, java_thread); err = op.result(); } @@ -1296,16 +1292,15 @@ jvmtiError JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) { jvmtiError err = JVMTI_ERROR_NONE; - JavaThread* calling_thread = JavaThread::current(); // It is only safe to perform the direct operation on the current - // thread. All other usage needs to use a vm-safepoint-op for safety. - if (java_thread == calling_thread) { - err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr); + // thread. All other usage needs to use a direct handshake for safety. + if (java_thread == JavaThread::current()) { + err = get_current_contended_monitor(java_thread, monitor_ptr); } else { - // get contended monitor information at safepoint. - VM_GetCurrentContendedMonitor op(this, calling_thread, java_thread, monitor_ptr); - VMThread::execute(&op); + // get contended monitor information with handshake + GetCurrentContendedMonitorClosure op(this, monitor_ptr); + Handshake::execute_direct(&op, java_thread); err = op.result(); } return err; --- old/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-04-10 16:57:04.627370700 +0900 +++ new/src/hotspot/share/prims/jvmtiEnvBase.cpp 2020-04-10 16:57:04.314846700 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -647,13 +647,11 @@ jvmtiError -JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) { -#ifdef ASSERT - uint32_t debug_bits = 0; -#endif - assert((SafepointSynchronize::is_at_safepoint() || - java_thread->is_thread_fully_suspended(false, &debug_bits)), - "at safepoint or target thread is suspended"); +JvmtiEnvBase::get_current_contended_monitor(JavaThread *java_thread, jobject *monitor_ptr) { + JavaThread *current_jt = JavaThread::current(); + assert(current_jt == java_thread || + current_jt == java_thread->active_handshaker(), + "call by myself or at direct handshake"); oop obj = NULL; ObjectMonitor *mon = java_thread->current_waiting_monitor(); if (mon == NULL) { @@ -675,23 +673,21 @@ *monitor_ptr = NULL; } else { HandleMark hm; - Handle hobj(Thread::current(), obj); - *monitor_ptr = jni_reference(calling_thread, hobj); + Handle hobj(current_jt, obj); + *monitor_ptr = jni_reference(current_jt, hobj); } return JVMTI_ERROR_NONE; } jvmtiError -JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread, +JvmtiEnvBase::get_owned_monitors(JavaThread* java_thread, GrowableArray *owned_monitors_list) { jvmtiError err = JVMTI_ERROR_NONE; -#ifdef ASSERT - uint32_t debug_bits = 0; -#endif - assert((SafepointSynchronize::is_at_safepoint() || - java_thread->is_thread_fully_suspended(false, &debug_bits)), - "at safepoint or target thread is suspended"); + JavaThread *current_jt = JavaThread::current(); + assert(current_jt == java_thread || + current_jt == java_thread->active_handshaker(), + "call by myself or at direct handshake"); if (java_thread->has_last_Java_frame()) { ResourceMark rm; @@ -703,7 +699,7 @@ jvf = jvf->java_sender()) { if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) { // check for stack too deep // add locked objects for this frame into list - err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1); + err = get_locked_objects_in_frame(JavaThread::current(), java_thread, jvf, owned_monitors_list, depth-1); if (err != JVMTI_ERROR_NONE) { return err; } @@ -712,7 +708,7 @@ } // Get off stack monitors. (e.g. acquired via jni MonitorEnter). - JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this); + JvmtiMonitorClosure jmc(java_thread, JavaThread::current(), owned_monitors_list, this); ObjectSynchronizer::monitors_iterate(&jmc); err = jmc.error(); @@ -1542,24 +1538,13 @@ } void -VM_GetOwnedMonitorInfo::doit() { - _result = JVMTI_ERROR_THREAD_NOT_ALIVE; - ThreadsListHandle tlh; - if (_java_thread != NULL && tlh.includes(_java_thread) - && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { - _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread, - _owned_monitors_list); - } +GetOwnedMonitorInfoClosure::do_thread(Thread *target) { + _result = ((JvmtiEnvBase *)_env)->get_owned_monitors((JavaThread *)target, _owned_monitors_list); } void -VM_GetCurrentContendedMonitor::doit() { - _result = JVMTI_ERROR_THREAD_NOT_ALIVE; - ThreadsListHandle tlh; - if (_java_thread != NULL && tlh.includes(_java_thread) - && !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) { - _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr); - } +GetCurrentContendedMonitorClosure::do_thread(Thread *target) { + _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor((JavaThread *)target, _owned_monitor_ptr); } void --- old/src/hotspot/share/prims/jvmtiEnvBase.hpp 2020-04-10 16:57:05.720272400 +0900 +++ new/src/hotspot/share/prims/jvmtiEnvBase.hpp 2020-04-10 16:57:05.412721100 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -301,10 +301,9 @@ jvmtiError get_stack_trace(JavaThread *java_thread, jint stack_depth, jint max_count, jvmtiFrameInfo* frame_buffer, jint* count_ptr); - jvmtiError get_current_contended_monitor(JavaThread *calling_thread, - JavaThread *java_thread, + jvmtiError get_current_contended_monitor(JavaThread *java_thread, jobject *monitor_ptr); - jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread, + jvmtiError get_owned_monitors(JavaThread* java_thread, GrowableArray *owned_monitors_list); jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread, jvalue value, TosState tos, Handle* ret_ob_h); @@ -376,27 +375,19 @@ }; -// VM operation to get monitor information with stack depth. -class VM_GetOwnedMonitorInfo : public VM_Operation { +// HandshakeClosure to get monitor information with stack depth. +class GetOwnedMonitorInfoClosure : public HandshakeClosure { private: JvmtiEnv *_env; - JavaThread* _calling_thread; - JavaThread *_java_thread; jvmtiError _result; GrowableArray *_owned_monitors_list; public: - VM_GetOwnedMonitorInfo(JvmtiEnv* env, JavaThread* calling_thread, - JavaThread* java_thread, - GrowableArray* owned_monitor_list) { - _env = env; - _calling_thread = calling_thread; - _java_thread = java_thread; - _owned_monitors_list = owned_monitor_list; - _result = JVMTI_ERROR_NONE; - } - VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; } - void doit(); + GetOwnedMonitorInfoClosure(JvmtiEnv* env, + GrowableArray* owned_monitor_list) + : HandshakeClosure("GetOwnedMonitorInfo"), + _env(env), _result(JVMTI_ERROR_NONE), _owned_monitors_list(owned_monitor_list) {} + void do_thread(Thread *target); jvmtiError result() { return _result; } }; @@ -425,25 +416,20 @@ }; -// VM operation to get current contended monitor. -class VM_GetCurrentContendedMonitor : public VM_Operation { +// HandshakeClosure to get current contended monitor. +class GetCurrentContendedMonitorClosure : public HandshakeClosure { private: JvmtiEnv *_env; - JavaThread *_calling_thread; - JavaThread *_java_thread; jobject *_owned_monitor_ptr; jvmtiError _result; public: - VM_GetCurrentContendedMonitor(JvmtiEnv *env, JavaThread *calling_thread, JavaThread *java_thread, jobject *mon_ptr) { - _env = env; - _calling_thread = calling_thread; - _java_thread = java_thread; - _owned_monitor_ptr = mon_ptr; - } - VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; } + GetCurrentContendedMonitorClosure(JvmtiEnv *env, jobject *mon_ptr) + : HandshakeClosure("GetOneCurrentContendedMonitor"), + _env(env), _owned_monitor_ptr(mon_ptr), + _result(JVMTI_ERROR_THREAD_NOT_ALIVE) {} jvmtiError result() { return _result; } - void doit(); + void do_thread(Thread *target); }; // VM operation to get stack trace at safepoint. --- old/src/hotspot/share/runtime/vmOperations.hpp 2020-04-10 16:57:06.797887800 +0900 +++ new/src/hotspot/share/runtime/vmOperations.hpp 2020-04-10 16:57:06.486652100 +0900 @@ -80,9 +80,7 @@ template(RedefineClasses) \ template(UpdateForPopTopFrame) \ template(SetFramePop) \ - template(GetOwnedMonitorInfo) \ template(GetObjectMonitorUsage) \ - template(GetCurrentContendedMonitor) \ template(GetStackTrace) \ template(GetMultipleStackTraces) \ template(GetAllStackTraces) \