-
Notifications
You must be signed in to change notification settings - Fork 5k
Replace Unsafe.As
with Unsafe.Read{Write}Unaligned
#113293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Doesn't depend upon implementation specific behaviour, i.e. that the array data is properly aligned.
@@ -600,7 +600,7 @@ internal static void Unbox_Nullable(ref byte destPtr, MethodTable* typeMT, objec | |||
} | |||
else | |||
{ | |||
Unsafe.As<byte, bool>(ref destPtr) = true; | |||
Unsafe.WriteUnaligned(ref destPtr, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bools are one byte long so this is not needed; accessing them is always aligned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and below, can you replace these byte <-> bool with ternary ops and run MihuBot?
Unsafe.As
with Unsafe.ReadUnaligned
for loadsUnsafe.As
with Unsafe.Read{Write}Unaligned
@@ -69,7 +69,7 @@ private BoxCache(RuntimeType rt) | |||
{ | |||
// If the allocator is null, then we shouldn't allocate and make a copy, | |||
// we should return the data as the object it currently is. | |||
return Unsafe.As<byte, object>(ref data); | |||
return Unsafe.ReadUnaligned<object>(ref data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GC references are not expected to be not-aligned. We can probably do Unsafe.Read here with a debug assert checking the alignment.
Same in other places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can introduce an internal helper in Unsafe
: ReadAligned
that checks alignment in Debug.Assert
return true; | ||
|
||
case EETypeElementType.Byte: | ||
result = (ulong)(long)Unsafe.As<byte, byte>(ref pValue); | ||
result = (ulong)(long)Unsafe.ReadUnaligned<byte>(ref pValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pValue is already byte, it doesn't need Unsafe. Same for SByte
@@ -1166,21 +1166,21 @@ internal object GetValue() | |||
ref byte data = ref this.GetRawData(); | |||
return InternalGetCorElementType() switch | |||
{ | |||
CorElementType.ELEMENT_TYPE_I1 => Unsafe.As<byte, sbyte>(ref data), | |||
CorElementType.ELEMENT_TYPE_I1 => Unsafe.ReadUnaligned<sbyte>(ref data), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here: sbyte is read from byte with unsafe
@@ -1256,21 +1256,21 @@ public override int GetHashCode() | |||
ref byte data = ref this.GetRawData(); | |||
return InternalGetCorElementType() switch | |||
{ | |||
CorElementType.ELEMENT_TYPE_I1 => Unsafe.As<byte, sbyte>(ref data).GetHashCode(), | |||
CorElementType.ELEMENT_TYPE_I1 => Unsafe.ReadUnaligned<sbyte>(ref data).GetHashCode(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@@ -1294,35 +1294,35 @@ public int CompareTo(object? target) | |||
switch (InternalGetCorElementType()) | |||
{ | |||
case CorElementType.ELEMENT_TYPE_I1: | |||
return Unsafe.As<byte, sbyte>(ref pThisValue).CompareTo(Unsafe.As<byte, sbyte>(ref pTargetValue)); | |||
return Unsafe.ReadUnaligned<sbyte>(ref pThisValue).CompareTo(Unsafe.ReadUnaligned<sbyte>(ref pTargetValue)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@@ -101,39 +101,39 @@ internal static unsafe bool TryGetUnboxedValueOfEnumOrInteger(object value, out | |||
switch (elementType) | |||
{ | |||
case EETypeElementType.Char: | |||
result = (ulong)(long)Unsafe.As<byte, char>(ref pValue); | |||
result = (ulong)(long)Unsafe.ReadUnaligned<char>(ref pValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pValue
is expected to be aligned properly. Changes in this method are unnecessary deoptimization.
@@ -161,23 +161,23 @@ internal static void PrimitiveWiden(EETypeElementType dstType, EETypeElementType | |||
switch (dstType) | |||
{ | |||
case EETypeElementType.Single: | |||
Unsafe.As<byte, float>(ref dstValue) = srcValue; | |||
Unsafe.WriteUnaligned(ref dstValue, (float)srcValue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. All changes in this method are unnecessary deoptimizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many of the changes are unnecessary deoptimizations (I have not commented on all of them). You need to check what the surrounding code does and only fix this in places where unaligned access is actually possible.
Tagging subscribers to this area: @dotnet/area-system-runtime |
Doesn't depend upon implementation specific behaviour, i.e. that data is properly aligned.
For
System.Private.CoreLib