@@ -1398,8 +1398,7 @@ JvmtiEnvBase::is_vthread_suspended(oop vt_oop, JavaThread* jt) {
13981398 bool suspended = false ;
13991399 if (java_lang_VirtualThread::is_instance (vt_oop)) {
14001400 suspended = JvmtiVTSuspender::is_vthread_suspended (vt_oop);
1401- }
1402- if (vt_oop->is_a (vmClasses::BoundVirtualThread_klass ())) {
1401+ } else if (vt_oop->is_a (vmClasses::BoundVirtualThread_klass ())) {
14031402 suspended = jt->is_suspended ();
14041403 }
14051404 return suspended;
@@ -1757,66 +1756,55 @@ JvmtiEnvBase::suspend_thread(oop thread_oop, JavaThread* java_thread, bool singl
17571756 Handle thread_h (current, thread_oop);
17581757 bool is_virtual = java_lang_VirtualThread::is_instance (thread_h ());
17591758
1760- if (is_virtual) {
1761- if (single_suspend) {
1762- if (JvmtiVTSuspender::is_vthread_suspended (thread_h ())) {
1763- return JVMTI_ERROR_THREAD_SUSPENDED;
1764- }
1765- JvmtiVTSuspender::register_vthread_suspend (thread_h ());
1766- // Check if virtual thread is mounted and there is a java_thread.
1767- // A non-null java_thread is always passed in the !single_suspend case.
1768- oop carrier_thread = java_lang_VirtualThread::carrier_thread (thread_h ());
1769- java_thread = carrier_thread == nullptr ? nullptr : java_lang_Thread::thread (carrier_thread);
1770- }
1771- // The java_thread can be still blocked in VTMS transition after a previous JVMTI resume call.
1772- // There is no need to suspend the java_thread in this case. After vthread unblocking,
1773- // it will check for ext_suspend request and suspend itself if necessary.
1774- if (java_thread == nullptr || java_thread->is_suspended ()) {
1775- // We are done if the virtual thread is unmounted or
1776- // the java_thread is externally suspended.
1777- return JVMTI_ERROR_NONE;
1778- }
1779- // The virtual thread is mounted: suspend the java_thread.
1780- }
1781- // Don't allow hidden thread suspend request.
1782- if (java_thread->is_hidden_from_external_view ()) {
1783- return JVMTI_ERROR_NONE;
1784- }
1785- bool is_thread_carrying = is_thread_carrying_vthread (java_thread, thread_h ());
1759+ // Unmounted vthread case.
17861760
1787- // A case of non-virtual thread.
1788- if (!is_virtual) {
1789- // Thread.suspend() is used in some tests. It sets jt->is_suspended() only.
1790- if (java_thread->is_carrier_thread_suspended () ||
1791- (!is_thread_carrying && java_thread->is_suspended ())) {
1761+ if (is_virtual && java_thread == nullptr ) {
1762+ assert (single_suspend, " sanity check" );
1763+ if (JvmtiVTSuspender::is_vthread_suspended (thread_h ())) {
17921764 return JVMTI_ERROR_THREAD_SUSPENDED;
17931765 }
1794- java_thread->set_carrier_thread_suspended ();
1766+ JvmtiVTSuspender::register_vthread_suspend (thread_h ());
1767+ return JVMTI_ERROR_NONE;
17951768 }
1769+
1770+ // Platform thread or mounted vthread cases.
1771+
1772+ assert (java_thread != nullptr , " sanity check" );
17961773 assert (!java_thread->is_in_VTMS_transition (), " sanity check" );
17971774
1798- assert (!single_suspend || (!is_virtual && java_thread->is_carrier_thread_suspended ()) ||
1799- (is_virtual && JvmtiVTSuspender::is_vthread_suspended (thread_h ())),
1800- " sanity check" );
1775+ // Don't allow hidden thread suspend request.
1776+ if (java_thread->is_hidden_from_external_view ()) {
1777+ return JVMTI_ERROR_NONE;
1778+ }
18011779
18021780 // An attempt to handshake-suspend a thread carrying a virtual thread will result in
18031781 // suspension of mounted virtual thread. So, we just mark it as suspended
18041782 // and it will be actually suspended at virtual thread unmount transition.
1805- if (!is_thread_carrying) {
1783+ bool is_thread_carrying = is_thread_carrying_vthread (java_thread, thread_h ());
1784+ if (is_thread_carrying) {
1785+ return java_thread->set_carrier_thread_suspended () ? JVMTI_ERROR_NONE : JVMTI_ERROR_THREAD_SUSPENDED;
1786+ } else {
1787+ // Platform thread (not carrying vthread) or mounted vthread cases.
18061788 assert (thread_h () != nullptr , " sanity check" );
18071789 assert (single_suspend || thread_h ()->is_a (vmClasses::BaseVirtualThread_klass ()),
18081790 " SuspendAllVirtualThreads should never suspend non-virtual threads" );
1809- // Case of mounted virtual or attached carrier thread.
1810- if (!java_thread->java_suspend ()) {
1791+
1792+ // Ideally we would just need to check java_thread->is_suspended(), but we have to
1793+ // consider the case of trying to suspend a thread that was previously suspended while
1794+ // carrying a vthread but has already unmounted it.
1795+ if (java_thread->is_suspended () || (!is_virtual && java_thread->is_carrier_thread_suspended ())) {
1796+ return JVMTI_ERROR_THREAD_SUSPENDED;
1797+ }
1798+ if (!java_thread->java_suspend (is_virtual && single_suspend)) {
18111799 // Thread is already suspended or in process of exiting.
18121800 if (java_thread->is_exiting ()) {
18131801 // The thread was in the process of exiting.
18141802 return JVMTI_ERROR_THREAD_NOT_ALIVE;
18151803 }
18161804 return JVMTI_ERROR_THREAD_SUSPENDED;
18171805 }
1806+ return JVMTI_ERROR_NONE;
18181807 }
1819- return JVMTI_ERROR_NONE;
18201808}
18211809
18221810// java_thread - protected by ThreadsListHandle
@@ -1827,54 +1815,51 @@ JvmtiEnvBase::resume_thread(oop thread_oop, JavaThread* java_thread, bool single
18271815 Handle thread_h (current, thread_oop);
18281816 bool is_virtual = java_lang_VirtualThread::is_instance (thread_h ());
18291817
1830- if (is_virtual) {
1831- if (single_resume) {
1832- if (!JvmtiVTSuspender::is_vthread_suspended (thread_h ())) {
1833- return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1834- }
1835- JvmtiVTSuspender::register_vthread_resume (thread_h ());
1836- // Check if virtual thread is mounted and there is a java_thread.
1837- // A non-null java_thread is always passed in the !single_resume case.
1838- oop carrier_thread = java_lang_VirtualThread::carrier_thread (thread_h ());
1839- java_thread = carrier_thread == nullptr ? nullptr : java_lang_Thread::thread (carrier_thread);
1840- }
1841- // The java_thread can be still blocked in VTMS transition after a previous JVMTI suspend call.
1842- // There is no need to resume the java_thread in this case. After vthread unblocking,
1843- // it will check for is_vthread_suspended request and remain resumed if necessary.
1844- if (java_thread == nullptr || !java_thread->is_suspended ()) {
1845- // We are done if the virtual thread is unmounted or
1846- // the java_thread is not externally suspended.
1847- return JVMTI_ERROR_NONE;
1818+ // Unmounted vthread case.
1819+
1820+ if (is_virtual && java_thread == nullptr ) {
1821+ assert (single_resume, " sanity check" );
1822+ if (!JvmtiVTSuspender::is_vthread_suspended (thread_h ())) {
1823+ return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
18481824 }
1849- // The virtual thread is mounted and java_thread is supended: resume the java_thread.
1825+ JvmtiVTSuspender::register_vthread_resume (thread_h ());
1826+ return JVMTI_ERROR_NONE;
18501827 }
1828+
1829+ // Platform thread or mounted vthread cases.
1830+
1831+ assert (java_thread != nullptr , " sanity check" );
1832+ assert (!java_thread->is_in_VTMS_transition (), " sanity check" );
1833+
18511834 // Don't allow hidden thread resume request.
18521835 if (java_thread->is_hidden_from_external_view ()) {
18531836 return JVMTI_ERROR_NONE;
18541837 }
1855- bool is_thread_carrying = is_thread_carrying_vthread (java_thread, thread_h ());
18561838
1857- // A case of a non-virtual thread.
1858- if (!is_virtual) {
1859- if (!java_thread->is_carrier_thread_suspended () &&
1860- (is_thread_carrying || !java_thread->is_suspended ())) {
1861- return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1862- }
1863- java_thread->clear_carrier_thread_suspended ();
1864- }
1865- assert (!java_thread->is_in_VTMS_transition (), " sanity check" );
1839+ bool is_thread_carrying = is_thread_carrying_vthread (java_thread, thread_h ());
1840+ if (is_thread_carrying) {
1841+ return java_thread->clear_carrier_thread_suspended () ? JVMTI_ERROR_NONE : JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1842+ } else {
1843+ // Platform thread (not carrying vthread) or mounted vthread cases.
18661844
1867- if (!is_thread_carrying) {
18681845 assert (thread_h () != nullptr , " sanity check" );
18691846 assert (single_resume || thread_h ()->is_a (vmClasses::BaseVirtualThread_klass ()),
18701847 " ResumeAllVirtualThreads should never resume non-virtual threads" );
1871- if (java_thread->is_suspended ()) {
1872- if (!java_thread->java_resume ()) {
1873- return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
1874- }
1848+
1849+ // Ideally we would not have to check this but we have to consider the case
1850+ // of trying to resume a thread that was previously suspended while carrying
1851+ // a vthread but has already unmounted it.
1852+ if (!is_virtual && java_thread->is_carrier_thread_suspended ()) {
1853+ bool res = java_thread->clear_carrier_thread_suspended ();
1854+ assert (res, " resume operations running concurrently?" );
1855+ return JVMTI_ERROR_NONE;
1856+ }
1857+
1858+ if (!java_thread->java_resume (is_virtual && single_resume)) {
1859+ return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
18751860 }
1861+ return JVMTI_ERROR_NONE;
18761862 }
1877- return JVMTI_ERROR_NONE;
18781863}
18791864
18801865ResourceTracker::ResourceTracker (JvmtiEnv* env) {
0 commit comments