866 mtlr(R0); 867 BLOCK_COMMENT("} remove_activation"); 868 } 869 870 // Lock object 871 // 872 // Registers alive 873 // monitor - Address of the BasicObjectLock to be used for locking, 874 // which must be initialized with the object to lock. 875 // object - Address of the object to be locked. 876 // 877 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { 878 if (UseHeavyMonitors) { 879 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), 880 monitor, /*check_for_exceptions=*/true); 881 } else { 882 // template code: 883 // 884 // markWord displaced_header = obj->mark().set_unlocked(); 885 // monitor->lock()->set_displaced_header(displaced_header); 886 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) { 887 // // We stored the monitor address into the object's mark word. 888 // } else if (THREAD->is_lock_owned((address)displaced_header)) 889 // // Simple recursive case. 890 // monitor->lock()->set_displaced_header(NULL); 891 // } else { 892 // // Slow path. 893 // InterpreterRuntime::monitorenter(THREAD, monitor); 894 // } 895 896 const Register displaced_header = R7_ARG5; 897 const Register object_mark_addr = R8_ARG6; 898 const Register current_header = R9_ARG7; 899 const Register tmp = R10_ARG8; 900 901 Label done; 902 Label cas_failed, slow_case; 903 904 assert_different_registers(displaced_header, object_mark_addr, current_header, tmp); 905 906 // markWord displaced_header = obj->mark().set_unlocked(); 907 908 // Load markWord from object into displaced_header. 909 ld(displaced_header, oopDesc::mark_offset_in_bytes(), object); 910 911 if (UseBiasedLocking) { 912 biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case); 913 } 914 915 // Set displaced_header to be (markWord of object | UNLOCK_VALUE). 916 ori(displaced_header, displaced_header, markWord::unlocked_value); 917 918 // monitor->lock()->set_displaced_header(displaced_header); 919 920 // Initialize the box (Must happen before we update the object mark!). 921 std(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 922 BasicLock::displaced_header_offset_in_bytes(), monitor); 923 924 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) { 925 926 // Store stack address of the BasicObjectLock (this is monitor) into object. 927 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); 928 929 // Must fence, otherwise, preceding store(s) may float below cmpxchg. 930 // CmpxchgX sets CCR0 to cmpX(current, displaced). 931 cmpxchgd(/*flag=*/CCR0, 932 /*current_value=*/current_header, 933 /*compare_value=*/displaced_header, /*exchange_value=*/monitor, 934 /*where=*/object_mark_addr, 935 MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, 936 MacroAssembler::cmpxchgx_hint_acquire_lock(), 937 noreg, 938 &cas_failed, 939 /*check without membar and ldarx first*/true); 940 941 // If the compare-and-exchange succeeded, then we found an unlocked 942 // object and we have now locked it. 943 b(done); 944 bind(cas_failed); 980 } 981 982 // Unlocks an object. Used in monitorexit bytecode and remove_activation. 983 // 984 // Registers alive 985 // monitor - Address of the BasicObjectLock to be used for locking, 986 // which must be initialized with the object to lock. 987 // 988 // Throw IllegalMonitorException if object is not locked by current thread. 989 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) { 990 if (UseHeavyMonitors) { 991 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), 992 monitor, check_for_exceptions); 993 } else { 994 995 // template code: 996 // 997 // if ((displaced_header = monitor->displaced_header()) == NULL) { 998 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 999 // monitor->set_obj(NULL); 1000 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) { 1001 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1002 // monitor->set_obj(NULL); 1003 // } else { 1004 // // Slow path. 1005 // InterpreterRuntime::monitorexit(THREAD, monitor); 1006 // } 1007 1008 const Register object = R7_ARG5; 1009 const Register displaced_header = R8_ARG6; 1010 const Register object_mark_addr = R9_ARG7; 1011 const Register current_header = R10_ARG8; 1012 1013 Label free_slot; 1014 Label slow_case; 1015 1016 assert_different_registers(object, displaced_header, object_mark_addr, current_header); 1017 1018 if (UseBiasedLocking) { 1019 // The object address from the monitor is in object. 1020 ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); 1021 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 1022 biased_locking_exit(CCR0, object, displaced_header, free_slot); 1023 } 1024 1025 // Test first if we are in the fast recursive case. 1026 ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 1027 BasicLock::displaced_header_offset_in_bytes(), monitor); 1028 1029 // If the displaced header is zero, we have a recursive unlock. 1030 cmpdi(CCR0, displaced_header, 0); 1031 beq(CCR0, free_slot); // recursive unlock 1032 1033 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) { 1034 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1035 // monitor->set_obj(NULL); 1036 1037 // If we still have a lightweight lock, unlock the object and be done. 1038 1039 // The object address from the monitor is in object. 1040 if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); } 1041 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); 1042 1043 // We have the displaced header in displaced_header. If the lock is still 1044 // lightweight, it will contain the monitor address and we'll store the 1045 // displaced header back into the object's mark word. 1046 // CmpxchgX sets CCR0 to cmpX(current, monitor). 1047 cmpxchgd(/*flag=*/CCR0, 1048 /*current_value=*/current_header, 1049 /*compare_value=*/monitor, /*exchange_value=*/displaced_header, 1050 /*where=*/object_mark_addr, 1051 MacroAssembler::MemBarRel, 1052 MacroAssembler::cmpxchgx_hint_release_lock(), 1053 noreg, | 866 mtlr(R0); 867 BLOCK_COMMENT("} remove_activation"); 868 } 869 870 // Lock object 871 // 872 // Registers alive 873 // monitor - Address of the BasicObjectLock to be used for locking, 874 // which must be initialized with the object to lock. 875 // object - Address of the object to be locked. 876 // 877 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { 878 if (UseHeavyMonitors) { 879 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), 880 monitor, /*check_for_exceptions=*/true); 881 } else { 882 // template code: 883 // 884 // markWord displaced_header = obj->mark().set_unlocked(); 885 // monitor->lock()->set_displaced_header(displaced_header); 886 // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { 887 // // We stored the monitor address into the object's mark word. 888 // } else if (THREAD->is_lock_owned((address)displaced_header)) 889 // // Simple recursive case. 890 // monitor->lock()->set_displaced_header(NULL); 891 // } else { 892 // // Slow path. 893 // InterpreterRuntime::monitorenter(THREAD, monitor); 894 // } 895 896 const Register displaced_header = R7_ARG5; 897 const Register object_mark_addr = R8_ARG6; 898 const Register current_header = R9_ARG7; 899 const Register tmp = R10_ARG8; 900 901 Label done; 902 Label cas_failed, slow_case; 903 904 assert_different_registers(displaced_header, object_mark_addr, current_header, tmp); 905 906 // markWord displaced_header = obj->mark().set_unlocked(); 907 908 // Load markWord from object into displaced_header. 909 ld(displaced_header, oopDesc::mark_offset_in_bytes(), object); 910 911 if (UseBiasedLocking) { 912 biased_locking_enter(CCR0, object, displaced_header, tmp, current_header, done, &slow_case); 913 } 914 915 // Set displaced_header to be (markWord of object | UNLOCK_VALUE). 916 ori(displaced_header, displaced_header, markWord::unlocked_value); 917 918 // monitor->lock()->set_displaced_header(displaced_header); 919 920 // Initialize the box (Must happen before we update the object mark!). 921 std(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 922 BasicLock::displaced_header_offset_in_bytes(), monitor); 923 924 // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { 925 926 // Store stack address of the BasicObjectLock (this is monitor) into object. 927 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); 928 929 // Must fence, otherwise, preceding store(s) may float below cmpxchg. 930 // CmpxchgX sets CCR0 to cmpX(current, displaced). 931 cmpxchgd(/*flag=*/CCR0, 932 /*current_value=*/current_header, 933 /*compare_value=*/displaced_header, /*exchange_value=*/monitor, 934 /*where=*/object_mark_addr, 935 MacroAssembler::MemBarRel | MacroAssembler::MemBarAcq, 936 MacroAssembler::cmpxchgx_hint_acquire_lock(), 937 noreg, 938 &cas_failed, 939 /*check without membar and ldarx first*/true); 940 941 // If the compare-and-exchange succeeded, then we found an unlocked 942 // object and we have now locked it. 943 b(done); 944 bind(cas_failed); 980 } 981 982 // Unlocks an object. Used in monitorexit bytecode and remove_activation. 983 // 984 // Registers alive 985 // monitor - Address of the BasicObjectLock to be used for locking, 986 // which must be initialized with the object to lock. 987 // 988 // Throw IllegalMonitorException if object is not locked by current thread. 989 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) { 990 if (UseHeavyMonitors) { 991 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), 992 monitor, check_for_exceptions); 993 } else { 994 995 // template code: 996 // 997 // if ((displaced_header = monitor->displaced_header()) == NULL) { 998 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 999 // monitor->set_obj(NULL); 1000 // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { 1001 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1002 // monitor->set_obj(NULL); 1003 // } else { 1004 // // Slow path. 1005 // InterpreterRuntime::monitorexit(THREAD, monitor); 1006 // } 1007 1008 const Register object = R7_ARG5; 1009 const Register displaced_header = R8_ARG6; 1010 const Register object_mark_addr = R9_ARG7; 1011 const Register current_header = R10_ARG8; 1012 1013 Label free_slot; 1014 Label slow_case; 1015 1016 assert_different_registers(object, displaced_header, object_mark_addr, current_header); 1017 1018 if (UseBiasedLocking) { 1019 // The object address from the monitor is in object. 1020 ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); 1021 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 1022 biased_locking_exit(CCR0, object, displaced_header, free_slot); 1023 } 1024 1025 // Test first if we are in the fast recursive case. 1026 ld(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 1027 BasicLock::displaced_header_offset_in_bytes(), monitor); 1028 1029 // If the displaced header is zero, we have a recursive unlock. 1030 cmpdi(CCR0, displaced_header, 0); 1031 beq(CCR0, free_slot); // recursive unlock 1032 1033 // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { 1034 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1035 // monitor->set_obj(NULL); 1036 1037 // If we still have a lightweight lock, unlock the object and be done. 1038 1039 // The object address from the monitor is in object. 1040 if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); } 1041 addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes()); 1042 1043 // We have the displaced header in displaced_header. If the lock is still 1044 // lightweight, it will contain the monitor address and we'll store the 1045 // displaced header back into the object's mark word. 1046 // CmpxchgX sets CCR0 to cmpX(current, monitor). 1047 cmpxchgd(/*flag=*/CCR0, 1048 /*current_value=*/current_header, 1049 /*compare_value=*/monitor, /*exchange_value=*/displaced_header, 1050 /*where=*/object_mark_addr, 1051 MacroAssembler::MemBarRel, 1052 MacroAssembler::cmpxchgx_hint_release_lock(), 1053 noreg, |