< prev index next >

src/hotspot/cpu/riscv/riscv.ad

Print this page
*** 2415,40 ***
      // Check for existing monitor
      __ andi(t0, disp_hdr, markWord::monitor_value);
      __ bnez(t0, object_has_monitor);
  
      if (!UseHeavyMonitors) {
!       // Set tmp to be (markWord of object | UNLOCK_VALUE).
!       __ ori(tmp, disp_hdr, markWord::unlocked_value);
! 
!       // Initialize the box. (Must happen before we update the object mark!)
!       __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
! 
!       // Compare object markWord with an unlocked value (tmp) and if
!       // equal exchange the stack address of our box with object markWord.
!       // On failure disp_hdr contains the possibly locked markWord.
!       __ cmpxchg(/*memory address*/oop, /*expected value*/tmp, /*new value*/box, Assembler::int64, Assembler::aq,
!                  Assembler::rl, /*result*/disp_hdr);
!       __ mv(flag, zr);
!       __ beq(disp_hdr, tmp, cont); // prepare zero flag and goto cont if we won the cas
! 
!       assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
! 
!       // If the compare-and-exchange succeeded, then we found an unlocked
!       // object, will have now locked it will continue at label cont
!       // We did not see an unlocked object so try the fast recursive case.
! 
!       // Check if the owner is self by comparing the value in the
!       // markWord of object (disp_hdr) with the stack pointer.
!       __ sub(disp_hdr, disp_hdr, sp);
!       __ mv(tmp, (intptr_t) (~(os::vm_page_size()-1) | (uintptr_t)markWord::lock_mask_in_place));
!       // If (mark & lock_mask) == 0 and mark - sp < page_size, we are stack-locking and goto cont,
!       // hence we can store 0 as the displaced header in the box, which indicates that it is a
!       // recursive lock.
!       __ andr(tmp/*==0?*/, disp_hdr, tmp);
!       __ sd(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
!       __ mv(flag, tmp); // we can use the value of tmp as the result here
      } else {
        __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path
      }
  
      __ j(cont);
--- 2415,50 ---
      // Check for existing monitor
      __ andi(t0, disp_hdr, markWord::monitor_value);
      __ bnez(t0, object_has_monitor);
  
      if (!UseHeavyMonitors) {
!       if (UseFastLocking) {
!         Label slow;
!         __ fast_lock(oop, disp_hdr, tmp, t0, slow);
!         // Indicate success at cont.
!         __ mv(flag, zr);
!         __ j(cont);
!         __ bind(slow);
!         __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path
!       } else {
!         // Set tmp to be (markWord of object | UNLOCK_VALUE).
!         __ ori(tmp, disp_hdr, markWord::unlocked_value);
! 
!         // Initialize the box. (Must happen before we update the object mark!)
!         __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
! 
!         // Compare object markWord with an unlocked value (tmp) and if
!         // equal exchange the stack address of our box with object markWord.
!         // On failure disp_hdr contains the possibly locked markWord.
!         __ cmpxchg(/*memory address*/oop, /*expected value*/tmp, /*new value*/box, Assembler::int64, Assembler::aq,
!                    Assembler::rl, /*result*/disp_hdr);
!         __ mv(flag, zr);
!         __ beq(disp_hdr, tmp, cont); // prepare zero flag and goto cont if we won the cas
! 
!         assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
! 
!         // If the compare-and-exchange succeeded, then we found an unlocked
!         // object, will have now locked it will continue at label cont
!         // We did not see an unlocked object so try the fast recursive case.
! 
!         // Check if the owner is self by comparing the value in the
+         // markWord of object (disp_hdr) with the stack pointer.
+         __ sub(disp_hdr, disp_hdr, sp);
+         __ mv(tmp, (intptr_t) (~(os::vm_page_size()-1) | (uintptr_t)markWord::lock_mask_in_place));
+         // If (mark & lock_mask) == 0 and mark - sp < page_size, we are stack-locking and goto cont,
+         // hence we can store 0 as the displaced header in the box, which indicates that it is a
+         // recursive lock.
+         __ andr(tmp/*==0?*/, disp_hdr, tmp);
+         __ sd(tmp/*==0, perhaps*/, Address(box, BasicLock::displaced_header_offset_in_bytes()));
+         __ mv(flag, tmp); // we can use the value of tmp as the result here
+       }
      } else {
        __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow-path
      }
  
      __ j(cont);

*** 2461,16 ***
      // Try to CAS m->owner from NULL to current thread.
      __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes() - markWord::monitor_value));
      __ cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/xthread, Assembler::int64, Assembler::aq,
               Assembler::rl, /*result*/flag); // cas succeeds if flag == zr(expected)
  
