@@ -71,6 +71,9 @@ objectMonitorExit(J9VMThread* vmStruct, j9object_t object)
7171 lock = J9_LOAD_LOCKWORD (vmStruct , lockEA );
7272
7373 if (J9_FLATLOCK_OWNER (lock ) == vmStruct ) {
74+ #if JAVA_SPEC_VERSION >= 24
75+ J9JavaVM * vm = vmStruct -> javaVM ;
76+ #endif /* JAVA_SPEC_VERSION >= 24 */
7477 /* The current thread owns the monitor, and it's a flat lock. */
7578 UDATA count = (UDATA )lock & OBJECT_HEADER_LOCK_BITS_MASK ;
7679 /*
@@ -96,133 +99,136 @@ objectMonitorExit(J9VMThread* vmStruct, j9object_t object)
9699#endif /* if !(defined(AIXPPC) || defined(LINUXPPC)) */
97100#endif /* ifndef J9VM_THR_LOCK_RESERVATION */
98101#if JAVA_SPEC_VERSION >= 24
99- if (OBJECT_HEADER_LOCK_FLC == count ) {
100- /* FLC set, non-recursive. */
101- J9ObjectMonitor * objectMonitor = objectMonitorInflate ( vmStruct , object , lock );
102-
103- if ( NULL == objectMonitor ) {
104- /* Out of memory - impossible? */
105- monitorExitWriteBarrier ();
106- J9_STORE_LOCKWORD ( vmStruct , lockEA , 0 );
107- } else {
108- omrthread_monitor_t monitor = objectMonitor -> monitor ;
109- J9JavaVM * vm = vmStruct -> javaVM ;
102+ if (J9_ARE_ANY_BITS_SET ( vm -> extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION ) {
103+ if ( OBJECT_HEADER_LOCK_FLC == count ) {
104+ /* FLC set, non-recursive. */
105+ J9ObjectMonitor * objectMonitor = objectMonitorInflate ( vmStruct , object , lock );
106+
107+ if ( NULL == objectMonitor ) {
108+ /* Out of memory - impossible? */
109+ monitorExitWriteBarrier ( );
110+ J9_STORE_LOCKWORD ( vmStruct , lockEA , 0 );
111+ } else {
112+ omrthread_monitor_t monitor = objectMonitor -> monitor ;
110113
111- TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_EXIT (vm -> hookInterface , vmStruct , monitor );
114+ TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_EXIT (vm -> hookInterface , vmStruct , monitor );
112115
113- omrthread_monitor_exit (monitor );
116+ omrthread_monitor_exit (monitor );
114117
115- if (J9_ARE_ANY_BITS_SET (vm -> extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION )
116- && (0 != objectMonitor -> virtualThreadWaitCount )
118+ if (J9_ARE_ANY_BITS_SET (vm -> extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION )
119+ && (0 != objectMonitor -> virtualThreadWaitCount )
120+ ) {
121+ J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL (vm );
122+ }
123+ }
124+ } else {
125+ j9objectmonitor_t newLock = 0 ;
126+ BOOLEAN casSuccess = FALSE;
127+ if (0x00 == count ) {
128+ /* Just release the flatlock. */
129+ } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )
130+ && J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING_RECURSION_MASK )
117131 ) {
118- J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL (vm );
132+ /* Learning state case. */
133+ newLock = lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT ;
134+ } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )) {
135+ /* Lock is in Learning state but unowned.
136+ * (if it were owned it would have been caught by the first Learning state check)
137+ */
138+ goto done ;
139+ } else if (count >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ) {
140+ /* Just decrement the flatlock recursion count. */
141+ newLock = lock - OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ;
142+ #ifdef J9VM_THR_LOCK_RESERVATION
143+ } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_RESERVED )) {
144+ /* Lock is reserved but unowned.
145+ * (if it were owned the count would be >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT)
146+ */
147+ Trc_VM_objectMonitorExit_Exit_ReservedButUnownedFlatLock (vmStruct , lock , object );
148+ goto done ;
149+ #endif /* J9VM_THR_LOCK_RESERVATION */
150+ }
151+
152+ monitorExitWriteBarrier ();
153+ if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES (vmStruct )) {
154+ casSuccess = (lock == compareAndSwapU32 ((uint32_t * )lockEA , (uint32_t )lock , (uint32_t )newLock ));
155+ } else {
156+ casSuccess = (lock == compareAndSwapUDATA ((uintptr_t * )lockEA , (uintptr_t )lock , (uintptr_t )newLock ));
157+ }
158+
159+ if (!casSuccess ) {
160+ /* Another thread has attempted to get the lock and may have update the FLC flag. */
161+ goto restart ;
119162 }
120163 }
121- } else {
122- j9objectmonitor_t newLock = 0 ;
123- BOOLEAN casSuccess = FALSE;
164+ } else
165+ #endif /* JAVA_SPEC_VERSION >= 24 */
166+ {
124167 if (0x00 == count ) {
125168 /* Just release the flatlock. */
169+ monitorExitWriteBarrier ();
170+ J9_STORE_LOCKWORD (vmStruct , lockEA , 0 );
126171 } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )
127172 && J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING_RECURSION_MASK )
128173 ) {
129174 /* Learning state case. */
130- newLock = lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT ;
175+ BOOLEAN casSuccess = FALSE;
176+
177+ if (1 == J9_FLATLOCK_COUNT (lock )) {
178+ /* If RC field is 1, this fully unlocks the object so a write barrier is needed. */
179+ monitorExitWriteBarrier ();
180+ }
181+
182+ if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES (vmStruct )) {
183+ casSuccess = (lock == compareAndSwapU32 ((uint32_t * )lockEA , (uint32_t )lock ,
184+ (uint32_t )(lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT )));
185+ } else {
186+ casSuccess = (lock == compareAndSwapUDATA ((uintptr_t * )lockEA , (uintptr_t )lock ,
187+ (uintptr_t )(lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT )));
188+ }
189+
190+ if (!casSuccess ) {
191+ /*
192+ * Another thread has attempted to get the lock and atomically changed the state to Flat.
193+ * Start over and read the new lockword. The lock can not go back to Learning so this will
194+ * only happen once.
195+ */
196+ goto restart ;
197+ }
131198 } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )) {
132199 /* Lock is in Learning state but unowned.
133- * (if it were owned it would have been caught by the first Learning state check)
134- */
200+ * (if it were owned it would have been caught by the first Learning state check)
201+ */
202+ Trc_VM_objectMonitorExit_Exit_LearningStateUnowned (vmStruct , lock , object );
135203 goto done ;
136204 } else if (count >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ) {
137205 /* Just decrement the flatlock recursion count. */
138- newLock = lock - OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ;
206+ lock -= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ;
207+ J9_STORE_LOCKWORD (vmStruct , lockEA , lock );
139208#ifdef J9VM_THR_LOCK_RESERVATION
140209 } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_RESERVED )) {
141210 /* Lock is reserved but unowned.
142- * (if it were owned the count would be >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT)
143- */
211+ * (if it were owned the count would be >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT)
212+ */
144213 Trc_VM_objectMonitorExit_Exit_ReservedButUnownedFlatLock (vmStruct , lock , object );
145214 goto done ;
146215#endif /* J9VM_THR_LOCK_RESERVATION */
147- }
148-
149- monitorExitWriteBarrier ();
150- if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES (vmStruct )) {
151- casSuccess = (lock == compareAndSwapU32 ((uint32_t * )lockEA , (uint32_t )lock , (uint32_t )newLock ));
152216 } else {
153- casSuccess = ( lock == compareAndSwapUDATA (( uintptr_t * ) lockEA , ( uintptr_t ) lock , ( uintptr_t ) newLock ));
154- }
217+ /* FLC set, non-recursive. */
218+ J9ObjectMonitor * objectMonitor = objectMonitorInflate ( vmStruct , object , lock );
155219
156- if (!casSuccess ) {
157- /* Another thread has attempted to get the lock and may have update the FLC flag. */
158- goto restart ;
220+ if (NULL == objectMonitor ) {
221+ /* Out of memory - impossible? */
222+ monitorExitWriteBarrier ();
223+ J9_STORE_LOCKWORD (vmStruct , lockEA , 0 );
224+ } else {
225+ omrthread_monitor_t monitor = objectMonitor -> monitor ;
226+ TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_EXIT (vmStruct -> javaVM -> hookInterface , vmStruct , monitor );
227+ omrthread_monitor_exit (monitor );
228+ }
159229 }
160230 }
161- #else /* JAVA_SPEC_VERSION >= 24 */
162- if (0x00 == count ) {
163- /* Just release the flatlock. */
164- monitorExitWriteBarrier ();
165- J9_STORE_LOCKWORD (vmStruct , lockEA , 0 );
166- } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )
167- && J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING_RECURSION_MASK )
168- ) {
169- /* Learning state case. */
170- BOOLEAN casSuccess = FALSE;
171-
172- if (1 == J9_FLATLOCK_COUNT (lock )) {
173- /* If RC field is 1, this fully unlocks the object so a write barrier is needed. */
174- monitorExitWriteBarrier ();
175- }
176-
177- if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES (vmStruct )) {
178- casSuccess = (lock == compareAndSwapU32 ((uint32_t * )lockEA , (uint32_t )lock ,
179- (uint32_t )(lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT )));
180- } else {
181- casSuccess = (lock == compareAndSwapUDATA ((uintptr_t * )lockEA , (uintptr_t )lock ,
182- (uintptr_t )(lock - OBJECT_HEADER_LOCK_LEARNING_FIRST_RECURSION_BIT )));
183- }
184231
185- if (!casSuccess ) {
186- /*
187- * Another thread has attempted to get the lock and atomically changed the state to Flat.
188- * Start over and read the new lockword. The lock can not go back to Learning so this will
189- * only happen once.
190- */
191- goto restart ;
192- }
193- } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_LEARNING )) {
194- /* Lock is in Learning state but unowned.
195- * (if it were owned it would have been caught by the first Learning state check)
196- */
197- Trc_VM_objectMonitorExit_Exit_LearningStateUnowned (vmStruct , lock , object );
198- goto done ;
199- } else if (count >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ) {
200- /* Just decrement the flatlock recursion count. */
201- lock -= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT ;
202- J9_STORE_LOCKWORD (vmStruct , lockEA , lock );
203- #ifdef J9VM_THR_LOCK_RESERVATION
204- } else if (J9_ARE_ANY_BITS_SET (count , OBJECT_HEADER_LOCK_RESERVED )) {
205- /* Lock is reserved but unowned.
206- * (if it were owned the count would be >= OBJECT_HEADER_LOCK_FIRST_RECURSION_BIT)
207- */
208- Trc_VM_objectMonitorExit_Exit_ReservedButUnownedFlatLock (vmStruct , lock , object );
209- goto done ;
210- #endif /* J9VM_THR_LOCK_RESERVATION */
211- } else {
212- /* FLC set, non-recursive. */
213- J9ObjectMonitor * objectMonitor = objectMonitorInflate (vmStruct , object , lock );
214-
215- if (NULL == objectMonitor ) {
216- /* Out of memory - impossible? */
217- monitorExitWriteBarrier ();
218- J9_STORE_LOCKWORD (vmStruct , lockEA , 0 );
219- } else {
220- omrthread_monitor_t monitor = objectMonitor -> monitor ;
221- TRIGGER_J9HOOK_VM_MONITOR_CONTENDED_EXIT (vmStruct -> javaVM -> hookInterface , vmStruct , monitor );
222- omrthread_monitor_exit (monitor );
223- }
224- }
225- #endif /* JAVA_SPEC_VERSION >= 24 */
226232 Trc_VM_objectMonitorExit_Exit_FCBSet (vmStruct );
227233 rc = 0 ;
228234 goto done ;
0 commit comments