651
652 const Register swap_reg = r0;
653 const Register tmp = c_rarg2;
654 const Register obj_reg = c_rarg3; // Will contain the oop
655
656 const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
657 const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
658 const int mark_offset = lock_offset +
659 BasicLock::displaced_header_offset_in_bytes();
660
661 Label slow_case;
662
663 // Load object pointer into obj_reg %c_rarg3
664 ldr(obj_reg, Address(lock_reg, obj_offset));
665
666 if (UseBiasedLocking) {
667 biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, done, &slow_case);
668 }
669
670 // Load (object->mark() | 1) into swap_reg
671 ldr(rscratch1, Address(obj_reg, 0));
672 orr(swap_reg, rscratch1, 1);
673
674 // Save (object->mark() | 1) into BasicLock's displaced header
675 str(swap_reg, Address(lock_reg, mark_offset));
676
677 assert(lock_offset == 0,
678 "displached header must be first word in BasicObjectLock");
679
680 Label fail;
681 if (PrintBiasedLockingStatistics) {
682 Label fast;
683 cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, fast, &fail);
684 bind(fast);
685 atomic_incw(Address((address)BiasedLocking::fast_path_entry_count_addr()),
686 rscratch2, rscratch1, tmp);
687 b(done);
688 bind(fail);
689 } else {
690 cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
691 }
692
693 // Test if the oopMark is an obvious stack pointer, i.e.,
694 // 1) (mark & 7) == 0, and
695 // 2) rsp <= mark < mark + os::pagesize()
696 //
697 // These 3 tests can be done by evaluating the following
698 // expression: ((mark - rsp) & (7 - os::vm_page_size())),
699 // assuming both stack pointer and pagesize have their
700 // least significant 3 bits clear.
760 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
761
762 // Load oop into obj_reg(%c_rarg3)
763 ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
764
765 // Free entry
766 str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
767
768 if (UseBiasedLocking) {
769 biased_locking_exit(obj_reg, header_reg, done);
770 }
771
772 // Load the old header from BasicLock structure
773 ldr(header_reg, Address(swap_reg,
774 BasicLock::displaced_header_offset_in_bytes()));
775
776 // Test for recursion
777 cbz(header_reg, done);
778
779 // Atomic swap back the old header
780 cmpxchgptr(swap_reg, header_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
781
782 // Call the runtime routine for slow case.
783 str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
784 call_VM(noreg,
785 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
786 lock_reg);
787
788 bind(done);
789
790 restore_bcp();
791 }
792 }
793
794 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
795 Label& zero_continue) {
796 assert(ProfileInterpreter, "must be profiling interpreter");
797 ldr(mdp, Address(rfp, frame::interpreter_frame_mdp_offset * wordSize));
798 cbz(mdp, zero_continue);
799 }
|
651
652 const Register swap_reg = r0;
653 const Register tmp = c_rarg2;
654 const Register obj_reg = c_rarg3; // Will contain the oop
655
656 const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
657 const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
658 const int mark_offset = lock_offset +
659 BasicLock::displaced_header_offset_in_bytes();
660
661 Label slow_case;
662
663 // Load object pointer into obj_reg %c_rarg3
664 ldr(obj_reg, Address(lock_reg, obj_offset));
665
666 if (UseBiasedLocking) {
667 biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp, false, done, &slow_case);
668 }
669
670 // Load (object->mark() | 1) into swap_reg
671 ldr(rscratch1, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
672 orr(swap_reg, rscratch1, 1);
673
674 // Save (object->mark() | 1) into BasicLock's displaced header
675 str(swap_reg, Address(lock_reg, mark_offset));
676
677 assert(lock_offset == 0,
678 "displached header must be first word in BasicObjectLock");
679
680 Label fail;
681 assert(oopDesc::mark_offset_in_bytes() == 0, "assumption");
682 if (PrintBiasedLockingStatistics) {
683 Label fast;
684 cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, fast, &fail);
685 bind(fast);
686 atomic_incw(Address((address)BiasedLocking::fast_path_entry_count_addr()),
687 rscratch2, rscratch1, tmp);
688 b(done);
689 bind(fail);
690 } else {
691 cmpxchgptr(swap_reg, lock_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
692 }
693
694 // Test if the oopMark is an obvious stack pointer, i.e.,
695 // 1) (mark & 7) == 0, and
696 // 2) rsp <= mark < mark + os::pagesize()
697 //
698 // These 3 tests can be done by evaluating the following
699 // expression: ((mark - rsp) & (7 - os::vm_page_size())),
700 // assuming both stack pointer and pagesize have their
701 // least significant 3 bits clear.
761 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
762
763 // Load oop into obj_reg(%c_rarg3)
764 ldr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
765
766 // Free entry
767 str(zr, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
768
769 if (UseBiasedLocking) {
770 biased_locking_exit(obj_reg, header_reg, done);
771 }
772
773 // Load the old header from BasicLock structure
774 ldr(header_reg, Address(swap_reg,
775 BasicLock::displaced_header_offset_in_bytes()));
776
777 // Test for recursion
778 cbz(header_reg, done);
779
780 // Atomic swap back the old header
781 assert(oopDesc::mark_offset_in_bytes() == 0, "assumption");
782 cmpxchgptr(swap_reg, header_reg, obj_reg, rscratch1, done, /*fallthrough*/NULL);
783
784 // Call the runtime routine for slow case.
785 str(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); // restore obj
786 call_VM(noreg,
787 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
788 lock_reg);
789
790 bind(done);
791
792 restore_bcp();
793 }
794 }
795
796 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
797 Label& zero_continue) {
798 assert(ProfileInterpreter, "must be profiling interpreter");
799 ldr(mdp, Address(rfp, frame::interpreter_frame_mdp_offset * wordSize));
800 cbz(mdp, zero_continue);
801 }
|