846 mtlr(R0);
847 BLOCK_COMMENT("} remove_activation");
848 }
849
850 // Lock object
851 //
852 // Registers alive
853 // monitor - Address of the BasicObjectLock to be used for locking,
854 // which must be initialized with the object to lock.
855 // object - Address of the object to be locked.
856 //
857 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
858 if (UseHeavyMonitors) {
859 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
860 monitor, /*check_for_exceptions=*/true);
861 } else {
862 // template code:
863 //
864 // markOop displaced_header = obj->mark().set_unlocked();
865 // monitor->lock()->set_displaced_header(displaced_header);
866 // if (Atomic::cmpxchg_ptr(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
867 // // We stored the monitor address into the object's mark word.
868 // } else if (THREAD->is_lock_owned((address)displaced_header))
869 // // Simple recursive case.
870 // monitor->lock()->set_displaced_header(NULL);
871 // } else {
872 // // Slow path.
873 // InterpreterRuntime::monitorenter(THREAD, monitor);
874 // }
875
876 const Register displaced_header = R7_ARG5;
877 const Register object_mark_addr = R8_ARG6;
878 const Register current_header = R9_ARG7;
879 const Register tmp = R10_ARG8;
880
881 Label done;
882 Label cas_failed, slow_case;
883
884 assert_different_registers(displaced_header, object_mark_addr, current_header, tmp);
885
886 // markOop displaced_header = obj->mark().set_unlocked();
887
888 // Load markOop from object into displaced_header.
889 ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
890
891 if (UseBiasedLocking) {
892 biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case);
893 }
894
895 // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
896 ori(displaced_header, displaced_header, markOopDesc::unlocked_value);
897
898 // monitor->lock()->set_displaced_header(displaced_header);
899
900 // Initialize the box (Must happen before we update the object mark!).
901 std(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
902 BasicLock::displaced_header_offset_in_bytes(), monitor);
903
904 // if (Atomic::cmpxchg_ptr(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
905
906 // Store stack address of the BasicObjectLock (this is monitor) into object.
907 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
908
909 // Must fence, otherwise, preceding store(s) may float below cmpxchg.
910 // CmpxchgX sets CCR0 to cmpX(current, displaced).
911 cmpxchgd(/*flag=*/CCR0,
912 /*current_value=*/current_header,
913 /*compare_value=*/displaced_header, /*exchange_value=*/monitor,
914 /*where=*/object_mark_addr,
915 MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
916 MacroAssembler::cmpxchgx_hint_acquire_lock(),
917 noreg,
918 &cas_failed,
919 /*check without membar and ldarx first*/true);
920
921 // If the compare-and-exchange succeeded, then we found an unlocked
922 // object and we have now locked it.
923 b(done);
924 bind(cas_failed);
960 }
961
962 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
963 //
964 // Registers alive
965 // monitor - Address of the BasicObjectLock to be used for locking,
966 // which must be initialized with the object to lock.
967 //
968 // Throw IllegalMonitorException if object is not locked by current thread.
969 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
970 if (UseHeavyMonitors) {
971 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
972 monitor, check_for_exceptions);
973 } else {
974
975 // template code:
976 //
977 // if ((displaced_header = monitor->displaced_header()) == NULL) {
978 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
979 // monitor->set_obj(NULL);
980 // } else if (Atomic::cmpxchg_ptr(displaced_header, obj->mark_addr(), monitor) == monitor) {
981 // // We swapped the unlocked mark in displaced_header into the object's mark word.
982 // monitor->set_obj(NULL);
983 // } else {
984 // // Slow path.
985 // InterpreterRuntime::monitorexit(THREAD, monitor);
986 // }
987
988 const Register object = R7_ARG5;
989 const Register displaced_header = R8_ARG6;
990 const Register object_mark_addr = R9_ARG7;
991 const Register current_header = R10_ARG8;
992
993 Label free_slot;
994 Label slow_case;
995
996 assert_different_registers(object, displaced_header, object_mark_addr, current_header);
997
998 if (UseBiasedLocking) {
999 // The object address from the monitor is in object.
1000 ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor);
1001 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1002 biased_locking_exit(CCR0, object, displaced_header, free_slot);
1003 }
1004
1005 // Test first if we are in the fast recursive case.
1006 ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
1007 BasicLock::displaced_header_offset_in_bytes(), monitor);
1008
1009 // If the displaced header is zero, we have a recursive unlock.
1010 cmpdi(CCR0, displaced_header, 0);
1011 beq(CCR0, free_slot); // recursive unlock
1012
1013 // } else if (Atomic::cmpxchg_ptr(displaced_header, obj->mark_addr(), monitor) == monitor) {
1014 // // We swapped the unlocked mark in displaced_header into the object's mark word.
1015 // monitor->set_obj(NULL);
1016
1017 // If we still have a lightweight lock, unlock the object and be done.
1018
1019 // The object address from the monitor is in object.
1020 if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); }
1021 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
1022
1023 // We have the displaced header in displaced_header. If the lock is still
1024 // lightweight, it will contain the monitor address and we'll store the
1025 // displaced header back into the object's mark word.
1026 // CmpxchgX sets CCR0 to cmpX(current, monitor).
1027 cmpxchgd(/*flag=*/CCR0,
1028 /*current_value=*/current_header,
1029 /*compare_value=*/monitor, /*exchange_value=*/displaced_header,
1030 /*where=*/object_mark_addr,
1031 MacroAssembler::MemBarRel,
1032 MacroAssembler::cmpxchgx_hint_release_lock(),
1033 noreg,
|
846 mtlr(R0);
847 BLOCK_COMMENT("} remove_activation");
848 }
849
850 // Lock object
851 //
852 // Registers alive
853 // monitor - Address of the BasicObjectLock to be used for locking,
854 // which must be initialized with the object to lock.
855 // object - Address of the object to be locked.
856 //
857 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
858 if (UseHeavyMonitors) {
859 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
860 monitor, /*check_for_exceptions=*/true);
861 } else {
862 // template code:
863 //
864 // markOop displaced_header = obj->mark().set_unlocked();
865 // monitor->lock()->set_displaced_header(displaced_header);
866 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
867 // // We stored the monitor address into the object's mark word.
868 // } else if (THREAD->is_lock_owned((address)displaced_header))
869 // // Simple recursive case.
870 // monitor->lock()->set_displaced_header(NULL);
871 // } else {
872 // // Slow path.
873 // InterpreterRuntime::monitorenter(THREAD, monitor);
874 // }
875
876 const Register displaced_header = R7_ARG5;
877 const Register object_mark_addr = R8_ARG6;
878 const Register current_header = R9_ARG7;
879 const Register tmp = R10_ARG8;
880
881 Label done;
882 Label cas_failed, slow_case;
883
884 assert_different_registers(displaced_header, object_mark_addr, current_header, tmp);
885
886 // markOop displaced_header = obj->mark().set_unlocked();
887
888 // Load markOop from object into displaced_header.
889 ld(displaced_header, oopDesc::mark_offset_in_bytes(), object);
890
891 if (UseBiasedLocking) {
892 biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case);
893 }
894
895 // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
896 ori(displaced_header, displaced_header, markOopDesc::unlocked_value);
897
898 // monitor->lock()->set_displaced_header(displaced_header);
899
900 // Initialize the box (Must happen before we update the object mark!).
901 std(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
902 BasicLock::displaced_header_offset_in_bytes(), monitor);
903
904 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
905
906 // Store stack address of the BasicObjectLock (this is monitor) into object.
907 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
908
909 // Must fence, otherwise, preceding store(s) may float below cmpxchg.
910 // CmpxchgX sets CCR0 to cmpX(current, displaced).
911 cmpxchgd(/*flag=*/CCR0,
912 /*current_value=*/current_header,
913 /*compare_value=*/displaced_header, /*exchange_value=*/monitor,
914 /*where=*/object_mark_addr,
915 MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq,
916 MacroAssembler::cmpxchgx_hint_acquire_lock(),
917 noreg,
918 &cas_failed,
919 /*check without membar and ldarx first*/true);
920
921 // If the compare-and-exchange succeeded, then we found an unlocked
922 // object and we have now locked it.
923 b(done);
924 bind(cas_failed);
960 }
961
962 // Unlocks an object. Used in monitorexit bytecode and remove_activation.
963 //
964 // Registers alive
965 // monitor - Address of the BasicObjectLock to be used for locking,
966 // which must be initialized with the object to lock.
967 //
968 // Throw IllegalMonitorException if object is not locked by current thread.
969 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
970 if (UseHeavyMonitors) {
971 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
972 monitor, check_for_exceptions);
973 } else {
974
975 // template code:
976 //
977 // if ((displaced_header = monitor->displaced_header()) == NULL) {
978 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
979 // monitor->set_obj(NULL);
980 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
981 // // We swapped the unlocked mark in displaced_header into the object's mark word.
982 // monitor->set_obj(NULL);
983 // } else {
984 // // Slow path.
985 // InterpreterRuntime::monitorexit(THREAD, monitor);
986 // }
987
988 const Register object = R7_ARG5;
989 const Register displaced_header = R8_ARG6;
990 const Register object_mark_addr = R9_ARG7;
991 const Register current_header = R10_ARG8;
992
993 Label free_slot;
994 Label slow_case;
995
996 assert_different_registers(object, displaced_header, object_mark_addr, current_header);
997
998 if (UseBiasedLocking) {
999 // The object address from the monitor is in object.
1000 ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor);
1001 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1002 biased_locking_exit(CCR0, object, displaced_header, free_slot);
1003 }
1004
1005 // Test first if we are in the fast recursive case.
1006 ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
1007 BasicLock::displaced_header_offset_in_bytes(), monitor);
1008
1009 // If the displaced header is zero, we have a recursive unlock.
1010 cmpdi(CCR0, displaced_header, 0);
1011 beq(CCR0, free_slot); // recursive unlock
1012
1013 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
1014 // // We swapped the unlocked mark in displaced_header into the object's mark word.
1015 // monitor->set_obj(NULL);
1016
1017 // If we still have a lightweight lock, unlock the object and be done.
1018
1019 // The object address from the monitor is in object.
1020 if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); }
1021 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
1022
1023 // We have the displaced header in displaced_header. If the lock is still
1024 // lightweight, it will contain the monitor address and we'll store the
1025 // displaced header back into the object's mark word.
1026 // CmpxchgX sets CCR0 to cmpX(current, monitor).
1027 cmpxchgd(/*flag=*/CCR0,
1028 /*current_value=*/current_header,
1029 /*compare_value=*/monitor, /*exchange_value=*/displaced_header,
1030 /*where=*/object_mark_addr,
1031 MacroAssembler::MemBarRel,
1032 MacroAssembler::cmpxchgx_hint_release_lock(),
1033 noreg,
|