33
33
34
34
import org .graalvm .compiler .core .common .SuppressFBWarnings ;
35
35
import org .graalvm .compiler .word .BarrieredAccess ;
36
+ import org .graalvm .compiler .word .Word ;
36
37
import org .graalvm .nativeimage .Feature ;
37
38
import org .graalvm .nativeimage .ImageSingletons ;
38
39
@@ -98,8 +99,10 @@ public static void monitorEnter(Object obj) {
98
99
return ;
99
100
}
100
101
102
+ ReentrantLock lockObject = null ;
101
103
try {
102
- ImageSingletons .lookup (MonitorSupport .class ).getOrCreateMonitor (obj , true ).lock ();
104
+ lockObject = ImageSingletons .lookup (MonitorSupport .class ).getOrCreateMonitor (obj , true );
105
+ lockObject .lock ();
103
106
} catch (Throwable ex ) {
104
107
/*
105
108
* The foreign call from snippets to this method does not have an exception edge. So we
@@ -112,7 +115,7 @@ public static void monitorEnter(Object obj) {
112
115
* Finally, it would not be clear whether the monitor is locked or unlocked in case of
113
116
* an exception.
114
117
*/
115
- VMError . shouldNotReachHere (ex );
118
+ throw shouldNotReachHere ("monitorEnter" , obj , lockObject , ex );
116
119
}
117
120
}
118
121
@@ -130,8 +133,10 @@ public static void monitorExit(Object obj) {
130
133
return ;
131
134
}
132
135
136
+ ReentrantLock lockObject = null ;
133
137
try {
134
- ImageSingletons .lookup (MonitorSupport .class ).getOrCreateMonitor (obj , true ).unlock ();
138
+ lockObject = ImageSingletons .lookup (MonitorSupport .class ).getOrCreateMonitor (obj , true );
139
+ lockObject .unlock ();
135
140
} catch (Throwable ex ) {
136
141
/*
137
142
* The foreign call from snippets to this method does not have an exception edge. So we
@@ -141,10 +146,46 @@ public static void monitorExit(Object obj) {
141
146
* the Java Virtual Machine Specification, but it ensures that we never need to throw an
142
147
* IllegalMonitorStateException.
143
148
*/
144
- VMError . shouldNotReachHere (ex );
149
+ throw shouldNotReachHere ("monitorExit" , obj , lockObject , ex );
145
150
}
146
151
}
147
152
153
+ private static RuntimeException shouldNotReachHere (String label , Object obj , ReentrantLock lockObject , Throwable ex ) {
154
+ StringBuilder msg = new StringBuilder ();
155
+ msg .append ("Unexpected exception in MonitorSupport." ).append (label );
156
+
157
+ if (obj != null ) {
158
+ msg .append (" object: " );
159
+ appendObject (msg , obj );
160
+ }
161
+ if (lockObject != null ) {
162
+ msg .append (" lock: " );
163
+ appendObject (msg , lockObject );
164
+
165
+ Target_java_util_concurrent_locks_ReentrantLock lockObjectTarget = KnownIntrinsics .unsafeCast (lockObject , Target_java_util_concurrent_locks_ReentrantLock .class );
166
+ Target_java_util_concurrent_locks_AbstractOwnableSynchronizer sync = KnownIntrinsics .unsafeCast (lockObjectTarget .sync , Target_java_util_concurrent_locks_AbstractOwnableSynchronizer .class );
167
+
168
+ if (sync != null ) {
169
+ msg .append (" sync: " );
170
+ appendObject (msg , sync );
171
+
172
+ Thread thread = sync .getExclusiveOwnerThread ();
173
+ if (thread == null ) {
174
+ msg .append (" no exclusiveOwnerThread" );
175
+ } else {
176
+ msg .append (" exclusiveOwnerThread: " );
177
+ appendObject (msg , thread );
178
+ }
179
+ }
180
+ }
181
+ msg .append (" raw exception: " );
182
+ throw VMError .shouldNotReachHere (msg .toString (), ex );
183
+ }
184
+
185
+ private static void appendObject (StringBuilder msg , Object obj ) {
186
+ msg .append (obj .getClass ().getName ()).append ("@" ).append (Long .toHexString (Word .objectToUntrackedPointer (obj ).rawValue ()));
187
+ }
188
+
148
189
/**
149
190
* This is a highly unsafe method that patches the existing lock of an object so that the object
150
191
* appears as if it has been locked from a different thread. It is only safe to call when the
0 commit comments