Skip to content

Commit b9b62a0

Browse files
author
Serguei Spitsyn
committed
8346792: serviceability/jvmti/vthread/GetThreadState/GetThreadState.java testObjectWaitMillis failed
Reviewed-by: dholmes, pchilanomate
1 parent 6b994cd commit b9b62a0

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

src/hotspot/share/prims/jvm.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -626,16 +626,6 @@ JVM_END
626626

627627
JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
628628
Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
629-
JavaThreadInObjectWaitState jtiows(thread, ms != 0);
630-
if (JvmtiExport::should_post_monitor_wait()) {
631-
JvmtiExport::post_monitor_wait(thread, obj(), ms);
632-
633-
// The current thread already owns the monitor and it has not yet
634-
// been added to the wait queue so the current thread cannot be
635-
// made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
636-
// event handler cannot accidentally consume an unpark() meant for
637-
// the ParkEvent associated with this ObjectMonitor.
638-
}
639629
ObjectSynchronizer::wait(obj, ms, CHECK);
640630
JVM_END
641631

src/hotspot/share/runtime/objectMonitor.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,11 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
16661666

16671667
// check for a pending interrupt
16681668
if (interruptible && current->is_interrupted(true) && !HAS_PENDING_EXCEPTION) {
1669+
JavaThreadInObjectWaitState jtiows(current, millis != 0, interruptible);
1670+
1671+
if (JvmtiExport::should_post_monitor_wait()) {
1672+
JvmtiExport::post_monitor_wait(current, object(), millis);
1673+
}
16691674
// post monitor waited event. Note that this is past-tense, we are done waiting.
16701675
if (JvmtiExport::should_post_monitor_waited()) {
16711676
// Note: 'false' parameter is passed here because the
@@ -1687,19 +1692,36 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
16871692
return;
16881693
}
16891694

1690-
current->set_current_waiting_monitor(this);
1691-
16921695
freeze_result result;
16931696
ContinuationEntry* ce = current->last_continuation();
1694-
if (ce != nullptr && ce->is_virtual_thread()) {
1697+
bool is_virtual = ce != nullptr && ce->is_virtual_thread();
1698+
if (is_virtual) {
1699+
if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1700+
JvmtiExport::post_monitor_wait(current, object(), millis);
1701+
}
1702+
current->set_current_waiting_monitor(this);
16951703
result = Continuation::try_preempt(current, ce->cont_oop(current));
16961704
if (result == freeze_ok) {
16971705
VThreadWait(current, millis);
16981706
current->set_current_waiting_monitor(nullptr);
16991707
return;
17001708
}
17011709
}
1710+
// The jtiows does nothing for non-interruptible.
1711+
JavaThreadInObjectWaitState jtiows(current, millis != 0, interruptible);
1712+
1713+
if (!is_virtual) { // it was already set for virtual thread
1714+
if (interruptible && JvmtiExport::should_post_monitor_wait()) {
1715+
JvmtiExport::post_monitor_wait(current, object(), millis);
17021716

1717+
// The current thread already owns the monitor and it has not yet
1718+
// been added to the wait queue so the current thread cannot be
1719+
// made the successor. This means that the JVMTI_EVENT_MONITOR_WAIT
1720+
// event handler cannot accidentally consume an unpark() meant for
1721+
// the ParkEvent associated with this ObjectMonitor.
1722+
}
1723+
current->set_current_waiting_monitor(this);
1724+
}
17031725
// create a node to be put into the queue
17041726
// Critically, after we reset() the event but prior to park(), we must check
17051727
// for a pending interrupt.

src/hotspot/share/services/threadService.hpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2025, 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
@@ -487,10 +487,19 @@ class JavaThreadInObjectWaitState : public JavaThreadStatusChanger {
487487
bool _active;
488488

489489
public:
490-
JavaThreadInObjectWaitState(JavaThread *java_thread, bool timed) :
490+
// Sets the java.lang.Thread state of the given JavaThread to reflect it is doing a regular,
491+
// or timed, Object.wait call.
492+
//
493+
// The interruptible parameter, if false, indicates an internal uninterruptible wait,
494+
// in which case we do not update the java.lang.Thread state. We do that by passing
495+
// the current state to the JavaThreadStatusChanger so no actual change is observable,
496+
// and skip the statistics updates. This avoids having to duplicate code paths for
497+
// the interruptible and non-interruptible cases in the caller.
498+
JavaThreadInObjectWaitState(JavaThread *java_thread, bool timed, bool interruptible) :
491499
JavaThreadStatusChanger(java_thread,
492-
timed ? JavaThreadStatus::IN_OBJECT_WAIT_TIMED : JavaThreadStatus::IN_OBJECT_WAIT) {
493-
if (is_alive()) {
500+
interruptible ? (timed ? JavaThreadStatus::IN_OBJECT_WAIT_TIMED : JavaThreadStatus::IN_OBJECT_WAIT)
501+
: java_lang_Thread::get_thread_status(java_thread->threadObj())) {
502+
if (is_alive() && interruptible) { // in non-interruptible case we set _active = false below
494503
_stat = java_thread->get_thread_stat();
495504
_active = ThreadService::is_thread_monitoring_contention();
496505
_stat->monitor_wait();

0 commit comments

Comments
 (0)