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
|