Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit efcb6bd

Browse files
committedApr 20, 2020
8242425: JVMTI monitor operations should use Thread-Local Handshakes
Reviewed-by: sspitsyn, dholmes
1 parent fc72827 commit efcb6bd

File tree

4 files changed

+61
-93
lines changed

4 files changed

+61
-93
lines changed
 

‎src/hotspot/share/prims/jvmtiEnv.cpp

+18-23
Original file line numberDiff line numberDiff line change
@@ -1200,21 +1200,19 @@ JvmtiEnv::GetThreadInfo(jthread thread, jvmtiThreadInfo* info_ptr) {
12001200
jvmtiError
12011201
JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count_ptr, jobject** owned_monitors_ptr) {
12021202
jvmtiError err = JVMTI_ERROR_NONE;
1203-
JavaThread* calling_thread = JavaThread::current();
12041203

12051204
// growable array of jvmti monitors info on the C-heap
12061205
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
12071206
new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
12081207

12091208
// It is only safe to perform the direct operation on the current
1210-
// thread. All other usage needs to use a vm-safepoint-op for safety.
1211-
if (java_thread == calling_thread) {
1212-
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
1209+
// thread. All other usage needs to use a direct handshake for safety.
1210+
if (java_thread == JavaThread::current()) {
1211+
err = get_owned_monitors(java_thread, owned_monitors_list);
12131212
} else {
1214-
// JVMTI get monitors info at safepoint. Do not require target thread to
1215-
// be suspended.
1216-
VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);
1217-
VMThread::execute(&op);
1213+
// get owned monitors info with handshake
1214+
GetOwnedMonitorInfoClosure op(this, owned_monitors_list);
1215+
Handshake::execute_direct(&op, java_thread);
12181216
err = op.result();
12191217
}
12201218
jint owned_monitor_count = owned_monitors_list->length();
@@ -1246,21 +1244,19 @@ JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count
12461244
jvmtiError
12471245
JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_info_count_ptr, jvmtiMonitorStackDepthInfo** monitor_info_ptr) {
12481246
jvmtiError err = JVMTI_ERROR_NONE;
1249-
JavaThread* calling_thread = JavaThread::current();
12501247

12511248
// growable array of jvmti monitors info on the C-heap
12521249
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
12531250
new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
12541251

12551252
// It is only safe to perform the direct operation on the current
1256-
// thread. All other usage needs to use a vm-safepoint-op for safety.
1257-
if (java_thread == calling_thread) {
1258-
err = get_owned_monitors(calling_thread, java_thread, owned_monitors_list);
1253+
// thread. All other usage needs to use a direct handshake for safety.
1254+
if (java_thread == JavaThread::current()) {
1255+
err = get_owned_monitors(java_thread, owned_monitors_list);
12591256
} else {
1260-
// JVMTI get owned monitors info at safepoint. Do not require target thread to
1261-
// be suspended.
1262-
VM_GetOwnedMonitorInfo op(this, calling_thread, java_thread, owned_monitors_list);
1263-
VMThread::execute(&op);
1257+
// get owned monitors info with handshake
1258+
GetOwnedMonitorInfoClosure op(this, owned_monitors_list);
1259+
Handshake::execute_direct(&op, java_thread);
12641260
err = op.result();
12651261
}
12661262

@@ -1295,16 +1291,15 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i
12951291
jvmtiError
12961292
JvmtiEnv::GetCurrentContendedMonitor(JavaThread* java_thread, jobject* monitor_ptr) {
12971293
jvmtiError err = JVMTI_ERROR_NONE;
1298-
JavaThread* calling_thread = JavaThread::current();
12991294

13001295
// It is only safe to perform the direct operation on the current
1301-
// thread. All other usage needs to use a vm-safepoint-op for safety.
1302-
if (java_thread == calling_thread) {
1303-
err = get_current_contended_monitor(calling_thread, java_thread, monitor_ptr);
1296+
// thread. All other usage needs to use a direct handshake for safety.
1297+
if (java_thread == JavaThread::current()) {
1298+
err = get_current_contended_monitor(java_thread, monitor_ptr);
13041299
} else {
1305-
// get contended monitor information at safepoint.
1306-
VM_GetCurrentContendedMonitor op(this, calling_thread, java_thread, monitor_ptr);
1307-
VMThread::execute(&op);
1300+
// get contended monitor information with handshake
1301+
GetCurrentContendedMonitorClosure op(this, monitor_ptr);
1302+
Handshake::execute_direct(&op, java_thread);
13081303
err = op.result();
13091304
}
13101305
return err;

‎src/hotspot/share/prims/jvmtiEnvBase.cpp

+19-34
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -647,13 +647,11 @@ JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
647647

648648

649649
jvmtiError
650-
JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
651-
#ifdef ASSERT
652-
uint32_t debug_bits = 0;
653-
#endif
654-
assert((SafepointSynchronize::is_at_safepoint() ||
655-
java_thread->is_thread_fully_suspended(false, &debug_bits)),
656-
"at safepoint or target thread is suspended");
650+
JvmtiEnvBase::get_current_contended_monitor(JavaThread *java_thread, jobject *monitor_ptr) {
651+
JavaThread *current_jt = JavaThread::current();
652+
assert(current_jt == java_thread ||
653+
current_jt == java_thread->active_handshaker(),
654+
"call by myself or at direct handshake");
657655
oop obj = NULL;
658656
ObjectMonitor *mon = java_thread->current_waiting_monitor();
659657
if (mon == NULL) {
@@ -675,23 +673,21 @@ JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThre
675673
*monitor_ptr = NULL;
676674
} else {
677675
HandleMark hm;
678-
Handle hobj(Thread::current(), obj);
679-
*monitor_ptr = jni_reference(calling_thread, hobj);
676+
Handle hobj(current_jt, obj);
677+
*monitor_ptr = jni_reference(current_jt, hobj);
680678
}
681679
return JVMTI_ERROR_NONE;
682680
}
683681

684682

685683
jvmtiError
686-
JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
684+
JvmtiEnvBase::get_owned_monitors(JavaThread* java_thread,
687685
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
688686
jvmtiError err = JVMTI_ERROR_NONE;
689-
#ifdef ASSERT
690-
uint32_t debug_bits = 0;
691-
#endif
692-
assert((SafepointSynchronize::is_at_safepoint() ||
693-
java_thread->is_thread_fully_suspended(false, &debug_bits)),
694-
"at safepoint or target thread is suspended");
687+
JavaThread *current_jt = JavaThread::current();
688+
assert(current_jt == java_thread ||
689+
current_jt == java_thread->active_handshaker(),
690+
"call by myself or at direct handshake");
695691

696692
if (java_thread->has_last_Java_frame()) {
697693
ResourceMark rm;
@@ -703,7 +699,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_th
703699
jvf = jvf->java_sender()) {
704700
if (MaxJavaStackTraceDepth == 0 || depth++ < MaxJavaStackTraceDepth) { // check for stack too deep
705701
// add locked objects for this frame into list
706-
err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
702+
err = get_locked_objects_in_frame(current_jt, java_thread, jvf, owned_monitors_list, depth-1);
707703
if (err != JVMTI_ERROR_NONE) {
708704
return err;
709705
}
@@ -712,7 +708,7 @@ JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_th
712708
}
713709

714710
// Get off stack monitors. (e.g. acquired via jni MonitorEnter).
715-
JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this);
711+
JvmtiMonitorClosure jmc(java_thread, current_jt, owned_monitors_list, this);
716712
ObjectSynchronizer::monitors_iterate(&jmc);
717713
err = jmc.error();
718714

@@ -1542,24 +1538,13 @@ VM_SetFramePop::doit() {
15421538
}
15431539

15441540
void
1545-
VM_GetOwnedMonitorInfo::doit() {
1546-
_result = JVMTI_ERROR_THREAD_NOT_ALIVE;
1547-
ThreadsListHandle tlh;
1548-
if (_java_thread != NULL && tlh.includes(_java_thread)
1549-
&& !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
1550-
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread, _java_thread,
1551-
_owned_monitors_list);
1552-
}
1541+
GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
1542+
_result = ((JvmtiEnvBase *)_env)->get_owned_monitors((JavaThread *)target, _owned_monitors_list);
15531543
}
15541544

15551545
void
1556-
VM_GetCurrentContendedMonitor::doit() {
1557-
_result = JVMTI_ERROR_THREAD_NOT_ALIVE;
1558-
ThreadsListHandle tlh;
1559-
if (_java_thread != NULL && tlh.includes(_java_thread)
1560-
&& !_java_thread->is_exiting() && _java_thread->threadObj() != NULL) {
1561-
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,_java_thread,_owned_monitor_ptr);
1562-
}
1546+
GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
1547+
_result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor((JavaThread *)target, _owned_monitor_ptr);
15631548
}
15641549

15651550
void

‎src/hotspot/share/prims/jvmtiEnvBase.hpp

+24-34
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -292,7 +292,8 @@ class JvmtiEnvBase : public CHeapObj<mtInternal> {
292292
// get a field descriptor for the specified class and field
293293
static bool get_field_descriptor(Klass* k, jfieldID field, fieldDescriptor* fd);
294294

295-
// JVMTI API helper functions which are called at safepoint or thread is suspended.
295+
// JVMTI API helper functions which are called when target thread is suspended
296+
// or at safepoint / thread local handshake.
296297
jvmtiError get_frame_count(JvmtiThreadState *state, jint *count_ptr);
297298
jvmtiError get_frame_location(JavaThread* java_thread, jint depth,
298299
jmethodID* method_ptr, jlocation* location_ptr);
@@ -301,11 +302,10 @@ class JvmtiEnvBase : public CHeapObj<mtInternal> {
301302
jvmtiError get_stack_trace(JavaThread *java_thread,
302303
jint stack_depth, jint max_count,
303304
jvmtiFrameInfo* frame_buffer, jint* count_ptr);
304-
jvmtiError get_current_contended_monitor(JavaThread *calling_thread,
305-
JavaThread *java_thread,
306-
jobject *monitor_ptr);
307-
jvmtiError get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
308-
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
305+
jvmtiError get_current_contended_monitor(JavaThread *java_thread,
306+
jobject *monitor_ptr);
307+
jvmtiError get_owned_monitors(JavaThread* java_thread,
308+
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list);
309309
jvmtiError check_top_frame(JavaThread* current_thread, JavaThread* java_thread,
310310
jvalue value, TosState tos, Handle* ret_ob_h);
311311
jvmtiError force_early_return(JavaThread* java_thread, jvalue value, TosState tos);
@@ -376,27 +376,21 @@ class VM_SetFramePop : public VM_Operation {
376376
};
377377

378378

379-
// VM operation to get monitor information with stack depth.
380-
class VM_GetOwnedMonitorInfo : public VM_Operation {
379+
// HandshakeClosure to get monitor information with stack depth.
380+
class GetOwnedMonitorInfoClosure : public HandshakeClosure {
381381
private:
382382
JvmtiEnv *_env;
383-
JavaThread* _calling_thread;
384-
JavaThread *_java_thread;
385383
jvmtiError _result;
386384
GrowableArray<jvmtiMonitorStackDepthInfo*> *_owned_monitors_list;
387385

388386
public:
389-
VM_GetOwnedMonitorInfo(JvmtiEnv* env, JavaThread* calling_thread,
390-
JavaThread* java_thread,
391-
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list) {
392-
_env = env;
393-
_calling_thread = calling_thread;
394-
_java_thread = java_thread;
395-
_owned_monitors_list = owned_monitor_list;
396-
_result = JVMTI_ERROR_NONE;
397-
}
398-
VMOp_Type type() const { return VMOp_GetOwnedMonitorInfo; }
399-
void doit();
387+
GetOwnedMonitorInfoClosure(JvmtiEnv* env,
388+
GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitor_list)
389+
: HandshakeClosure("GetOwnedMonitorInfo"),
390+
_env(env),
391+
_result(JVMTI_ERROR_NONE),
392+
_owned_monitors_list(owned_monitor_list) {}
393+
void do_thread(Thread *target);
400394
jvmtiError result() { return _result; }
401395
};
402396

@@ -425,25 +419,21 @@ class VM_GetObjectMonitorUsage : public VM_Operation {
425419

426420
};
427421

428-
// VM operation to get current contended monitor.
429-
class VM_GetCurrentContendedMonitor : public VM_Operation {
422+
// HandshakeClosure to get current contended monitor.
423+
class GetCurrentContendedMonitorClosure : public HandshakeClosure {
430424
private:
431425
JvmtiEnv *_env;
432-
JavaThread *_calling_thread;
433-
JavaThread *_java_thread;
434426
jobject *_owned_monitor_ptr;
435427
jvmtiError _result;
436428

437429
public:
438-
VM_GetCurrentContendedMonitor(JvmtiEnv *env, JavaThread *calling_thread, JavaThread *java_thread, jobject *mon_ptr) {
439-
_env = env;
440-
_calling_thread = calling_thread;
441-
_java_thread = java_thread;
442-
_owned_monitor_ptr = mon_ptr;
443-
}
444-
VMOp_Type type() const { return VMOp_GetCurrentContendedMonitor; }
430+
GetCurrentContendedMonitorClosure(JvmtiEnv *env, jobject *mon_ptr)
431+
: HandshakeClosure("GetCurrentContendedMonitor"),
432+
_env(env),
433+
_owned_monitor_ptr(mon_ptr),
434+
_result(JVMTI_ERROR_THREAD_NOT_ALIVE) {}
445435
jvmtiError result() { return _result; }
446-
void doit();
436+
void do_thread(Thread *target);
447437
};
448438

449439
// VM operation to get stack trace at safepoint.

‎src/hotspot/share/runtime/vmOperations.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@
8080
template(RedefineClasses) \
8181
template(UpdateForPopTopFrame) \
8282
template(SetFramePop) \
83-
template(GetOwnedMonitorInfo) \
8483
template(GetObjectMonitorUsage) \
85-
template(GetCurrentContendedMonitor) \
8684
template(GetStackTrace) \
8785
template(GetMultipleStackTraces) \
8886
template(GetAllStackTraces) \

0 commit comments

Comments
 (0)
This repository has been archived.