7676import com .oracle .svm .core .snippets .KnownIntrinsics ;
7777import com .oracle .svm .core .stack .StackOverflowCheck ;
7878import com .oracle .svm .core .thread .VMThreads .SafepointBehavior ;
79+ import com .oracle .svm .core .thread .VirtualThreads ;
7980import com .oracle .svm .core .util .Utf8 ;
8081import com .oracle .svm .core .util .VMError ;
8182import com .oracle .svm .jni .JNIObjectHandles ;
@@ -1015,10 +1016,38 @@ static int MonitorEnter(JNIEnvironment env, JNIObjectHandle handle) {
10151016 if (obj == null ) {
10161017 throw new NullPointerException ();
10171018 }
1018- MonitorSupport .singleton ().monitorEnter (obj );
1019- assert Thread .holdsLock (obj );
1020- JNIThreadOwnedMonitors .entered (obj );
1021- return JNIErrors .JNI_OK ();
1019+ boolean pinned = false ;
1020+ if (VirtualThreads .isSupported () && VirtualThreads .get ().isVirtual (Thread .currentThread ())) {
1021+ // Acquiring monitors via JNI associates them with the carrier thread via
1022+ // JNIThreadOwnedMonitors, so we must pin the virtual thread
1023+ try {
1024+ VirtualThreads .get ().pinCurrent ();
1025+ } catch (IllegalStateException e ) { // too many pins
1026+ throw new IllegalMonitorStateException ();
1027+ }
1028+ pinned = true ;
1029+ }
1030+ boolean acquired = false ;
1031+ try {
1032+ MonitorSupport .singleton ().monitorEnter (obj );
1033+ assert Thread .holdsLock (obj );
1034+ acquired = true ;
1035+
1036+ JNIThreadOwnedMonitors .entered (obj );
1037+ return JNIErrors .JNI_OK ();
1038+ } catch (Throwable t ) {
1039+ try {
1040+ if (acquired ) {
1041+ MonitorSupport .singleton ().monitorExit (obj );
1042+ }
1043+ if (pinned ) {
1044+ VirtualThreads .get ().unpinCurrent ();
1045+ }
1046+ } catch (Throwable u ) {
1047+ throw VMError .shouldNotReachHere (u );
1048+ }
1049+ throw t ;
1050+ }
10221051 }
10231052
10241053 /*
@@ -1036,6 +1065,13 @@ static int MonitorExit(JNIEnvironment env, JNIObjectHandle handle) {
10361065 }
10371066 MonitorSupport .singleton ().monitorExit (obj );
10381067 JNIThreadOwnedMonitors .exited (obj );
1068+ if (VirtualThreads .isSupported () && VirtualThreads .get ().isVirtual (Thread .currentThread ())) {
1069+ try {
1070+ VirtualThreads .get ().unpinCurrent ();
1071+ } catch (IllegalStateException e ) { // not pinned?
1072+ throw new IllegalMonitorStateException ();
1073+ }
1074+ }
10391075 return JNIErrors .JNI_OK ();
10401076 }
10411077
0 commit comments