@@ -224,10 +224,10 @@ void C2_MacroAssembler::fast_unlock(Register objectReg, Register boxReg, Registe
224224 bind (no_count);
225225}
226226
227- void C2_MacroAssembler::fast_lock_lightweight (Register obj, Register t1,
227+ void C2_MacroAssembler::fast_lock_lightweight (Register obj, Register box, Register t1,
228228 Register t2, Register t3) {
229229 assert (LockingMode == LM_LIGHTWEIGHT, " must be" );
230- assert_different_registers (obj, t1, t2, t3);
230+ assert_different_registers (obj, box, t1, t2, t3);
231231
232232 // Handle inflated monitor.
233233 Label inflated;
@@ -236,6 +236,11 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
236236 // Finish fast lock unsuccessfully. MUST branch to with flag == NE
237237 Label slow_path;
238238
239+ if (UseObjectMonitorTable) {
240+ // Clear cache in case fast locking succeeds.
241+ str (zr, Address (box, BasicLock::object_monitor_cache_offset_in_bytes ()));
242+ }
243+
239244 if (DiagnoseSyncOnValueBasedClasses != 0 ) {
240245 load_klass (t1, obj);
241246 ldrw (t1, Address (t1, Klass::access_flags_offset ()));
@@ -244,14 +249,14 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
244249 }
245250
246251 const Register t1_mark = t1;
252+ const Register t3_t = t3;
247253
248254 { // Lightweight locking
249255
250256 // Push lock to the lock stack and finish successfully. MUST branch to with flag == EQ
251257 Label push;
252258
253259 const Register t2_top = t2;
254- const Register t3_t = t3;
255260
256261 // Check if lock-stack is full.
257262 ldrw (t2_top, Address (rthread, JavaThread::lock_stack_top_offset ()));
@@ -289,26 +294,71 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
289294 { // Handle inflated monitor.
290295 bind (inflated);
291296
292- // mark contains the tagged ObjectMonitor*.
293- const Register t1_tagged_monitor = t1_mark;
294- const uintptr_t monitor_tag = markWord::monitor_value;
297+ const Register t1_monitor = t1;
298+
299+ if (!UseObjectMonitorTable) {
300+ assert (t1_monitor == t1_mark, " should be the same here" );
301+ } else {
302+ Label monitor_found;
303+
304+ // Load cache address
305+ lea (t3_t , Address (rthread, JavaThread::om_cache_oops_offset ()));
306+
307+ const int num_unrolled = 2 ;
308+ for (int i = 0 ; i < num_unrolled; i++) {
309+ ldr (t1, Address (t3_t ));
310+ cmp (obj, t1);
311+ br (Assembler::EQ, monitor_found);
312+ increment (t3_t , in_bytes (OMCache::oop_to_oop_difference ()));
313+ }
314+
315+ Label loop;
316+
317+ // Search for obj in cache.
318+ bind (loop);
319+
320+ // Check for match.
321+ ldr (t1, Address (t3_t ));
322+ cmp (obj, t1);
323+ br (Assembler::EQ, monitor_found);
324+
325+ // Search until null encountered, guaranteed _null_sentinel at end.
326+ increment (t3_t , in_bytes (OMCache::oop_to_oop_difference ()));
327+ cbnz (t1, loop);
328+ // Cache Miss, NE set from cmp above, cbnz does not set flags
329+ b (slow_path);
330+
331+ bind (monitor_found);
332+ ldr (t1_monitor, Address (t3_t , OMCache::oop_to_monitor_difference ()));
333+ }
334+
295335 const Register t2_owner_addr = t2;
296336 const Register t3_owner = t3;
337+ const ByteSize monitor_tag = in_ByteSize (UseObjectMonitorTable ? 0 : checked_cast<int >(markWord::monitor_value));
338+ const Address owner_address (t1_monitor, ObjectMonitor::owner_offset () - monitor_tag);
339+ const Address recursions_address (t1_monitor, ObjectMonitor::recursions_offset () - monitor_tag);
340+
341+ Label monitor_locked;
297342
298343 // Compute owner address.
299- lea (t2_owner_addr, Address (t1_tagged_monitor, ( in_bytes ( ObjectMonitor::owner_offset ()) - monitor_tag)) );
344+ lea (t2_owner_addr, owner_address );
300345
301346 // CAS owner (null => current thread).
302347 cmpxchg (t2_owner_addr, zr, rthread, Assembler::xword, /* acquire*/ true ,
303348 /* release*/ false , /* weak*/ false , t3_owner);
304- br (Assembler::EQ, locked );
349+ br (Assembler::EQ, monitor_locked );
305350
306351 // Check if recursive.
307352 cmp (t3_owner, rthread);
308353 br (Assembler::NE, slow_path);
309354
310355 // Recursive.
311- increment (Address (t1_tagged_monitor, in_bytes (ObjectMonitor::recursions_offset ()) - monitor_tag), 1 );
356+ increment (recursions_address, 1 );
357+
358+ bind (monitor_locked);
359+ if (UseObjectMonitorTable) {
360+ str (t1_monitor, Address (box, BasicLock::object_monitor_cache_offset_in_bytes ()));
361+ }
312362 }
313363
314364 bind (locked);
@@ -331,13 +381,13 @@ void C2_MacroAssembler::fast_lock_lightweight(Register obj, Register t1,
331381 // C2 uses the value of Flags (NE vs EQ) to determine the continuation.
332382}
333383
334- void C2_MacroAssembler::fast_unlock_lightweight (Register obj, Register t1 , Register t2 ,
335- Register t3) {
384+ void C2_MacroAssembler::fast_unlock_lightweight (Register obj, Register box , Register t1 ,
385+ Register t2, Register t3) {
336386 assert (LockingMode == LM_LIGHTWEIGHT, " must be" );
337- assert_different_registers (obj, t1, t2, t3);
387+ assert_different_registers (obj, box, t1, t2, t3);
338388
339389 // Handle inflated monitor.
340- Label inflated, inflated_load_monitor ;
390+ Label inflated, inflated_load_mark ;
341391 // Finish fast unlock successfully. MUST branch to with flag == EQ
342392 Label unlocked;
343393 // Finish fast unlock unsuccessfully. MUST branch to with flag == NE
@@ -349,13 +399,15 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
349399
350400 { // Lightweight unlock
351401
402+ Label push_and_slow_path;
403+
352404 // Check if obj is top of lock-stack.
353405 ldrw (t2_top, Address (rthread, JavaThread::lock_stack_top_offset ()));
354406 subw (t2_top, t2_top, oopSize);
355407 ldr (t3_t , Address (rthread, t2_top));
356408 cmp (obj, t3_t );
357409 // Top of lock stack was not obj. Must be monitor.
358- br (Assembler::NE, inflated_load_monitor );
410+ br (Assembler::NE, inflated_load_mark );
359411
360412 // Pop lock-stack.
361413 DEBUG_ONLY (str (zr, Address (rthread, t2_top));)
@@ -372,7 +424,10 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
372424 ldr (t1_mark, Address (obj, oopDesc::mark_offset_in_bytes ()));
373425
374426 // Check header for monitor (0b10).
375- tbnz (t1_mark, exact_log2 (markWord::monitor_value), inflated);
427+ // Because we got here by popping (meaning we pushed in locked)
428+ // there will be no monitor in the box. So we need to push back the obj
429+ // so that the runtime can fix any potential anonymous owner.
430+ tbnz (t1_mark, exact_log2 (markWord::monitor_value), UseObjectMonitorTable ? push_and_slow_path : inflated);
376431
377432 // Try to unlock. Transition lock bits 0b00 => 0b01
378433 assert (oopDesc::mark_offset_in_bytes () == 0 , " required to avoid lea" );
@@ -381,6 +436,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
381436 /* acquire*/ false , /* release*/ true , /* weak*/ false , noreg);
382437 br (Assembler::EQ, unlocked);
383438
439+ bind (push_and_slow_path);
384440 // Compare and exchange failed.
385441 // Restore lock-stack and handle the unlock in runtime.
386442 DEBUG_ONLY (str (obj, Address (rthread, t2_top));)
@@ -391,7 +447,7 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
391447
392448
393449 { // Handle inflated monitor.
394- bind (inflated_load_monitor );
450+ bind (inflated_load_mark );
395451 ldr (t1_mark, Address (obj, oopDesc::mark_offset_in_bytes ()));
396452#ifdef ASSERT
397453 tbnz (t1_mark, exact_log2 (markWord::monitor_value), inflated);
@@ -412,12 +468,19 @@ void C2_MacroAssembler::fast_unlock_lightweight(Register obj, Register t1, Regis
412468 bind (check_done);
413469#endif
414470
415- // mark contains the tagged ObjectMonitor*.
416- const Register t1_monitor = t1_mark;
417- const uintptr_t monitor_tag = markWord::monitor_value;
471+ const Register t1_monitor = t1;
472+
473+ if (!UseObjectMonitorTable) {
474+ assert (t1_monitor == t1_mark, " should be the same here" );
418475
419- // Untag the monitor.
420- sub (t1_monitor, t1_mark, monitor_tag);
476+ // Untag the monitor.
477+ add (t1_monitor, t1_mark, -(int )markWord::monitor_value);
478+ } else {
479+ ldr (t1_monitor, Address (box, BasicLock::object_monitor_cache_offset_in_bytes ()));
480+ // null check with Flags == NE, no valid pointer below alignof(ObjectMonitor*)
481+ cmp (t1_monitor, checked_cast<uint8_t >(alignof (ObjectMonitor*)));
482+ br (Assembler::LO, slow_path);
483+ }
421484
422485 const Register t2_recursions = t2;
423486 Label not_recursive;
0 commit comments