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, |