< prev index next >

src/hotspot/cpu/x86/interp_masm_x86.cpp

Print this page

1171     const Register rklass_decode_tmp = rscratch1;
1172 
1173     const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
1174     const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
1175     const int mark_offset = lock_offset +
1176                             BasicLock::displaced_header_offset_in_bytes();
1177 
1178     // Load object pointer into obj_reg
1179     movptr(obj_reg, Address(lock_reg, obj_offset));
1180 
1181     if (DiagnoseSyncOnValueBasedClasses != 0) {
1182       load_klass(tmp_reg, obj_reg, rklass_decode_tmp);
1183       movl(tmp_reg, Address(tmp_reg, Klass::access_flags_offset()));
1184       testl(tmp_reg, JVM_ACC_IS_VALUE_BASED_CLASS);
1185       jcc(Assembler::notZero, slow_case);
1186     }
1187 
1188     if (LockingMode == LM_LIGHTWEIGHT) {
1189 #ifdef _LP64
1190       const Register thread = r15_thread;

1191 #else
1192       const Register thread = lock_reg;
1193       get_thread(thread);
1194 #endif
1195       lightweight_lock(obj_reg, swap_reg, thread, tmp_reg, slow_case);
1196     } else if (LockingMode == LM_LEGACY) {
1197       // Load immediate 1 into swap_reg %rax
1198       movl(swap_reg, 1);
1199 
1200       // Load (object->mark() | 1) into swap_reg %rax
1201       orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1202 
1203       // Save (object->mark() | 1) into BasicLock's displaced header
1204       movptr(Address(lock_reg, mark_offset), swap_reg);
1205 
1206       assert(lock_offset == 0,
1207              "displaced header must be first word in BasicObjectLock");
1208 
1209       lock();
1210       cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1211       jcc(Assembler::zero, count_locking);
1212 
1213       const int zero_bits = LP64_ONLY(7) NOT_LP64(3);
1214 
1215       // Fast check for recursive lock.

1237       // These 3 tests can be done by evaluating the following
1238       // expression: ((mark - rsp) & (zero_bits - os::vm_page_size())),
1239       // assuming both stack pointer and pagesize have their
1240       // least significant bits clear.
1241       // NOTE: the mark is in swap_reg %rax as the result of cmpxchg
1242       subptr(swap_reg, rsp);
1243       andptr(swap_reg, zero_bits - (int)os::vm_page_size());
1244 
1245       // Save the test result, for recursive case, the result is zero
1246       movptr(Address(lock_reg, mark_offset), swap_reg);
1247       jcc(Assembler::notZero, slow_case);
1248 
1249       bind(count_locking);
1250     }
1251     inc_held_monitor_count();
1252     jmp(done);
1253 
1254     bind(slow_case);
1255 
1256     // Call the runtime routine for slow case
1257     if (LockingMode == LM_LIGHTWEIGHT) {
1258       call_VM(noreg,
1259               CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter_obj),
1260               obj_reg);
1261     } else {
1262       call_VM(noreg,
1263               CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
1264               lock_reg);
1265     }
1266     bind(done);
1267   }
1268 }
1269 
1270 
1271 // Unlocks an object. Used in monitorexit bytecode and
1272 // remove_activation.  Throws an IllegalMonitorException if object is
1273 // not locked by current thread.
1274 //
1275 // Args:
1276 //      rdx, c_rarg1: BasicObjectLock for lock
1277 //
1278 // Kills:
1279 //      rax
1280 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
1281 //      rscratch1 (scratch reg)
1282 // rax, rbx, rcx, rdx
1283 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
1284   assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
1285          "The argument is only for looks. It must be c_rarg1");

