8242428: JVMTI thread operations should use Thread-Local Handshake

Reviewed-by: dcubed, sspitsyn, dholmes
This commit is contained in:
Yasumasa Suenaga 2020-07-11 23:28:02 +09:00
parent 09510a15a1
commit faf4d7ccb7
6 changed files with 308 additions and 67 deletions

View file

@ -816,13 +816,14 @@ JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
#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");
Thread *current_thread = Thread::current();
assert(current_thread == java_thread ||
SafepointSynchronize::is_at_safepoint() ||
current_thread == java_thread->active_handshaker(),
"call by myself / at safepoint / at handshake");
int count = 0;
if (java_thread->has_last_Java_frame()) {
RegisterMap reg_map(java_thread);
Thread* current_thread = Thread::current();
ResourceMark rm(current_thread);
javaVFrame *jvf = java_thread->last_java_vframe(&reg_map);
HandleMark hm(current_thread);
@ -1154,8 +1155,14 @@ struct StackInfoNode {
// Note that either or both of thr and thread_oop
// may be null if the thread is new or has exited.
void
VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
MultipleStackTracesCollector::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
#ifdef ASSERT
Thread *current_thread = Thread::current();
assert(current_thread == thr ||
SafepointSynchronize::is_at_safepoint() ||
current_thread == thr->active_handshaker(),
"call by myself / at safepoint / at handshake");
#endif
jint state = 0;
struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode);
@ -1199,7 +1206,7 @@ VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_o
// Based on the stack information in the linked list, allocate memory
// block to return and fill it from the info in the linked list.
void
VM_GetMultipleStackTraces::allocate_and_fill_stacks(jint thread_count) {
MultipleStackTracesCollector::allocate_and_fill_stacks(jint thread_count) {
// do I need to worry about alignment issues?
jlong alloc_size = thread_count * sizeof(jvmtiStackInfo)
+ _frame_count_total * sizeof(jvmtiFrameInfo);
@ -1248,14 +1255,27 @@ VM_GetThreadListStackTraces::doit() {
// only return an error from here if we didn't get a valid
// thread_oop.
if (thread_oop == NULL) {
set_result(err);
_collector.set_result(err);
return;
}
// We have a valid thread_oop.
}
fill_frames(jt, java_thread, thread_oop);
_collector.fill_frames(jt, java_thread, thread_oop);
}
_collector.allocate_and_fill_stacks(_thread_count);
}
void
GetSingleStackTraceClosure::do_thread(Thread *target) {
assert(target->is_Java_thread(), "just checking");
JavaThread *jt = (JavaThread *)target;
oop thread_oop = jt->threadObj();
if (!jt->is_exiting() && thread_oop != NULL) {
ResourceMark rm;
_collector.fill_frames(_jthread, jt, thread_oop);
_collector.allocate_and_fill_stacks(1);
}
allocate_and_fill_stacks(_thread_count);
}
void
@ -1272,11 +1292,11 @@ VM_GetAllStackTraces::doit() {
!jt->is_hidden_from_external_view()) {
++_final_thread_count;
// Handle block of the calling thread is used to create local refs.
fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
jt, thread_oop);
_collector.fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
jt, thread_oop);
}
}
allocate_and_fill_stacks(_final_thread_count);
_collector.allocate_and_fill_stacks(_final_thread_count);
}
// Verifies that the top frame is a java frame in an expected state.
@ -1528,12 +1548,11 @@ GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
}
void
VM_GetStackTrace::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_stack_trace(_java_thread,
GetStackTraceClosure::do_thread(Thread *target) {
assert(target->is_Java_thread(), "just checking");
JavaThread *jt = (JavaThread *)target;
if (!jt->is_exiting() && jt->threadObj() != NULL) {
_result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
_start_depth, _max_count,
_frame_buffer, _count_ptr);
}