< prev index next >

src/hotspot/cpu/s390/interp_masm_s390.cpp

Print this page
rev 47400 : [mq]: cmpxchg_ptr


 897 }
 898 
 899 // lock object
 900 //
 901 // Registers alive
 902 //   monitor - Address of the BasicObjectLock to be used for locking,
 903 //             which must be initialized with the object to lock.
 904 //   object  - Address of the object to be locked.
 905 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
 906 
 907   if (UseHeavyMonitors) {
 908     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 909             monitor, /*check_for_exceptions=*/false);
 910     return;
 911   }
 912 
 913   // template code:
 914   //
 915   // markOop displaced_header = obj->mark().set_unlocked();
 916   // monitor->lock()->set_displaced_header(displaced_header);
 917   // if (Atomic::cmpxchg_ptr(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 918   //   // We stored the monitor address into the object's mark word.
 919   // } else if (THREAD->is_lock_owned((address)displaced_header))
 920   //   // Simple recursive case.
 921   //   monitor->lock()->set_displaced_header(NULL);
 922   // } else {
 923   //   // Slow path.
 924   //   InterpreterRuntime::monitorenter(THREAD, monitor);
 925   // }
 926 
 927   const Register displaced_header = Z_ARG5;
 928   const Register object_mark_addr = Z_ARG4;
 929   const Register current_header   = Z_ARG5;
 930 
 931   NearLabel done;
 932   NearLabel slow_case;
 933 
 934   // markOop displaced_header = obj->mark().set_unlocked();
 935 
 936   // Load markOop from object into displaced_header.
 937   z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object);
 938 
 939   if (UseBiasedLocking) {
 940     biased_locking_enter(object, displaced_header, Z_R1, Z_R0, done, &slow_case);
 941   }
 942 
 943   // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
 944   z_oill(displaced_header, markOopDesc::unlocked_value);
 945 
 946   // monitor->lock()->set_displaced_header(displaced_header);
 947 
 948   // Initialize the box (Must happen before we update the object mark!).
 949   z_stg(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
 950                           BasicLock::displaced_header_offset_in_bytes(), monitor);
 951 
 952   // if (Atomic::cmpxchg_ptr(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 953 
 954   // Store stack address of the BasicObjectLock (this is monitor) into object.
 955   add2reg(object_mark_addr, oopDesc::mark_offset_in_bytes(), object);
 956 
 957   z_csg(displaced_header, monitor, 0, object_mark_addr);
 958   assert(current_header==displaced_header, "must be same register"); // Identified two registers from z/Architecture.
 959 
 960   z_bre(done);
 961 
 962   // } else if (THREAD->is_lock_owned((address)displaced_header))
 963   //   // Simple recursive case.
 964   //   monitor->lock()->set_displaced_header(NULL);
 965 
 966   // We did not see an unlocked object so try the fast recursive case.
 967 
 968   // Check if owner is self by comparing the value in the markOop of object
 969   // (current_header) with the stack pointer.
 970   z_sgr(current_header, Z_SP);
 971 
 972   assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");


