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 |