1294     const Register obj_reg    = LP64_ONLY(c_rarg3) NOT_LP64(rcx);  // Will contain the oop
1295 
1296     save_bcp(); // Save in case of exception
1297 
1298     if (LockingMode != LM_LIGHTWEIGHT) {
1299       // Convert from BasicObjectLock structure to object and BasicLock
1300       // structure Store the BasicLock address into %rax
1301       lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
1302     }
1303 
1304     // Load oop into obj_reg(%c_rarg3)
1305     movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
1306 
1307     // Free entry
1308     movptr(Address(lock_reg, BasicObjectLock::obj_offset()), NULL_WORD);
1309 
1310     if (LockingMode == LM_LIGHTWEIGHT) {
1311 #ifdef _LP64
1312       lightweight_unlock(obj_reg, swap_reg, r15_thread, header_reg, slow_case);
1313 #else
1314       // This relies on the implementation of lightweight_unlock being able to handle
1315       // that the reg_rax and thread Register parameters may alias each other.
1316       get_thread(swap_reg);
1317       lightweight_unlock(obj_reg, swap_reg, swap_reg, header_reg, slow_case);
1318 #endif
1319     } else if (LockingMode == LM_LEGACY) {
1320       // Load the old header from BasicLock structure
1321       movptr(header_reg, Address(swap_reg,
1322                                  BasicLock::displaced_header_offset_in_bytes()));
1323 
1324       // Test for recursion
1325       testptr(header_reg, header_reg);
1326 
1327       // zero for recursive case
1328       jcc(Assembler::zero, count_locking);
1329 
1330       // Atomic swap back the old header
1331       lock();
1332       cmpxchgptr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1333 
1334       // zero for simple unlock of a stack-lock case
1335       jcc(Assembler::notZero, slow_case);
1336 
1337       bind(count_locking);

1171     const Register rklass_decode_tmp = rscratch1;
1172 
1173     const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
1174     const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
1175     const int mark_offset = lock_offset +
1176                             BasicLock::displaced_header_offset_in_bytes();
1177 
1178     // Load object pointer into obj_reg
1179     movptr(obj_reg, Address(lock_reg, obj_offset));
1180 
1181     if (DiagnoseSyncOnValueBasedClasses != 0) {
1182       load_klass(tmp_reg, obj_reg, rklass_decode_tmp);
1183       movl(tmp_reg, Address(tmp_reg, Klass::access_flags_offset()));
1184       testl(tmp_reg, JVM_ACC_IS_VALUE_BASED_CLASS);
1185       jcc(Assembler::notZero, slow_case);
1186     }
1187 
1188     if (LockingMode == LM_LIGHTWEIGHT) {
1189 #ifdef _LP64
1190       const Register thread = r15_thread;
1191       lightweight_lock(lock_reg, obj_reg, swap_reg, thread, tmp_reg, slow_case);
1192 #else
1193       // Lacking registers and thread on x86_32. Always take slow path.
1194       jmp(slow_case);
1195 #endif

1196     } else if (LockingMode == LM_LEGACY) {
1197       // Load immediate 1 into swap_reg %rax
1198       movl(swap_reg, 1);
1199 
1200       // Load (object->mark() | 1) into swap_reg %rax
1201       orptr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1202 
1203       // Save (object->mark() | 1) into BasicLock's displaced header
1204       movptr(Address(lock_reg, mark_offset), swap_reg);
1205 
1206       assert(lock_offset == 0,
1207              "displaced header must be first word in BasicObjectLock");
1208 
1209       lock();
1210       cmpxchgptr(lock_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1211       jcc(Assembler::zero, count_locking);
1212 
1213       const int zero_bits = LP64_ONLY(7) NOT_LP64(3);
1214 
1215       // Fast check for recursive lock.

1237       // These 3 tests can be done by evaluating the following
1238       // expression: ((mark - rsp) & (zero_bits - os::vm_page_size())),
1239       // assuming both stack pointer and pagesize have their
1240       // least significant bits clear.
1241       // NOTE: the mark is in swap_reg %rax as the result of cmpxchg
1242       subptr(swap_reg, rsp);
1243       andptr(swap_reg, zero_bits - (int)os::vm_page_size());
1244 
1245       // Save the test result, for recursive case, the result is zero
1246       movptr(Address(lock_reg, mark_offset), swap_reg);
1247       jcc(Assembler::notZero, slow_case);
1248 
1249       bind(count_locking);
1250     }
1251     inc_held_monitor_count();
1252     jmp(done);
1253 
1254     bind(slow_case);
1255 
1256     // Call the runtime routine for slow case
1257     call_VM(noreg,
1258             CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
1259             lock_reg);






1260     bind(done);
1261   }
1262 }
1263 
1264 
1265 // Unlocks an object. Used in monitorexit bytecode and
1266 // remove_activation.  Throws an IllegalMonitorException if object is
1267 // not locked by current thread.
1268 //
1269 // Args:
1270 //      rdx, c_rarg1: BasicObjectLock for lock
1271 //
1272 // Kills:
1273 //      rax
1274 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
1275 //      rscratch1 (scratch reg)
1276 // rax, rbx, rcx, rdx
1277 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
1278   assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
1279          "The argument is only for looks. It must be c_rarg1");

1288     const Register obj_reg    = LP64_ONLY(c_rarg3) NOT_LP64(rcx);  // Will contain the oop
1289 
1290     save_bcp(); // Save in case of exception
1291 
1292     if (LockingMode != LM_LIGHTWEIGHT) {
1293       // Convert from BasicObjectLock structure to object and BasicLock
1294       // structure Store the BasicLock address into %rax
1295       lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset()));
1296     }
1297 
1298     // Load oop into obj_reg(%c_rarg3)
1299     movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset()));
1300 
1301     // Free entry
1302     movptr(Address(lock_reg, BasicObjectLock::obj_offset()), NULL_WORD);
1303 
1304     if (LockingMode == LM_LIGHTWEIGHT) {
1305 #ifdef _LP64
1306       lightweight_unlock(obj_reg, swap_reg, r15_thread, header_reg, slow_case);
1307 #else
1308       // Lacking registers and thread on x86_32. Always take slow path.
1309       jmp(slow_case);


1310 #endif
1311     } else if (LockingMode == LM_LEGACY) {
1312       // Load the old header from BasicLock structure
1313       movptr(header_reg, Address(swap_reg,
1314                                  BasicLock::displaced_header_offset_in_bytes()));
1315 
1316       // Test for recursion
1317       testptr(header_reg, header_reg);
1318 
1319       // zero for recursive case
1320       jcc(Assembler::zero, count_locking);
1321 
1322       // Atomic swap back the old header
1323       lock();
1324       cmpxchgptr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
1325 
1326       // zero for simple unlock of a stack-lock case
1327       jcc(Assembler::notZero, slow_case);
1328 
1329       bind(count_locking);
< prev index next >