< prev index next >

src/hotspot/cpu/s390/interp_masm_s390.cpp

Print this page




 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


< prev index next >