751 } |
751 } |
752 |
752 |
753 LIR_Opr addr = new_pointer_register(); |
753 LIR_Opr addr = new_pointer_register(); |
754 LIR_Address* a; |
754 LIR_Address* a; |
755 if(offset.result()->is_constant()) { |
755 if(offset.result()->is_constant()) { |
|
756 #ifdef _LP64 |
|
757 jlong c = offset.result()->as_jlong(); |
|
758 if ((jlong)((jint)c) == c) { |
|
759 a = new LIR_Address(obj.result(), |
|
760 (jint)c, |
|
761 as_BasicType(type)); |
|
762 } else { |
|
763 LIR_Opr tmp = new_register(T_LONG); |
|
764 __ move(offset.result(), tmp); |
|
765 a = new LIR_Address(obj.result(), |
|
766 tmp, |
|
767 as_BasicType(type)); |
|
768 } |
|
769 #else |
756 a = new LIR_Address(obj.result(), |
770 a = new LIR_Address(obj.result(), |
757 NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()), |
771 offset.result()->as_jint(), |
758 as_BasicType(type)); |
772 as_BasicType(type)); |
|
773 #endif |
759 } else { |
774 } else { |
760 a = new LIR_Address(obj.result(), |
775 a = new LIR_Address(obj.result(), |
761 offset.result(), |
776 offset.result(), |
762 LIR_Address::times_1, |
777 LIR_Address::times_1, |
763 0, |
778 0, |
1343 } else { |
1358 } else { |
1344 __ move(data, addr); |
1359 __ move(data, addr); |
1345 } |
1360 } |
1346 } |
1361 } |
1347 } |
1362 } |
|
1363 |
|
1364 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { |
|
1365 BasicType type = x->basic_type(); |
|
1366 LIRItem src(x->object(), this); |
|
1367 LIRItem off(x->offset(), this); |
|
1368 LIRItem value(x->value(), this); |
|
1369 |
|
1370 src.load_item(); |
|
1371 value.load_item(); |
|
1372 off.load_nonconstant(); |
|
1373 |
|
1374 LIR_Opr dst = rlock_result(x, type); |
|
1375 LIR_Opr data = value.result(); |
|
1376 bool is_obj = (type == T_ARRAY || type == T_OBJECT); |
|
1377 LIR_Opr offset = off.result(); |
|
1378 |
|
1379 assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type"); |
|
1380 LIR_Address* addr; |
|
1381 if (offset->is_constant()) { |
|
1382 #ifdef _LP64 |
|
1383 jlong c = offset->as_jlong(); |
|
1384 if ((jlong)((jint)c) == c) { |
|
1385 addr = new LIR_Address(src.result(), (jint)c, type); |
|
1386 } else { |
|
1387 LIR_Opr tmp = new_register(T_LONG); |
|
1388 __ move(offset, tmp); |
|
1389 addr = new LIR_Address(src.result(), tmp, type); |
|
1390 } |
|
1391 #else |
|
1392 addr = new LIR_Address(src.result(), offset->as_jint(), type); |
|
1393 #endif |
|
1394 } else { |
|
1395 addr = new LIR_Address(src.result(), offset, type); |
|
1396 } |
|
1397 |
|
1398 if (data != dst) { |
|
1399 __ move(data, dst); |
|
1400 data = dst; |
|
1401 } |
|
1402 if (x->is_add()) { |
|
1403 __ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr); |
|
1404 } else { |
|
1405 if (is_obj) { |
|
1406 // Do the pre-write barrier, if any. |
|
1407 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, |
|
1408 true /* do_load */, false /* patch */, NULL); |
|
1409 } |
|
1410 __ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr); |
|
1411 if (is_obj) { |
|
1412 // Seems to be a precise address |
|
1413 post_barrier(LIR_OprFact::address(addr), data); |
|
1414 } |
|
1415 } |
|
1416 } |