1216 Register field_index, Register field_offset,
1217 Register obj) {
1218 Label alloc_failed, empty_value, done;
1219 const Register src = field_offset;
1220 const Register alloc_temp = LP64_ONLY(rscratch1) NOT_LP64(rsi);
1221 const Register dst_temp = LP64_ONLY(rscratch2) NOT_LP64(rdi);
1222 assert_different_registers(obj, holder_klass, field_index, field_offset, dst_temp);
1223
1224 // Grap the inline field klass
1225 push(holder_klass);
1226 const Register field_klass = holder_klass;
1227 get_value_field_klass(holder_klass, field_index, field_klass);
1228
1229 //check for empty value klass
1230 test_klass_is_empty_value(field_klass, dst_temp, empty_value);
1231
1232 // allocate buffer
1233 push(obj); // save holder
1234 allocate_instance(field_klass, obj, alloc_temp, dst_temp, false, alloc_failed);
1235
1236 // Have a oop instance buffer, copy into it
1237 data_for_oop(obj, dst_temp, field_klass);
1238 pop(alloc_temp); // restore holder
1239 lea(src, Address(alloc_temp, field_offset));
1240 // call_VM_leaf, clobbers a few regs, save restore new obj
1241 push(obj);
1242 access_value_copy(IS_DEST_UNINITIALIZED, src, dst_temp, field_klass);
1243 pop(obj);
1244 pop(holder_klass);
1245 jmp(done);
1246
1247 bind(empty_value);
1248 get_empty_value_oop(field_klass, dst_temp, obj);
1249 pop(holder_klass);
1250 jmp(done);
1251
1252 bind(alloc_failed);
1253 pop(obj);
1254 pop(holder_klass);
1255 call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::read_flattened_field),
1256 obj, field_index, holder_klass);
1257
1258 bind(done);
1259 }
1260
1261 // Lock object
1262 //
1263 // Args:
1264 // rdx, c_rarg1: BasicObjectLock to be used for locking
1265 //
1266 // Kills:
1267 // rax, rbx
1268 void InterpreterMacroAssembler::lock_object(Register lock_reg) {
1269 assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
1270 "The argument is only for looks. It must be c_rarg1");
1271
1272 if (UseHeavyMonitors) {
1273 call_VM(noreg,
1274 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
1275 lock_reg);
1276 } else {
1277 Label done;
1278
1279 const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|
1216 Register field_index, Register field_offset,
1217 Register obj) {
1218 Label alloc_failed, empty_value, done;
1219 const Register src = field_offset;
1220 const Register alloc_temp = LP64_ONLY(rscratch1) NOT_LP64(rsi);
1221 const Register dst_temp = LP64_ONLY(rscratch2) NOT_LP64(rdi);
1222 assert_different_registers(obj, holder_klass, field_index, field_offset, dst_temp);
1223
1224 // Grap the inline field klass
1225 push(holder_klass);
1226 const Register field_klass = holder_klass;
1227 get_value_field_klass(holder_klass, field_index, field_klass);
1228
1229 //check for empty value klass
1230 test_klass_is_empty_value(field_klass, dst_temp, empty_value);
1231
1232 // allocate buffer
1233 push(obj); // save holder
1234 allocate_instance(field_klass, obj, alloc_temp, dst_temp, false, alloc_failed);
1235
1236 // Have an oop instance buffer, copy into it
1237 data_for_oop(obj, dst_temp, field_klass);
1238 pop(alloc_temp); // restore holder
1239 lea(src, Address(alloc_temp, field_offset));
1240 // call_VM_leaf, clobbers a few regs, save restore new obj
1241 push(obj);
1242 access_value_copy(IS_DEST_UNINITIALIZED, src, dst_temp, field_klass);
1243 pop(obj);
1244 pop(holder_klass);
1245 jmp(done);
1246
1247 bind(empty_value);
1248 get_empty_value_oop(field_klass, dst_temp, obj);
1249 pop(holder_klass);
1250 jmp(done);
1251
1252 bind(alloc_failed);
1253 pop(obj);
1254 pop(holder_klass);
1255 call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::read_flattened_field),
1256 obj, field_index, holder_klass);
1257
1258 bind(done);
1259 }
1260
1261 void InterpreterMacroAssembler::read_flattened_element(Register array, Register index,
1262 Register t1, Register t2,
1263 Register obj) {
1264 assert_different_registers(array, index, t1, t2);
1265 Label alloc_failed, empty_value, done;
1266 const Register array_klass = t2;
1267 const Register elem_klass = t1;
1268 const Register alloc_temp = LP64_ONLY(rscratch1) NOT_LP64(rsi);
1269 const Register dst_temp = LP64_ONLY(rscratch2) NOT_LP64(rdi);
1270
1271 // load in array->klass()->element_klass()
1272 load_klass(array_klass, array);
1273 movptr(elem_klass, Address(array_klass, ArrayKlass::element_klass_offset()));
1274
1275 //check for empty value klass
1276 test_klass_is_empty_value(elem_klass, dst_temp, empty_value);
1277
1278 // calc source into "array_klass" and free up some regs
1279 const Register src = array_klass;
1280 push(index); // preserve index reg in case alloc_failed
1281 data_for_value_array_index(array, array_klass, index, src);
1282
1283 allocate_instance(elem_klass, obj, alloc_temp, dst_temp, false, alloc_failed);
1284 // Have an oop instance buffer, copy into it
1285 movptr(Address(rsp, 0), obj); // preserve obj (overwrite index, no longer needed)
1286 data_for_oop(obj, dst_temp, elem_klass);
1287 access_value_copy(IS_DEST_UNINITIALIZED, src, dst_temp, elem_klass);
1288 pop(obj);
1289 jmp(done);
1290
1291 bind(empty_value);
1292 get_empty_value_oop(elem_klass, dst_temp, obj);
1293 jmp(done);
1294
1295 bind(alloc_failed);
1296 pop(index);
1297 if (array == c_rarg2) {
1298 mov(elem_klass, array);
1299 array = elem_klass;
1300 }
1301 call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::value_array_load), array, index);
1302
1303 bind(done);
1304 }
1305
1306
1307 // Lock object
1308 //
1309 // Args:
1310 // rdx, c_rarg1: BasicObjectLock to be used for locking
1311 //
1312 // Kills:
1313 // rax, rbx
1314 void InterpreterMacroAssembler::lock_object(Register lock_reg) {
1315 assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
1316 "The argument is only for looks. It must be c_rarg1");
1317
1318 if (UseHeavyMonitors) {
1319 call_VM(noreg,
1320 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
1321 lock_reg);
1322 } else {
1323 Label done;
1324
1325 const Register swap_reg = rax; // Must use rax for cmpxchg instruction
|