/// <param name="value">The value to which the <paramref name="location1"/> parameter is set.</param>
/// <returns>The original value of <paramref name="location1"/>.</returns>
/// <exception cref="NullReferenceException">The address of location1 is a null pointer.</exception>
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
[return: NotNullIfNotNull(nameof(location1))]
public static extern object? Exchange([NotNullIfNotNull(nameof(value))] ref object? location1, object? value);
/// <param name="comparand">The object that is compared by reference to the object at <paramref name="location1"/>.</param>
/// <returns>The original value in <paramref name="location1"/>.</returns>
/// <exception cref="NullReferenceException">The address of <paramref name="location1"/> is a null pointer.</exception>
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
[return: NotNullIfNotNull(nameof(location1))]
public static extern object? CompareExchange(ref object? location1, object? value, object? comparand);
assert(addr->isUsedFromReg());
assert(data->isUsedFromReg());
- assert((size == EA_4BYTE) || (size == EA_PTRSIZE));
+ assert((size == EA_4BYTE) || (size == EA_PTRSIZE) || (size == EA_GCREF));
genConsumeOperands(node);
case IF_ARW_RRD:
case IF_ARW_CNS:
- assert(id->idGCref() == GCT_BYREF && (ins == INS_add || ins == INS_sub || ins == INS_sub_hide));
+ if (id->idGCref() == GCT_BYREF)
+ {
+ assert(ins == INS_add || ins == INS_sub || ins == INS_sub_hide);
+ }
+ else
+ {
+ assert((id->idGCref() == GCT_GCREF) && (ins == INS_cmpxchg || ins == INS_xchg));
+ }
break;
default:
{
break;
}
- if ((retType != TYP_INT) && (retType != TYP_LONG))
+ if ((retType == TYP_REF) && impStackTop(1).val->IsIntegralConst(0))
+ {
+ // Intrinsify "object" overload in case of null assignment
+ // since we don't need the write barrier.
+ }
+ else if ((retType != TYP_INT) && (retType != TYP_LONG))
{
break;
}
{
break;
}
- if ((retType != TYP_INT) && (retType != TYP_LONG))
+ if ((retType == TYP_REF) && impStackTop().val->IsIntegralConst(0))
+ {
+ // Intrinsify "object" overload in case of null assignment
+ // since we don't need the write barrier.
+ assert(ni == NI_System_Threading_Interlocked_Exchange);
+ }
+ else if ((retType != TYP_INT) && (retType != TYP_LONG))
{
break;
}