1004 //
1005 // Registers alive
1006 //   monitor - address of the BasicObjectLock to be used for locking,
1007 //             which must be initialized with the object to lock.
1008 //
1009 // Throw IllegalMonitorException if object is not locked by current thread.
1010 void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) {
1011 
1012   if (UseHeavyMonitors) {
1013     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
1014             monitor, /*check_for_exceptions=*/ true);
1015     return;
1016   }
1017 
1018 // else {
1019   // template code:
1020   //
1021   // if ((displaced_header = monitor->displaced_header()) == NULL) {
1022   //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
1023   //   monitor->set_obj(NULL);
1024   // } else if (Atomic::cmpxchg_ptr(displaced_header, obj->mark_addr(), monitor) == monitor) {
1025   //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1026   //   monitor->set_obj(NULL);
1027   // } else {
1028   //   // Slow path.
1029   //   InterpreterRuntime::monitorexit(THREAD, monitor);
1030   // }
1031 
1032   const Register displaced_header = Z_ARG4;
1033   const Register current_header   = Z_R1;
1034   Address obj_entry(monitor, BasicObjectLock::obj_offset_in_bytes());
1035   Label done;
1036 
1037   if (object == noreg) {
1038     // In the template interpreter, we must assure that the object
1039     // entry in the monitor is cleared on all paths. Thus we move
1040     // loading up to here, and clear the entry afterwards.
1041     object = Z_ARG3; // Use Z_ARG3 if caller didn't pass object.
1042     z_lg(object, obj_entry);
1043   }
1044 
1045   assert_different_registers(monitor, object, displaced_header, current_header);
1046 
1047   // if ((displaced_header = monitor->displaced_header()) == NULL) {
1048   //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
1049   //   monitor->set_obj(NULL);
1050 
1051   clear_mem(obj_entry, sizeof(oop));
1052 
1053   if (UseBiasedLocking) {
1054     // The object address from the monitor is in object.
1055     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1056     biased_locking_exit(object, displaced_header, done);
1057   }
1058 
1059   // Test first if we are in the fast recursive case.
1060   MacroAssembler::load_and_test_long(displaced_header,
1061                                      Address(monitor, BasicObjectLock::lock_offset_in_bytes() +
1062                                                       BasicLock::displaced_header_offset_in_bytes()));
1063   z_bre(done); // displaced_header == 0 -> goto done
1064 
1065   // } else if (Atomic::cmpxchg_ptr(displaced_header, obj->mark_addr(), monitor) == monitor) {
1066   //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1067   //   monitor->set_obj(NULL);
1068 
1069   // If we still have a lightweight lock, unlock the object and be done.
1070 
1071   // The markword is expected to be at offset 0.
1072   assert(oopDesc::mark_offset_in_bytes() == 0, "unlock_object: review code below");
1073 
1074   // We have the displaced header in displaced_header. If the lock is still
1075   // lightweight, it will contain the monitor address and we'll store the
1076   // displaced header back into the object's mark word.
1077   z_lgr(current_header, monitor);
1078   z_csg(current_header, displaced_header, 0, object);
1079   z_bre(done);
1080 
1081   // } else {
1082   //   // Slow path.
1083   //   InterpreterRuntime::monitorexit(THREAD, monitor);
1084 
1085   // The lock has been converted into a heavy lock and hence




 897 }
 898 
 899 // lock object
 900 //
 901 // Registers alive
 902 //   monitor - Address of the BasicObjectLock to be used for locking,
 903 //             which must be initialized with the object to lock.
 904 //   object  - Address of the object to be locked.
 905 void InterpreterMacroAssembler::lock_object(Register monitor, Register object) {
 906 
 907   if (UseHeavyMonitors) {
 908     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
 909             monitor, /*check_for_exceptions=*/false);
 910     return;
 911   }
 912 
 913   // template code:
 914   //
 915   // markOop displaced_header = obj->mark().set_unlocked();
 916   // monitor->lock()->set_displaced_header(displaced_header);
 917   // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 918   //   // We stored the monitor address into the object's mark word.
 919   // } else if (THREAD->is_lock_owned((address)displaced_header))
 920   //   // Simple recursive case.
 921   //   monitor->lock()->set_displaced_header(NULL);
 922   // } else {
 923   //   // Slow path.
 924   //   InterpreterRuntime::monitorenter(THREAD, monitor);
 925   // }
 926 
 927   const Register displaced_header = Z_ARG5;
 928   const Register object_mark_addr = Z_ARG4;
 929   const Register current_header   = Z_ARG5;
 930 
 931   NearLabel done;
 932   NearLabel slow_case;
 933 
 934   // markOop displaced_header = obj->mark().set_unlocked();
 935 
 936   // Load markOop from object into displaced_header.
 937   z_lg(displaced_header, oopDesc::mark_offset_in_bytes(), object);
 938 
 939   if (UseBiasedLocking) {
 940     biased_locking_enter(object, displaced_header, Z_R1, Z_R0, done, &slow_case);
 941   }
 942 
 943   // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
 944   z_oill(displaced_header, markOopDesc::unlocked_value);
 945 
 946   // monitor->lock()->set_displaced_header(displaced_header);
 947 
 948   // Initialize the box (Must happen before we update the object mark!).
 949   z_stg(displaced_header, BasicObjectLock::lock_offset_in_bytes() +
 950                           BasicLock::displaced_header_offset_in_bytes(), monitor);
 951 
 952   // if (Atomic::cmpxchg(/*ex=*/monitor, /*addr*/obj->mark_addr(), /*cmp*/displaced_header) == displaced_header) {
 953 
 954   // Store stack address of the BasicObjectLock (this is monitor) into object.
 955   add2reg(object_mark_addr, oopDesc::mark_offset_in_bytes(), object);
 956 
 957   z_csg(displaced_header, monitor, 0, object_mark_addr);
 958   assert(current_header==displaced_header, "must be same register"); // Identified two registers from z/Architecture.
 959 
 960   z_bre(done);
 961 
 962   // } else if (THREAD->is_lock_owned((address)displaced_header))
 963   //   // Simple recursive case.
 964   //   monitor->lock()->set_displaced_header(NULL);
 965 
 966   // We did not see an unlocked object so try the fast recursive case.
 967 
 968   // Check if owner is self by comparing the value in the markOop of object
 969   // (current_header) with the stack pointer.
 970   z_sgr(current_header, Z_SP);
 971 
 972   assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");


