646 assert(x->number_of_arguments() == 4, "wrong type");
647 LIRItem obj (x->argument_at(0), this); // object
648 LIRItem offset(x->argument_at(1), this); // offset of field
649 LIRItem cmp (x->argument_at(2), this); // value to compare with field
650 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp
651
652 // Use temps to avoid kills
653 LIR_Opr t1 = FrameMap::G1_opr;
654 LIR_Opr t2 = FrameMap::G3_opr;
655 LIR_Opr addr = new_pointer_register();
656
657 // get address of field
658 obj.load_item();
659 offset.load_item();
660 cmp.load_item();
661 val.load_item();
662
663 __ add(obj.result(), offset.result(), addr);
664
665 if (type == objectType) { // Write-barrier needed for Object fields.
666 if (UseLoadBarrier) {
667 // Load barrier to make sure that cas_obj() sees a correct oop.
668 LIR_Opr pre_val = new_register(T_OBJECT);
669 __ load(new LIR_Address(addr, as_BasicType(type)), pre_val);
670 load_barrier(pre_val, addr);
671 }
672 pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
673 true /* do_load */, false /* patch */, NULL);
674 }
675
676 if (type == objectType)
677 __ cas_obj(addr, cmp.result(), val.result(), t1, t2);
678 else if (type == intType)
679 __ cas_int(addr, cmp.result(), val.result(), t1, t2);
680 else if (type == longType)
681 __ cas_long(addr, cmp.result(), val.result(), t1, t2);
682 else {
683 ShouldNotReachHere();
684 }
685 // generate conditional move of boolean result
686 LIR_Opr result = rlock_result(x);
1373
1374 if (is_obj) {
1375 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1376 true /* do_load */, false /* patch */, NULL);
1377 // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));
1378 }
1379 __ move(data, addr);
1380 if (is_obj) {
1381 // This address is precise
1382 post_barrier(LIR_OprFact::address(addr), data);
1383 }
1384 }
1385 }
1386
1387
1388 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
1389 BasicType type, bool is_volatile) {
1390 {
1391 LIR_Address* addr = new LIR_Address(src, offset, type);
1392 __ load(addr, dst);
1393 if (type == T_OBJECT && UseLoadBarrier) {
1394 load_barrier(dst, LIR_OprFact::address(addr));
1395 }
1396 }
1397 }
1398
1399 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1400 BasicType type = x->basic_type();
1401 LIRItem src(x->object(), this);
1402 LIRItem off(x->offset(), this);
1403 LIRItem value(x->value(), this);
1404
1405 src.load_item();
1406 value.load_item();
1407 off.load_nonconstant();
1408
1409 LIR_Opr dst = rlock_result(x, type);
1410 LIR_Opr data = value.result();
1411 bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1412 LIR_Opr offset = off.result();
1413
1423 jint c = (jint)l;
1424 addr = new LIR_Address(src.result(), c, type);
1425 } else {
1426 addr = new LIR_Address(src.result(), offset, type);
1427 }
1428
1429 LIR_Opr tmp = LIR_OprFact::illegalOpr;
1430 LIR_Opr ptr = LIR_OprFact::illegalOpr;
1431
1432 if (is_obj) {
1433 // Do the pre-write barrier, if any.
1434 // barriers on sparc don't work with a base + index address
1435 tmp = FrameMap::G3_opr;
1436 ptr = new_pointer_register();
1437 __ add(src.result(), off.result(), ptr);
1438 pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
1439 true /* do_load */, false /* patch */, NULL);
1440 }
1441 __ xchg(LIR_OprFact::address(addr), dst, dst, tmp);
1442 if (is_obj) {
1443 if (UseLoadBarrier) {
1444 load_barrier(dst);
1445 }
1446
1447 // Seems to be a precise address
1448 post_barrier(ptr, data);
1449 }
1450 }
|
646 assert(x->number_of_arguments() == 4, "wrong type");
647 LIRItem obj (x->argument_at(0), this); // object
648 LIRItem offset(x->argument_at(1), this); // offset of field
649 LIRItem cmp (x->argument_at(2), this); // value to compare with field
650 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp
651
652 // Use temps to avoid kills
653 LIR_Opr t1 = FrameMap::G1_opr;
654 LIR_Opr t2 = FrameMap::G3_opr;
655 LIR_Opr addr = new_pointer_register();
656
657 // get address of field
658 obj.load_item();
659 offset.load_item();
660 cmp.load_item();
661 val.load_item();
662
663 __ add(obj.result(), offset.result(), addr);
664
665 if (type == objectType) { // Write-barrier needed for Object fields.
666 if (UseZGC) {
667 // Load barrier to make sure that cas_obj() sees a correct oop.
668 LIR_Opr pre_val = new_register(T_OBJECT);
669 __ load(new LIR_Address(addr, as_BasicType(type)), pre_val);
670 load_barrier(pre_val, addr);
671 }
672 pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
673 true /* do_load */, false /* patch */, NULL);
674 }
675
676 if (type == objectType)
677 __ cas_obj(addr, cmp.result(), val.result(), t1, t2);
678 else if (type == intType)
679 __ cas_int(addr, cmp.result(), val.result(), t1, t2);
680 else if (type == longType)
681 __ cas_long(addr, cmp.result(), val.result(), t1, t2);
682 else {
683 ShouldNotReachHere();
684 }
685 // generate conditional move of boolean result
686 LIR_Opr result = rlock_result(x);
1373
1374 if (is_obj) {
1375 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
1376 true /* do_load */, false /* patch */, NULL);
1377 // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));
1378 }
1379 __ move(data, addr);
1380 if (is_obj) {
1381 // This address is precise
1382 post_barrier(LIR_OprFact::address(addr), data);
1383 }
1384 }
1385 }
1386
1387
1388 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
1389 BasicType type, bool is_volatile) {
1390 {
1391 LIR_Address* addr = new LIR_Address(src, offset, type);
1392 __ load(addr, dst);
1393 if (type == T_OBJECT && UseZGC) {
1394 load_barrier(dst, LIR_OprFact::address(addr));
1395 }
1396 }
1397 }
1398
1399 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
1400 BasicType type = x->basic_type();
1401 LIRItem src(x->object(), this);
1402 LIRItem off(x->offset(), this);
1403 LIRItem value(x->value(), this);
1404
1405 src.load_item();
1406 value.load_item();
1407 off.load_nonconstant();
1408
1409 LIR_Opr dst = rlock_result(x, type);
1410 LIR_Opr data = value.result();
1411 bool is_obj = (type == T_ARRAY || type == T_OBJECT);
1412 LIR_Opr offset = off.result();
1413
1423 jint c = (jint)l;
1424 addr = new LIR_Address(src.result(), c, type);
1425 } else {
1426 addr = new LIR_Address(src.result(), offset, type);
1427 }
1428
1429 LIR_Opr tmp = LIR_OprFact::illegalOpr;
1430 LIR_Opr ptr = LIR_OprFact::illegalOpr;
1431
1432 if (is_obj) {
1433 // Do the pre-write barrier, if any.
1434 // barriers on sparc don't work with a base + index address
1435 tmp = FrameMap::G3_opr;
1436 ptr = new_pointer_register();
1437 __ add(src.result(), off.result(), ptr);
1438 pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
1439 true /* do_load */, false /* patch */, NULL);
1440 }
1441 __ xchg(LIR_OprFact::address(addr), dst, dst, tmp);
1442 if (is_obj) {
1443 if (UseZGC) {
1444 load_barrier(dst);
1445 }
1446
1447 // Seems to be a precise address
1448 post_barrier(ptr, data);
1449 }
1450 }
|