< prev index next >

src/hotspot/cpu/riscv/interp_masm_riscv.cpp

Print this page

 709   // If we're returning to interpreted code we will shortly be
 710   // adjusting SP to allow some space for ESP.  If we're returning to
 711   // compiled code the saved sender SP was saved in sender_sp, so this
 712   // restores it.
 713   andi(sp, esp, -16);
 714 }
 715 
 716 // Lock object
 717 //
 718 // Args:
 719 //      c_rarg1: BasicObjectLock to be used for locking
 720 //
 721 // Kills:
 722 //      x10
 723 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5, .. (param regs)
 724 //      t0, t1 (temp regs)
 725 void InterpreterMacroAssembler::lock_object(Register lock_reg)
 726 {
 727   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
 728   if (LockingMode == LM_MONITOR) {

 729     call_VM(noreg,
 730             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 731             lock_reg);

 732   } else {
 733     Label count, done;
 734 
 735     const Register swap_reg = x10;
 736     const Register tmp = c_rarg2;
 737     const Register obj_reg = c_rarg3; // Will contain the oop
 738     const Register tmp2 = c_rarg4;
 739     const Register tmp3 = c_rarg5;
 740 
 741     const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
 742     const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
 743     const int mark_offset = lock_offset +
 744                             BasicLock::displaced_header_offset_in_bytes();
 745 
 746     Label slow_case;
 747 
 748     // Load object pointer into obj_reg c_rarg3
 749     ld(obj_reg, Address(lock_reg, obj_offset));
 750 
 751     if (DiagnoseSyncOnValueBasedClasses != 0) {
 752       load_klass(tmp, obj_reg);
 753       lbu(tmp, Address(tmp, Klass::misc_flags_offset()));
 754       test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class));
 755       bnez(tmp, slow_case);
 756     }
 757 
 758     if (LockingMode == LM_LIGHTWEIGHT) {
 759       lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
 760       j(count);
 761     } else if (LockingMode == LM_LEGACY) {
 762       // Load (object->mark() | 1) into swap_reg
 763       ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 764       ori(swap_reg, t0, 1);
 765 
 766       // Save (object->mark() | 1) into BasicLock's displaced header
 767       sd(swap_reg, Address(lock_reg, mark_offset));
 768 
 769       assert(lock_offset == 0,
 770              "displached header must be first word in BasicObjectLock");
 771 
 772       cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, tmp, count, /*fallthrough*/nullptr);
 773 
 774       // Test if the oopMark is an obvious stack pointer, i.e.,
 775       //  1) (mark & 7) == 0, and
 776       //  2) sp <= mark < mark + os::pagesize()
 777       //
 778       // These 3 tests can be done by evaluating the following
 779       // expression: ((mark - sp) & (7 - os::vm_page_size())),
 780       // assuming both stack pointer and pagesize have their
 781       // least significant 3 bits clear.
 782       // NOTE: the oopMark is in swap_reg x10 as the result of cmpxchg
 783       sub(swap_reg, swap_reg, sp);
 784       mv(t0, (int64_t)(7 - (int)os::vm_page_size()));
 785       andr(swap_reg, swap_reg, t0);
 786 
 787       // Save the test result, for recursive case, the result is zero
 788       sd(swap_reg, Address(lock_reg, mark_offset));
 789       beqz(swap_reg, count);




 790     }
 791 
 792     bind(slow_case);
 793 
 794     // Call the runtime routine for slow case

 795     call_VM(noreg,
 796             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 797             lock_reg);
 798     j(done);
 799 
 800     bind(count);
 801     increment(Address(xthread, JavaThread::held_monitor_count_offset()));
 802 
 803     bind(done);
 804   }
 805 }
 806 
 807 
 808 // Unlocks an object. Used in monitorexit bytecode and
 809 // remove_activation.  Throws an IllegalMonitorException if object is
 810 // not locked by current thread.
 811 //
 812 // Args:
 813 //      c_rarg1: BasicObjectLock for lock
 814 //
 815 // Kills:
 816 //      x10
 817 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, ... (param regs)
 818 //      t0, t1 (temp regs)
 819 void InterpreterMacroAssembler::unlock_object(Register lock_reg)
 820 {
 821   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");

 827 
 828     const Register swap_reg   = x10;
 829     const Register header_reg = c_rarg2;  // Will contain the old oopMark
 830     const Register obj_reg    = c_rarg3;  // Will contain the oop
 831     const Register tmp_reg    = c_rarg4;  // Temporary used by lightweight_unlock
 832 
 833     save_bcp(); // Save in case of exception
 834 
 835     if (LockingMode != LM_LIGHTWEIGHT) {
 836       // Convert from BasicObjectLock structure to object and BasicLock
 837       // structure Store the BasicLock address into x10
 838       la(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
 839     }
 840 
 841     // Load oop into obj_reg(c_rarg3)
 842     ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
 843 
 844     // Free entry
 845     sd(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
 846 

 847     if (LockingMode == LM_LIGHTWEIGHT) {
 848       Label slow_case;
 849       lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
 850       j(count);
 851 
 852       bind(slow_case);
 853     } else if (LockingMode == LM_LEGACY) {
 854       // Load the old header from BasicLock structure
 855       ld(header_reg, Address(swap_reg,
 856                              BasicLock::displaced_header_offset_in_bytes()));
 857 
 858       // Test for recursion
 859       beqz(header_reg, count);
 860 
 861       // Atomic swap back the old header
 862       cmpxchg_obj_header(swap_reg, header_reg, obj_reg, tmp_reg, count, /*fallthrough*/nullptr);




 863     }
 864 

 865     // Call the runtime routine for slow case.
 866     sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
 867     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 868 
 869     j(done);
 870 
 871     bind(count);
 872     decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
 873 
 874     bind(done);
 875 
 876     restore_bcp();
 877   }
 878 }
 879 
 880 
 881 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
 882                                                          Label& zero_continue) {
 883   assert(ProfileInterpreter, "must be profiling interpreter");
 884   ld(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
 885   beqz(mdp, zero_continue);
 886 }
 887 
 888 // Set the method data pointer for the current bcp.
 889 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
 890   assert(ProfileInterpreter, "must be profiling interpreter");
 891   Label set_mdp;
 892   push_reg(RegSet::of(x10, x11), sp); // save x10, x11
 893 
 894   // Test MDO to avoid the call if it is null.
 895   ld(x10, Address(xmethod, in_bytes(Method::method_data_offset())));

 709   // If we're returning to interpreted code we will shortly be
 710   // adjusting SP to allow some space for ESP.  If we're returning to
 711   // compiled code the saved sender SP was saved in sender_sp, so this
 712   // restores it.
 713   andi(sp, esp, -16);
 714 }
 715 
 716 // Lock object
 717 //
 718 // Args:
 719 //      c_rarg1: BasicObjectLock to be used for locking
 720 //
 721 // Kills:
 722 //      x10
 723 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5, .. (param regs)
 724 //      t0, t1 (temp regs)
 725 void InterpreterMacroAssembler::lock_object(Register lock_reg)
 726 {
 727   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
 728   if (LockingMode == LM_MONITOR) {
 729     push_cont_fastpath();
 730     call_VM(noreg,
 731             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 732             lock_reg);
 733     pop_cont_fastpath();
 734   } else {
 735     Label count, done;
 736 
 737     const Register swap_reg = x10;
 738     const Register tmp = c_rarg2;
 739     const Register obj_reg = c_rarg3; // Will contain the oop
 740     const Register tmp2 = c_rarg4;
 741     const Register tmp3 = c_rarg5;
 742 
 743     const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
 744     const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
 745     const int mark_offset = lock_offset +
 746                             BasicLock::displaced_header_offset_in_bytes();
 747 
 748     Label slow_case;
 749 
 750     // Load object pointer into obj_reg c_rarg3
 751     ld(obj_reg, Address(lock_reg, obj_offset));
 752 
 753     if (DiagnoseSyncOnValueBasedClasses != 0) {
 754       load_klass(tmp, obj_reg);
 755       lbu(tmp, Address(tmp, Klass::misc_flags_offset()));
 756       test_bit(tmp, tmp, exact_log2(KlassFlags::_misc_is_value_based_class));
 757       bnez(tmp, slow_case);
 758     }
 759 
 760     if (LockingMode == LM_LIGHTWEIGHT) {
 761       lightweight_lock(lock_reg, obj_reg, tmp, tmp2, tmp3, slow_case);
 762       j(done);
 763     } else if (LockingMode == LM_LEGACY) {
 764       // Load (object->mark() | 1) into swap_reg
 765       ld(t0, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
 766       ori(swap_reg, t0, 1);
 767 
 768       // Save (object->mark() | 1) into BasicLock's displaced header
 769       sd(swap_reg, Address(lock_reg, mark_offset));
 770 
 771       assert(lock_offset == 0,
 772              "displached header must be first word in BasicObjectLock");
 773 
 774       cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, tmp, count, /*fallthrough*/nullptr);
 775 
 776       // Test if the oopMark is an obvious stack pointer, i.e.,
 777       //  1) (mark & 7) == 0, and
 778       //  2) sp <= mark < mark + os::pagesize()
 779       //
 780       // These 3 tests can be done by evaluating the following
 781       // expression: ((mark - sp) & (7 - os::vm_page_size())),
 782       // assuming both stack pointer and pagesize have their
 783       // least significant 3 bits clear.
 784       // NOTE: the oopMark is in swap_reg x10 as the result of cmpxchg
 785       sub(swap_reg, swap_reg, sp);
 786       mv(t0, (int64_t)(7 - (int)os::vm_page_size()));
 787       andr(swap_reg, swap_reg, t0);
 788 
 789       // Save the test result, for recursive case, the result is zero
 790       sd(swap_reg, Address(lock_reg, mark_offset));
 791       bnez(swap_reg, slow_case);
 792 
 793       bind(count);
 794       inc_held_monitor_count();
 795       j(done);
 796     }
 797 
 798     bind(slow_case);
 799 
 800     // Call the runtime routine for slow case
 801     push_cont_fastpath();
 802     call_VM(noreg,
 803             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 804             lock_reg);
 805     pop_cont_fastpath();



 806 
 807     bind(done);
 808   }
 809 }
 810 
 811 
 812 // Unlocks an object. Used in monitorexit bytecode and
 813 // remove_activation.  Throws an IllegalMonitorException if object is
 814 // not locked by current thread.
 815 //
 816 // Args:
 817 //      c_rarg1: BasicObjectLock for lock
 818 //
 819 // Kills:
 820 //      x10
 821 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, ... (param regs)
 822 //      t0, t1 (temp regs)
 823 void InterpreterMacroAssembler::unlock_object(Register lock_reg)
 824 {
 825   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");

 831 
 832     const Register swap_reg   = x10;
 833     const Register header_reg = c_rarg2;  // Will contain the old oopMark
 834     const Register obj_reg    = c_rarg3;  // Will contain the oop
 835     const Register tmp_reg    = c_rarg4;  // Temporary used by lightweight_unlock
 836 
 837     save_bcp(); // Save in case of exception
 838 
 839     if (LockingMode != LM_LIGHTWEIGHT) {
 840       // Convert from BasicObjectLock structure to object and BasicLock
 841       // structure Store the BasicLock address into x10
 842       la(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
 843     }
 844 
 845     // Load oop into obj_reg(c_rarg3)
 846     ld(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
 847 
 848     // Free entry
 849     sd(zr, Address(lock_reg, BasicObjectLock::obj_offset()));
 850 
 851     Label slow_case;
 852     if (LockingMode == LM_LIGHTWEIGHT) {

 853       lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
 854       j(done);


 855     } else if (LockingMode == LM_LEGACY) {
 856       // Load the old header from BasicLock structure
 857       ld(header_reg, Address(swap_reg,
 858                              BasicLock::displaced_header_offset_in_bytes()));
 859 
 860       // Test for recursion
 861       beqz(header_reg, count);
 862 
 863       // Atomic swap back the old header
 864       cmpxchg_obj_header(swap_reg, header_reg, obj_reg, tmp_reg, count, &slow_case);
 865 
 866       bind(count);
 867       dec_held_monitor_count();
 868       j(done);
 869     }
 870 
 871     bind(slow_case);
 872     // Call the runtime routine for slow case.
 873     sd(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset())); // restore obj
 874     call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg);
 875 





 876     bind(done);

 877     restore_bcp();
 878   }
 879 }
 880 
 881 
 882 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
 883                                                          Label& zero_continue) {
 884   assert(ProfileInterpreter, "must be profiling interpreter");
 885   ld(mdp, Address(fp, frame::interpreter_frame_mdp_offset * wordSize));
 886   beqz(mdp, zero_continue);
 887 }
 888 
 889 // Set the method data pointer for the current bcp.
 890 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
 891   assert(ProfileInterpreter, "must be profiling interpreter");
 892   Label set_mdp;
 893   push_reg(RegSet::of(x10, x11), sp); // save x10, x11
 894 
 895   // Test MDO to avoid the call if it is null.
 896   ld(x10, Address(xmethod, in_bytes(Method::method_data_offset())));
< prev index next >