Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 6795:7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
Summary: use shorter instruction sequences for atomic add and atomic exchange when possible.
Reviewed-by: kvn, jrose
author | roland |
---|---|
date | Thu, 20 Sep 2012 16:49:17 +0200 |
parents | 8a02ca5e5576 |
children | 8e47bac5643a |
comparison
equal
deleted
inserted
replaced
6794:8ae8f9dd7099 | 6795:7eca5de9e0b6 |
---|---|
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 } |