!     // Store a non-null value into the box to avoid looking like a re-entrant
!     // lock. The fast-path monitor unlock code checks for
!     // markWord::monitor_value so use markWord::unused_mark which has the
!     // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
!     __ mv(tmp, (address)markWord::unused_mark().value());
!     __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
  
      __ beqz(flag, cont); // CAS success means locking succeeded
  
      __ bne(flag, xthread, cont); // Check for recursive locking
  
--- 2471,18 ---
      // Try to CAS m->owner from NULL to current thread.
      __ add(tmp, disp_hdr, (ObjectMonitor::owner_offset_in_bytes() - markWord::monitor_value));
      __ cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/xthread, Assembler::int64, Assembler::aq,
               Assembler::rl, /*result*/flag); // cas succeeds if flag == zr(expected)
  
!     if (!UseFastLocking) {
!       // Store a non-null value into the box to avoid looking like a re-entrant
!       // lock. The fast-path monitor unlock code checks for
!       // markWord::monitor_value so use markWord::unused_mark which has the
!       // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
!       __ mv(tmp, (address)markWord::unused_mark().value());
+       __ sd(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
+     }
  
      __ beqz(flag, cont); // CAS success means locking succeeded
  
      __ bne(flag, xthread, cont); // Check for recursive locking
  

*** 2499,11 ***
      Label object_has_monitor;
      Label no_count;
  
      assert_different_registers(oop, box, tmp, disp_hdr, flag);
  
!     if (!UseHeavyMonitors) {
        // Find the lock address and load the displaced header from the stack.
        __ ld(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
  
        // If the displaced header is 0, we have a recursive unlock.
        __ mv(flag, disp_hdr);
--- 2511,11 ---
      Label object_has_monitor;
      Label no_count;
  
      assert_different_registers(oop, box, tmp, disp_hdr, flag);
  
!     if (!UseHeavyMonitors && !UseFastLocking) {
        // Find the lock address and load the displaced header from the stack.
        __ ld(disp_hdr, Address(box, BasicLock::displaced_header_offset_in_bytes()));
  
        // If the displaced header is 0, we have a recursive unlock.
        __ mv(flag, disp_hdr);

*** 2514,17 ***
      __ ld(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
      __ andi(t0, tmp, markWord::monitor_value);
      __ bnez(t0, object_has_monitor);
  
      if (!UseHeavyMonitors) {
!       // Check if it is still a light weight lock, this is true if we
!       // see the stack address of the basicLock in the markWord of the
!       // object.
  
!       __ cmpxchg(/*memory address*/oop, /*expected value*/box, /*new value*/disp_hdr, Assembler::int64, Assembler::relaxed,
!                  Assembler::rl, /*result*/tmp);
!       __ xorr(flag, box, tmp); // box == tmp if cas succeeds
      } else {
        __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path
      }
      __ j(cont);
  
--- 2526,28 ---
      __ ld(tmp, Address(oop, oopDesc::mark_offset_in_bytes()));
      __ andi(t0, tmp, markWord::monitor_value);
      __ bnez(t0, object_has_monitor);
  
      if (!UseHeavyMonitors) {
!       if (UseFastLocking) {
!         Label slow;
!         __ fast_unlock(oop, tmp, box, disp_hdr, slow);
+ 
+         // Indicate success at cont.
+         __ mv(flag, zr);
+         __ j(cont);
+         __ bind(slow);
+         __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path
+       } else {
+         // Check if it is still a light weight lock, this is true if we
+         // see the stack address of the basicLock in the markWord of the
+         // object.
  
!         __ cmpxchg(/*memory address*/oop, /*expected value*/box, /*new value*/disp_hdr, Assembler::int64, Assembler::relaxed,
!                    Assembler::rl, /*result*/tmp);
!         __ xorr(flag, box, tmp); // box == tmp if cas succeeds
+       }
      } else {
        __ mv(flag, 1); // Set non-zero flag to indicate 'failure' -> take slow path
      }
      __ j(cont);
  

*** 2532,10 ***
--- 2555,21 ---
  
      // Handle existing monitor.
      __ bind(object_has_monitor);
      STATIC_ASSERT(markWord::monitor_value <= INT_MAX);
      __ add(tmp, tmp, -(int)markWord::monitor_value); // monitor
+ 
+     if (UseFastLocking) {
+       Label L;
+       __ ld(disp_hdr, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
+       __ mv(t0, (unsigned char)(intptr_t)ANONYMOUS_OWNER);
+       __ bne(disp_hdr, t0, L);
+       __ mv(flag, 1); // Indicate failure at cont -- dive into slow-path.
+       __ j(cont);
+       __ bind(L);
+     }
+ 
      __ ld(disp_hdr, Address(tmp, ObjectMonitor::recursions_offset_in_bytes()));
  
      Label notRecursive;
      __ beqz(disp_hdr, notRecursive); // Will be 0 if not recursive.
  
< prev index next >