< prev index next >

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

Print this page
@@ -728,94 +728,46 @@
  //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)
  //      rscratch1, rscratch2 (scratch regs)
  void InterpreterMacroAssembler::lock_object(Register lock_reg)
  {
    assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
+ 
+   const Register obj_reg = c_rarg3; // Will contain the oop
+   const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
+ 
+   // Load object pointer into obj_reg %c_rarg3
+   ldr(obj_reg, Address(lock_reg, obj_offset));
+ 
    if (UseHeavyMonitors) {
      call_VM(noreg,
              CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
-             lock_reg);
+             obj_reg);
    } else {
      Label count, done;
  
      const Register swap_reg = r0;
      const Register tmp = c_rarg2;
-     const Register obj_reg = c_rarg3; // Will contain the oop
- 
-     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
-     const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
-     const int mark_offset = lock_offset +
-                             BasicLock::displaced_header_offset_in_bytes();
  
      Label slow_case;
  
-     // Load object pointer into obj_reg %c_rarg3
-     ldr(obj_reg, Address(lock_reg, obj_offset));
- 
      if (DiagnoseSyncOnValueBasedClasses != 0) {
        load_klass(tmp, obj_reg);
        ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
        tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
        br(Assembler::NE, slow_case);
      }
  
-     // Load (object->mark() | 1) into swap_reg
-     ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
-     orr(swap_reg, rscratch1, 1);
- 
-     // Save (object->mark() | 1) into BasicLock's displaced header
-     str(swap_reg, Address(lock_reg, mark_offset));
- 
-     assert(lock_offset == 0,
-            "displached header must be first word in BasicObjectLock");
- 
-     Label fail;
-     cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
- 
-     // Fast check for recursive lock.
-     //
-     // Can apply the optimization only if this is a stack lock
-     // allocated in this thread. For efficiency, we can focus on
-     // recently allocated stack locks (instead of reading the stack
-     // base and checking whether 'mark' points inside the current
-     // thread stack):
-     //  1) (mark & 7) == 0, and
-     //  2) sp <= mark < mark + os::pagesize()
-     //
-     // Warning: sp + os::pagesize can overflow the stack base. We must
-     // neither apply the optimization for an inflated lock allocated
-     // just above the thread stack (this is why condition 1 matters)
-     // nor apply the optimization if the stack lock is inside the stack
-     // of another thread. The latter is avoided even in case of overflow
-     // because we have guard pages at the end of all stacks. Hence, if
-     // we go over the stack base and hit the stack of another thread,
-     // this should not be in a writeable area that could contain a
-     // stack lock allocated by that thread. As a consequence, a stack
-     // lock less than page size away from sp is guaranteed to be
-     // owned by the current thread.
-     //
-     // These 3 tests can be done by evaluating the following
-     // expression: ((mark - sp) & (7 - os::vm_page_size())),
-     // assuming both stack pointer and pagesize have their
-     // least significant 3 bits clear.
-     // NOTE: the mark is in swap_reg %r0 as the result of cmpxchg
-     // NOTE2: aarch64 does not like to subtract sp from rn so take a
-     // copy
-     mov(rscratch1, sp);
-     sub(swap_reg, swap_reg, rscratch1);
-     ands(swap_reg, swap_reg, (uint64_t)(7 - os::vm_page_size()));
- 
-     // Save the test result, for recursive case, the result is zero
-     str(swap_reg, Address(lock_reg, mark_offset));
-     br(Assembler::EQ, count);
+     ldr(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
+     fast_lock(obj_reg, tmp, rscratch1, swap_reg, rscratch2, slow_case);
+     b(count);
  
      bind(slow_case);
  
      // Call the runtime routine for slow case
      call_VM(noreg,
              CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
-             lock_reg);
+             obj_reg);
      b(done);
  
      bind(count);
      increment(Address(rthread, JavaThread::held_monitor_count_offset()));
  

@@ -837,44 +789,41 @@
  //      rscratch1, rscratch2 (scratch regs)
  void InterpreterMacroAssembler::unlock_object(Register lock_reg)
  {
    assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
  
+   const Register obj_reg    = c_rarg3;  // Will contain the oop
+ 
+   // Load oop into obj_reg(%c_rarg3)
+   ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
+ 
+   // Free entry
+   str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
+ 
    if (UseHeavyMonitors) {
-     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
+     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), obj_reg);
    } else {
-     Label count, done;
+     Label count, done, slow_case;
  
      const Register swap_reg   = r0;
      const Register header_reg = c_rarg2;  // Will contain the old oopMark
-     const Register obj_reg    = c_rarg3;  // Will contain the oop
  
      save_bcp(); // Save in case of exception
  
-     // Convert from BasicObjectLock structure to object and BasicLock
-     // structure Store the BasicLock address into %r0
-     lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
- 
-     // Load oop into obj_reg(%c_rarg3)
-     ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
- 
-     // Free entry
-     str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
+     // Check for non-symmetric locking. This is allowed by the spec and the interpreter
+     // must handle it.
+     ldr(header_reg, Address(rthread, Thread::lock_stack_current_offset()));
+     cmpoop(header_reg, obj_reg);
+     br(Assembler::NE, slow_case);
  
-     // Load the old header from BasicLock structure
-     ldr(header_reg, Address(swap_reg,
-                             BasicLock::displaced_header_offset_in_bytes()));
- 
-     // Test for recursion
-     cbz(header_reg, count);
- 
-     // Atomic swap back the old header
-     cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
+     ldr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
+     fast_unlock(obj_reg, header_reg, swap_reg, rscratch1, slow_case);
+     b(count);
  
      // Call the runtime routine for slow case.
-     str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
-     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
+     bind(slow_case);
+     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), obj_reg);
      b(done);
  
      bind(count);
      decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
  

@@ -1633,11 +1582,12 @@
    cbnz(obj, update);
    orptr(mdo_addr, TypeEntries::null_seen);
    b(next);
  
    bind(update);
-   load_klass(obj, obj);
+   load_klass(rscratch1, obj);
+   mov(obj, rscratch1);
  
    ldr(rscratch1, mdo_addr);
    eor(obj, obj, rscratch1);
    tst(obj, TypeEntries::type_klass_mask);
    br(Assembler::EQ, next); // klass seen before, nothing to
< prev index next >