1004 //
1005 // Registers alive
1006 //   monitor - address of the BasicObjectLock to be used for locking,
1007 //             which must be initialized with the object to lock.
1008 //
1009 // Throw IllegalMonitorException if object is not locked by current thread.
1010 void InterpreterMacroAssembler::unlock_object(Register monitor, Register object) {
1011 
1012   if (UseHeavyMonitors) {
1013     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
1014             monitor, /*check_for_exceptions=*/ true);
1015     return;
1016   }
1017 
1018 // else {
1019   // template code:
1020   //
1021   // if ((displaced_header = monitor->displaced_header()) == NULL) {
1022   //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
1023   //   monitor->set_obj(NULL);
1024   // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
1025   //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1026   //   monitor->set_obj(NULL);
1027   // } else {
1028   //   // Slow path.
1029   //   InterpreterRuntime::monitorexit(THREAD, monitor);
1030   // }
1031 
1032   const Register displaced_header = Z_ARG4;
1033   const Register current_header   = Z_R1;
1034   Address obj_entry(monitor, BasicObjectLock::obj_offset_in_bytes());
1035   Label done;
1036 
1037   if (object == noreg) {
1038     // In the template interpreter, we must assure that the object
1039     // entry in the monitor is cleared on all paths. Thus we move
1040     // loading up to here, and clear the entry afterwards.
1041     object = Z_ARG3; // Use Z_ARG3 if caller didn't pass object.
1042     z_lg(object, obj_entry);
1043   }
1044 
1045   assert_different_registers(monitor, object, displaced_header, current_header);
1046 
1047   // if ((displaced_header = monitor->displaced_header()) == NULL) {
1048   //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
1049   //   monitor->set_obj(NULL);
1050 
1051   clear_mem(obj_entry, sizeof(oop));
1052 
1053   if (UseBiasedLocking) {
1054     // The object address from the monitor is in object.
1055     assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
1056     biased_locking_exit(object, displaced_header, done);
1057   }
1058 
1059   // Test first if we are in the fast recursive case.
1060   MacroAssembler::load_and_test_long(displaced_header,
1061                                      Address(monitor, BasicObjectLock::lock_offset_in_bytes() +
1062                                                       BasicLock::displaced_header_offset_in_bytes()));
1063   z_bre(done); // displaced_header == 0 -> goto done
1064 
1065   // } else if (Atomic::cmpxchg(displaced_header, obj->mark_addr(), monitor) == monitor) {
1066   //   // We swapped the unlocked mark in displaced_header into the object's mark word.
1067   //   monitor->set_obj(NULL);
1068 
1069   // If we still have a lightweight lock, unlock the object and be done.
1070 
1071   // The markword is expected to be at offset 0.
1072   assert(oopDesc::mark_offset_in_bytes() == 0, "unlock_object: review code below");
1073 
1074   // We have the displaced header in displaced_header. If the lock is still
1075   // lightweight, it will contain the monitor address and we'll store the
1076   // displaced header back into the object's mark word.
1077   z_lgr(current_header, monitor);
1078   z_csg(current_header, displaced_header, 0, object);
1079   z_bre(done);
1080 
1081   // } else {
1082   //   // Slow path.
1083   //   InterpreterRuntime::monitorexit(THREAD, monitor);
1084 
1085   // The lock has been converted into a heavy lock and hence


< prev index next >