@@ -1398,8 +1398,7 @@ JvmtiEnvBase::is_vthread_suspended(oop vt_oop, JavaThread* jt) {
1398
1398
bool suspended = false ;
1399
1399
if (java_lang_VirtualThread::is_instance (vt_oop)) {
1400
1400
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 ())) {
1403
1402
suspended = jt->is_suspended ();
1404
1403
}
1405
1404
return suspended;
@@ -1757,66 +1756,55 @@ JvmtiEnvBase::suspend_thread(oop thread_oop, JavaThread* java_thread, bool singl
1757
1756
Handle thread_h (current, thread_oop);
1758
1757
bool is_virtual = java_lang_VirtualThread::is_instance (thread_h ());
1759
1758
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.
1786
1760
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 ())) {
1792
1764
return JVMTI_ERROR_THREAD_SUSPENDED;
1793
1765
}
1794
- java_thread->set_carrier_thread_suspended ();
1766
+ JvmtiVTSuspender::register_vthread_suspend (thread_h ());
1767
+ return JVMTI_ERROR_NONE;
1795
1768
}
1769
+
1770
+ // Platform thread or mounted vthread cases.
1771
+
1772
+ assert (java_thread != nullptr , " sanity check" );
1796
1773
assert (!java_thread->is_in_VTMS_transition (), " sanity check" );
1797
1774
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
+ }
1801
1779
1802
1780
// An attempt to handshake-suspend a thread carrying a virtual thread will result in
1803
1781
// suspension of mounted virtual thread. So, we just mark it as suspended
1804
1782
// 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.
1806
1788
assert (thread_h () != nullptr , " sanity check" );
1807
1789
assert (single_suspend || thread_h ()->is_a (vmClasses::BaseVirtualThread_klass ()),
1808
1790
" 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)) {
1811
1799
// Thread is already suspended or in process of exiting.
1812
1800
if (java_thread->is_exiting ()) {
1813
1801
// The thread was in the process of exiting.
1814
1802
return JVMTI_ERROR_THREAD_NOT_ALIVE;
1815
1803
}
1816
1804
return JVMTI_ERROR_THREAD_SUSPENDED;
1817
1805
}
1806
+ return JVMTI_ERROR_NONE;
1818
1807
}
1819
- return JVMTI_ERROR_NONE;
1820
1808
}
1821
1809
1822
1810
// java_thread - protected by ThreadsListHandle
@@ -1827,54 +1815,51 @@ JvmtiEnvBase::resume_thread(oop thread_oop, JavaThread* java_thread, bool single
1827
1815
Handle thread_h (current, thread_oop);
1828
1816
bool is_virtual = java_lang_VirtualThread::is_instance (thread_h ());
1829
1817
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;
1848
1824
}
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;
1850
1827
}
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
+
1851
1834
// Don't allow hidden thread resume request.
1852
1835
if (java_thread->is_hidden_from_external_view ()) {
1853
1836
return JVMTI_ERROR_NONE;
1854
1837
}
1855
- bool is_thread_carrying = is_thread_carrying_vthread (java_thread, thread_h ());
1856
1838
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.
1866
1844
1867
- if (!is_thread_carrying) {
1868
1845
assert (thread_h () != nullptr , " sanity check" );
1869
1846
assert (single_resume || thread_h ()->is_a (vmClasses::BaseVirtualThread_klass ()),
1870
1847
" 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;
1875
1860
}
1861
+ return JVMTI_ERROR_NONE;
1876
1862
}
1877
- return JVMTI_ERROR_NONE;
1878
1863
}
1879
1864
1880
1865
ResourceTracker::ResourceTracker (JvmtiEnv* env) {
0 commit comments