< prev index next >

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

Print this page

 741     const Register tmp = c_rarg2;
 742     const Register obj_reg = c_rarg3; // Will contain the oop
 743 
 744     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
 745     const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
 746     const int mark_offset = lock_offset +
 747                             BasicLock::displaced_header_offset_in_bytes();
 748 
 749     Label slow_case;
 750 
 751     // Load object pointer into obj_reg %c_rarg3
 752     ldr(obj_reg, Address(lock_reg, obj_offset));
 753 
 754     if (DiagnoseSyncOnValueBasedClasses != 0) {
 755       load_klass(tmp, obj_reg);
 756       ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
 757       tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
 758       br(Assembler::NE, slow_case);
 759     }
 760 
 761     // Load (object->mark() | 1) into swap_reg
 762     ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 763     orr(swap_reg, rscratch1, 1);
 764 
 765     // Save (object->mark() | 1) into BasicLock's displaced header
 766     str(swap_reg, Address(lock_reg, mark_offset));
 767 
 768     assert(lock_offset == 0,
 769            "displached header must be first word in BasicObjectLock");
 770 
 771     Label fail;
 772     cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
 773 
 774     // Fast check for recursive lock.
 775     //
 776     // Can apply the optimization only if this is a stack lock
 777     // allocated in this thread. For efficiency, we can focus on
 778     // recently allocated stack locks (instead of reading the stack
 779     // base and checking whether 'mark' points inside the current
 780     // thread stack):
 781     //  1) (mark & 7) == 0, and
 782     //  2) sp <= mark < mark + os::pagesize()
 783     //
 784     // Warning: sp + os::pagesize can overflow the stack base. We must
 785     // neither apply the optimization for an inflated lock allocated
 786     // just above the thread stack (this is why condition 1 matters)
 787     // nor apply the optimization if the stack lock is inside the stack
 788     // of another thread. The latter is avoided even in case of overflow
 789     // because we have guard pages at the end of all stacks. Hence, if
 790     // we go over the stack base and hit the stack of another thread,
 791     // this should not be in a writeable area that could contain a
 792     // stack lock allocated by that thread. As a consequence, a stack
 793     // lock less than page size away from sp is guaranteed to be
 794     // owned by the current thread.
 795     //
 796     // These 3 tests can be done by evaluating the following
 797     // expression: ((mark - sp) & (7 - os::vm_page_size())),
 798     // assuming both stack pointer and pagesize have their
 799     // least significant 3 bits clear.
 800     // NOTE: the mark is in swap_reg %r0 as the result of cmpxchg
 801     // NOTE2: aarch64 does not like to subtract sp from rn so take a
 802     // copy
 803     mov(rscratch1, sp);
 804     sub(swap_reg, swap_reg, rscratch1);
 805     ands(swap_reg, swap_reg, (uint64_t)(7 - (int)os::vm_page_size()));
 806 
 807     // Save the test result, for recursive case, the result is zero
 808     str(swap_reg, Address(lock_reg, mark_offset));
 809     br(Assembler::EQ, count);
 810 





 811     bind(slow_case);
 812 
 813     // Call the runtime routine for slow case
 814     call_VM(noreg,
 815             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 816             lock_reg);
 817     b(done);
 818 
 819     bind(count);
 820     increment(Address(rthread, JavaThread::held_monitor_count_offset()));
 821 
 822     bind(done);
 823   }
 824 }
 825 
 826 
 827 // Unlocks an object. Used in monitorexit bytecode and
 828 // remove_activation.  Throws an IllegalMonitorException if object is
 829 // not locked by current thread.
 830 //
 831 // Args:
 832 //      c_rarg1: BasicObjectLock for lock
 833 //
 834 // Kills:
 835 //      r0
 836 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
 837 //      rscratch1, rscratch2 (scratch regs)
 838 void InterpreterMacroAssembler::unlock_object(Register lock_reg)
 839 {
 840   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
 841 
 842   if (UseHeavyMonitors) {
 843     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 844   } else {
 845     Label count, done;
 846 
 847     const Register swap_reg   = r0;
 848     const Register header_reg = c_rarg2;  // Will contain the old oopMark
 849     const Register obj_reg    = c_rarg3;  // Will contain the oop
 850 
 851     save_bcp(); // Save in case of exception
 852 
 853     // Convert from BasicObjectLock structure to object and BasicLock
 854     // structure Store the BasicLock address into %r0
 855     lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));


 856 
 857     // Load oop into obj_reg(%c_rarg3)
 858     ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
 859 
 860     // Free entry
 861     str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
 862 
 863     // Load the old header from BasicLock structure
 864     ldr(header_reg, Address(swap_reg,
 865                             BasicLock::displaced_header_offset_in_bytes()));
 866 
 867     // Test for recursion
 868     cbz(header_reg, count);














 869 
 870     // Atomic swap back the old header
 871     cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
 872 



 873     // Call the runtime routine for slow case.
 874     str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
 875     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 876     b(done);
 877 
 878     bind(count);
 879     decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
 880 
 881     bind(done);
 882     restore_bcp();
 883   }
 884 }
 885 
 886 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
 887                                                          Label& zero_continue) {
 888   assert(ProfileInterpreter, "must be profiling interpreter");
 889   ldr(mdp, Address(rfp, frame::interpreter_frame_mdp_offset * wordSize));
 890   cbz(mdp, zero_continue);
 891 }
 892 

 741     const Register tmp = c_rarg2;
 742     const Register obj_reg = c_rarg3; // Will contain the oop
 743 
 744     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
 745     const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
 746     const int mark_offset = lock_offset +
 747                             BasicLock::displaced_header_offset_in_bytes();
 748 
 749     Label slow_case;
 750 
 751     // Load object pointer into obj_reg %c_rarg3
 752     ldr(obj_reg, Address(lock_reg, obj_offset));
 753 
 754     if (DiagnoseSyncOnValueBasedClasses != 0) {
 755       load_klass(tmp, obj_reg);
 756       ldrw(tmp, Address(tmp, Klass::access_flags_offset()));
 757       tstw(tmp, JVM_ACC_IS_VALUE_BASED_CLASS);
 758       br(Assembler::NE, slow_case);
 759     }
 760 
 761     if (UseFastLocking) {
 762       ldr(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 763       fast_lock(obj_reg, tmp, rscratch1, rscratch2, slow_case);
 764       b(count);
 765     } else {
 766       // Load (object->mark() | 1) into swap_reg
 767       ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 768       orr(swap_reg, rscratch1, 1);
 769 
 770       // Save (object->mark() | 1) into BasicLock's displaced header
 771       str(swap_reg, Address(lock_reg, mark_offset));
 772 
 773       assert(lock_offset == 0,
 774              "displached header must be first word in BasicObjectLock");
 775 
 776       Label fail;
 777       cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
 778 
 779       // Fast check for recursive lock.
 780       //
 781       // Can apply the optimization only if this is a stack lock
 782       // allocated in this thread. For efficiency, we can focus on
 783       // recently allocated stack locks (instead of reading the stack
 784       // base and checking whether 'mark' points inside the current
 785       // thread stack):
 786       //  1) (mark & 7) == 0, and
 787       //  2) sp <= mark < mark + os::pagesize()
 788       //
 789       // Warning: sp + os::pagesize can overflow the stack base. We must
 790       // neither apply the optimization for an inflated lock allocated
 791       // just above the thread stack (this is why condition 1 matters)
 792       // nor apply the optimization if the stack lock is inside the stack
 793       // of another thread. The latter is avoided even in case of overflow
 794       // because we have guard pages at the end of all stacks. Hence, if
 795       // we go over the stack base and hit the stack of another thread,
 796       // this should not be in a writeable area that could contain a
 797       // stack lock allocated by that thread. As a consequence, a stack
 798       // lock less than page size away from sp is guaranteed to be
 799       // owned by the current thread.
 800       //
 801       // These 3 tests can be done by evaluating the following
 802       // expression: ((mark - sp) & (7 - os::vm_page_size())),
 803       // assuming both stack pointer and pagesize have their
 804       // least significant 3 bits clear.
 805       // NOTE: the mark is in swap_reg %r0 as the result of cmpxchg
 806       // NOTE2: aarch64 does not like to subtract sp from rn so take a
 807       // copy
 808       mov(rscratch1, sp);
 809       sub(swap_reg, swap_reg, rscratch1);
 810       ands(swap_reg, swap_reg, (uint64_t)(7 - (int)os::vm_page_size()));
 811 
 812       // Save the test result, for recursive case, the result is zero
 813       str(swap_reg, Address(lock_reg, mark_offset));
 814       br(Assembler::EQ, count);
 815     }
 816     bind(slow_case);
 817 
 818     // Call the runtime routine for slow case
 819     call_VM(noreg,
 820             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 821             UseFastLocking ? obj_reg : lock_reg);
 822     b(done);
 823 
 824     bind(count);
 825     increment(Address(rthread, JavaThread::held_monitor_count_offset()));
 826 
 827     bind(done);
 828   }
 829 }
 830 
 831 
 832 // Unlocks an object. Used in monitorexit bytecode and
 833 // remove_activation.  Throws an IllegalMonitorException if object is
 834 // not locked by current thread.
 835 //
 836 // Args:
 837 //      c_rarg1: BasicObjectLock for lock
 838 //
 839 // Kills:
 840 //      r0
 841 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
 842 //      rscratch1, rscratch2 (scratch regs)
 843 void InterpreterMacroAssembler::unlock_object(Register lock_reg)
 844 {
 845   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
 846 
 847   if (UseHeavyMonitors) {
 848     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 849   } else {
 850     Label count, done;
 851 
 852     const Register swap_reg   = r0;
 853     const Register header_reg = c_rarg2;  // Will contain the old oopMark
 854     const Register obj_reg    = c_rarg3;  // Will contain the oop
 855 
 856     save_bcp(); // Save in case of exception
 857 
 858     if (!UseFastLocking) {
 859       // Convert from BasicObjectLock structure to object and BasicLock
 860       // structure Store the BasicLock address into %r0
 861       lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
 862     }
 863 
 864     // Load oop into obj_reg(%c_rarg3)
 865     ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
 866 
 867     // Free entry
 868     str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
 869 
 870     if (UseFastLocking) {
 871       Label slow_case;

 872 
 873       // Check for non-symmetric locking. This is allowed by the spec and the interpreter
 874       // must handle it.
 875       Register tmp = header_reg;
 876       ldr(tmp, Address(rthread, JavaThread::lock_stack_current_offset()));
 877       ldr(tmp, Address(tmp, -oopSize));
 878       cmpoop(tmp, obj_reg);
 879       br(Assembler::NE, slow_case);
 880 
 881       ldr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 882       fast_unlock(obj_reg, header_reg, swap_reg, rscratch1, slow_case);
 883       b(count);
 884       bind(slow_case);
 885     } else {
 886       // Load the old header from BasicLock structure
 887       ldr(header_reg, Address(swap_reg,
 888                               BasicLock::displaced_header_offset_in_bytes()));
 889 
 890       // Test for recursion
 891       cbz(header_reg, count);
 892 
 893       // Atomic swap back the old header
 894       cmpxchg_obj_header(swap_reg, header_reg, obj_reg, rscratch1, count, /*fallthrough*/NULL);
 895     }
 896     // Call the runtime routine for slow case.
 897     str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
 898     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 899     b(done);
 900 
 901     bind(count);
 902     decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
 903 
 904     bind(done);
 905     restore_bcp();
 906   }
 907 }
 908 
 909 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
 910                                                          Label& zero_continue) {
 911   assert(ProfileInterpreter, "must be profiling interpreter");
 912   ldr(mdp, Address(rfp, frame::interpreter_frame_mdp_offset * wordSize));
 913   cbz(mdp, zero_continue);
 914 }
 915 
< prev index next >