< prev index next >

src/hotspot/cpu/riscv/macroAssembler_riscv.cpp

Print this page
*** 4480,5 ***
--- 4480,60 ---
        la_patchable(tmp, target, offset);
        jalr(x1, tmp, offset);
      });
    }
  }
+ 
+ // Attempt to fast-lock an object. Fall-through on success, branch to slow label
+ // on failure.
+ // Registers:
+ //  - obj: the object to be locked
+ //  - hdr: the header, already loaded from obj, will be destroyed
+ //  - tmp1, tmp2: temporary registers, will be destroyed
+ void MacroAssembler::fast_lock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
+   assert(UseFastLocking, "only used with fast-locking");
+   assert_different_registers(obj, hdr, tmp1, tmp2);
+ 
+   // Check if we would have space on lock-stack for the object.
+   ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
+   ld(tmp2, Address(xthread, JavaThread::lock_stack_limit_offset()));
+   bge(tmp1, tmp2, slow, true);
+ 
+   // Load (object->mark() | 1) into hdr
+   ori(hdr, hdr, markWord::unlocked_value);
+   // Clear lock-bits, into tmp2
+   xori(tmp2, hdr, markWord::unlocked_value);
+   // Try to swing header from unlocked to locked
+   Label success;
+   cmpxchgptr(hdr, tmp2, obj, tmp1, success, &slow);
+   bind(success);
+ 
+   // After successful lock, push object on lock-stack
+   // TODO: Can we avoid re-loading the current offset? The CAS above clobbers it.
+   // Maybe we could ensure that we have enough space on the lock stack more cleverly.
+   ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
+   sd(obj, Address(tmp1, 0));
+   add(tmp1, tmp1, oopSize);
+   sd(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
+ }
+ 
+ void MacroAssembler::fast_unlock(Register obj, Register hdr, Register tmp1, Register tmp2, Label& slow) {
+   assert(UseFastLocking, "only used with fast-locking");
+   assert_different_registers(obj, hdr, tmp1, tmp2);
+ 
+   // Load the expected old header (lock-bits cleared to indicate 'locked') into hdr
+   mv(tmp1, ~markWord::lock_mask_in_place);
+   andr(hdr, hdr, tmp1);
+ 
+   // Load the new header (unlocked) into tmp1
+   ori(tmp1, hdr, markWord::unlocked_value);
+ 
+   // Try to swing header from locked to unlocked
+   Label success;
+   cmpxchgptr(hdr, tmp1, obj, tmp2, success, &slow);
+   bind(success);
+ 
+   // After successful unlock, pop object from lock-stack
+   ld(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
+   sub(tmp1, tmp1, oopSize);
+   sd(tmp1, Address(xthread, JavaThread::lock_stack_current_offset()));
+ }
< prev index next >