959 } 960 961 // lock object 962 // 963 // Registers alive 964 // monitor - Address of the BasicObjectLock to be used for locking, 965 // which must be initialized with the object to lock. 966 // object - Address of the object to be locked. 967 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { 968 969 if (UseHeavyMonitors) { 970 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), 971 monitor, /*check_for_exceptions=*/false); 972 return; 973 } 974 975 // template code: 976 // 977 // markWord displaced_header = obj->mark().set_unlocked(); 978 // monitor->lock()->set_displaced_header(displaced_header); 979 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) { 980 // // We stored the monitor address into the object's mark word. 981 // } else if (THREAD->is_lock_owned((address)displaced_header)) 982 // // Simple recursive case. 983 // monitor->lock()->set_displaced_header(NULL); 984 // } else { 985 // // Slow path. 986 // InterpreterRuntime::monitorenter(THREAD, monitor); 987 // } 988 989 const Register displaced_header = Z_ARG5; 990 const Register object_mark_addr = Z_ARG4; 991 const Register current_header = Z_ARG5; 992 993 NearLabel done; 994 NearLabel slow_case; 995 996 // markWord displaced_header = obj->mark().set_unlocked(); 997 998 // Load markWord from object into displaced_header. 999 z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object); 1000 1001 if (UseBiasedLocking) { 1002 biased_locking_enter(object, displaced_header, Z_R1, Z_R0, done, &slow_case); 1003 } 1004 1005 // Set displaced_header to be (markWord of object | UNLOCK_VALUE). 1006 z_oill(displaced_header, markWord::unlocked_value); 1007 1008 // monitor->lock()->set_displaced_header(displaced_header); 1009 1010 // Initialize the box (Must happen before we update the object mark!). 1011 z_stg(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 1012 BasicLock::displaced_header_offset_in_bytes(), monitor); 1013 1014 // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) { 1015 1016 // Store stack address of the BasicObjectLock (this is monitor) into object. 1017 add2reg(object_mark_addr, oopDesc::mark_offset_in_bytes(), object); 1018 1019 z_csg(displaced_header, monitor, 0, object_mark_addr); 1020 assert(current_header==displaced_header, "must be same register"); // Identified two registers from z/Architecture. 1021 1022 z_bre(done); 1023 1024 // } else if (THREAD->is_lock_owned((address)displaced_header)) 1025 // // Simple recursive case. 1026 // monitor->lock()->set_displaced_header(NULL); 1027 1028 // We did not see an unlocked object so try the fast recursive case. 1029 1030 // Check if owner is self by comparing the value in the markWord of object 1031 // (current_header) with the stack pointer. 1032 z_sgr(current_header, Z_SP); 1033 1034 assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); 1065 // Unlocks an object. Used in monitorexit bytecode and remove_activation. 1066 // 1067 // Registers alive 1068 // monitor - address of the BasicObjectLock to be used for locking, 1069 // which must be initialized with the object to lock. 1070 // 1071 // Throw IllegalMonitorException if object is not locked by current thread. 1072 void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) { 1073 1074 if (UseHeavyMonitors) { 1075 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor); 1076 return; 1077 } 1078 1079 // else { 1080 // template code: 1081 // 1082 // if ((displaced_header = monitor->displaced_header()) == NULL) { 1083 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 1084 // monitor->set_obj(NULL); 1085 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) { 1086 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1087 // monitor->set_obj(NULL); 1088 // } else { 1089 // // Slow path. 1090 // InterpreterRuntime::monitorexit(THREAD, monitor); 1091 // } 1092 1093 const Register displaced_header = Z_ARG4; 1094 const Register current_header = Z_R1; 1095 Address obj_entry(monitor, BasicObjectLock::obj_offset_in_bytes()); 1096 Label done; 1097 1098 if (object == noreg) { 1099 // In the template interpreter, we must assure that the object 1100 // entry in the monitor is cleared on all paths. Thus we move 1101 // loading up to here, and clear the entry afterwards. 1102 object = Z_ARG3; // Use Z_ARG3 if caller didn't pass object. 1103 z_lg(object, obj_entry); 1104 } 1105 1106 assert_different_registers(monitor, object, displaced_header, current_header); 1107 1108 // if ((displaced_header = monitor->displaced_header()) == NULL) { 1109 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 1110 // monitor->set_obj(NULL); 1111 1112 clear_mem(obj_entry, sizeof(oop)); 1113 1114 if (UseBiasedLocking) { 1115 // The object address from the monitor is in object. 1116 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 1117 biased_locking_exit(object, displaced_header, done); 1118 } 1119 1120 // Test first if we are in the fast recursive case. 1121 MacroAssembler::load_and_test_long(displaced_header, 1122 Address(monitor, BasicObjectLock::lock_offset_in_bytes() + 1123 BasicLock::displaced_header_offset_in_bytes())); 1124 z_bre(done); // displaced_header == 0 -> goto done 1125 1126 // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) { 1127 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1128 // monitor->set_obj(NULL); 1129 1130 // If we still have a lightweight lock, unlock the object and be done. 1131 1132 // The markword is expected to be at offset 0. 1133 assert(oopDesc::mark_offset_in_bytes() == 0, "unlock_object: review code below"); 1134 1135 // We have the displaced header in displaced_header. If the lock is still 1136 // lightweight, it will contain the monitor address and we'll store the 1137 // displaced header back into the object's mark word. 1138 z_lgr(current_header, monitor); 1139 z_csg(current_header, displaced_header, 0, object); 1140 z_bre(done); 1141 1142 // } else { 1143 // // Slow path. 1144 // InterpreterRuntime::monitorexit(THREAD, monitor); 1145 1146 // The lock has been converted into a heavy lock and hence | 959 } 960 961 // lock object 962 // 963 // Registers alive 964 // monitor - Address of the BasicObjectLock to be used for locking, 965 // which must be initialized with the object to lock. 966 // object - Address of the object to be locked. 967 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) { 968 969 if (UseHeavyMonitors) { 970 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter), 971 monitor, /*check_for_exceptions=*/false); 972 return; 973 } 974 975 // template code: 976 // 977 // markWord displaced_header = obj->mark().set_unlocked(); 978 // monitor->lock()->set_displaced_header(displaced_header); 979 // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { 980 // // We stored the monitor address into the object's mark word. 981 // } else if (THREAD->is_lock_owned((address)displaced_header)) 982 // // Simple recursive case. 983 // monitor->lock()->set_displaced_header(NULL); 984 // } else { 985 // // Slow path. 986 // InterpreterRuntime::monitorenter(THREAD, monitor); 987 // } 988 989 const Register displaced_header = Z_ARG5; 990 const Register object_mark_addr = Z_ARG4; 991 const Register current_header = Z_ARG5; 992 993 NearLabel done; 994 NearLabel slow_case; 995 996 // markWord displaced_header = obj->mark().set_unlocked(); 997 998 // Load markWord from object into displaced_header. 999 z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object); 1000 1001 if (UseBiasedLocking) { 1002 biased_locking_enter(object, displaced_header, Z_R1, Z_R0, done, &slow_case); 1003 } 1004 1005 // Set displaced_header to be (markWord of object | UNLOCK_VALUE). 1006 z_oill(displaced_header, markWord::unlocked_value); 1007 1008 // monitor->lock()->set_displaced_header(displaced_header); 1009 1010 // Initialize the box (Must happen before we update the object mark!). 1011 z_stg(displaced_header, BasicObjectLock::lock_offset_in_bytes() + 1012 BasicLock::displaced_header_offset_in_bytes(), monitor); 1013 1014 // if (Atomic::cmpxchg(/*addr*/obj->mark_addr(), /*cmp*/displaced_header, /*ex=*/monitor) == displaced_header) { 1015 1016 // Store stack address of the BasicObjectLock (this is monitor) into object. 1017 add2reg(object_mark_addr, oopDesc::mark_offset_in_bytes(), object); 1018 1019 z_csg(displaced_header, monitor, 0, object_mark_addr); 1020 assert(current_header==displaced_header, "must be same register"); // Identified two registers from z/Architecture. 1021 1022 z_bre(done); 1023 1024 // } else if (THREAD->is_lock_owned((address)displaced_header)) 1025 // // Simple recursive case. 1026 // monitor->lock()->set_displaced_header(NULL); 1027 1028 // We did not see an unlocked object so try the fast recursive case. 1029 1030 // Check if owner is self by comparing the value in the markWord of object 1031 // (current_header) with the stack pointer. 1032 z_sgr(current_header, Z_SP); 1033 1034 assert(os::vm_page_size() > 0xfff, "page size too small - change the constant"); 1065 // Unlocks an object. Used in monitorexit bytecode and remove_activation. 1066 // 1067 // Registers alive 1068 // monitor - address of the BasicObjectLock to be used for locking, 1069 // which must be initialized with the object to lock. 1070 // 1071 // Throw IllegalMonitorException if object is not locked by current thread. 1072 void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) { 1073 1074 if (UseHeavyMonitors) { 1075 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), monitor); 1076 return; 1077 } 1078 1079 // else { 1080 // template code: 1081 // 1082 // if ((displaced_header = monitor->displaced_header()) == NULL) { 1083 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 1084 // monitor->set_obj(NULL); 1085 // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { 1086 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1087 // monitor->set_obj(NULL); 1088 // } else { 1089 // // Slow path. 1090 // InterpreterRuntime::monitorexit(THREAD, monitor); 1091 // } 1092 1093 const Register displaced_header = Z_ARG4; 1094 const Register current_header = Z_R1; 1095 Address obj_entry(monitor, BasicObjectLock::obj_offset_in_bytes()); 1096 Label done; 1097 1098 if (object == noreg) { 1099 // In the template interpreter, we must assure that the object 1100 // entry in the monitor is cleared on all paths. Thus we move 1101 // loading up to here, and clear the entry afterwards. 1102 object = Z_ARG3; // Use Z_ARG3 if caller didn't pass object. 1103 z_lg(object, obj_entry); 1104 } 1105 1106 assert_different_registers(monitor, object, displaced_header, current_header); 1107 1108 // if ((displaced_header = monitor->displaced_header()) == NULL) { 1109 // // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL. 1110 // monitor->set_obj(NULL); 1111 1112 clear_mem(obj_entry, sizeof(oop)); 1113 1114 if (UseBiasedLocking) { 1115 // The object address from the monitor is in object. 1116 assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0"); 1117 biased_locking_exit(object, displaced_header, done); 1118 } 1119 1120 // Test first if we are in the fast recursive case. 1121 MacroAssembler::load_and_test_long(displaced_header, 1122 Address(monitor, BasicObjectLock::lock_offset_in_bytes() + 1123 BasicLock::displaced_header_offset_in_bytes())); 1124 z_bre(done); // displaced_header == 0 -> goto done 1125 1126 // } else if (Atomic::cmpxchg(obj->mark_addr(), monitor, displaced_header) == monitor) { 1127 // // We swapped the unlocked mark in displaced_header into the object's mark word. 1128 // monitor->set_obj(NULL); 1129 1130 // If we still have a lightweight lock, unlock the object and be done. 1131 1132 // The markword is expected to be at offset 0. 1133 assert(oopDesc::mark_offset_in_bytes() == 0, "unlock_object: review code below"); 1134 1135 // We have the displaced header in displaced_header. If the lock is still 1136 // lightweight, it will contain the monitor address and we'll store the 1137 // displaced header back into the object's mark word. 1138 z_lgr(current_header, monitor); 1139 z_csg(current_header, displaced_header, 0, object); 1140 z_bre(done); 1141 1142 // } else { 1143 // // Slow path. 1144 // InterpreterRuntime::monitorexit(THREAD, monitor); 1145 1146 // The lock has been converted into a heavy lock and hence |