comparison src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @ 3671: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
35:7fb10f88f9db 36:bcc1dec26fe3
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 }