-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
.NET has two concepts regarding how types are allocated and laid out in memory. The first is alignment
and ensures that the address for a new allocation is always evenly divisible by the target alignment. The second is packing
and ensures that the offset for a field relative to the containing type is always evenly divisible by the target packing.
These concepts are similar and having correct alignment should also guarantee correct packing. They are currently treated differently due to GC limitations, however. For example, Vector128<T>
has 16-byte
packing and is supposed to also have 16-byte
alignment. The packing
is always respected, regardless of whether the data is on the stack or heap and this means that for a struct S { byte x; Vector128<byte> y; }
the y
field is at offset 16
. The alignment
however, due to existing GC limitations, is not respected and the data encountered may be 4 or 8-byte aligned instead (there is a best effort, but not a guarantee that stack locals will be correctly aligned).
Mono does not currently respect the packing
or the alignment
for various ABI primitives (that is types that are considered "primitive" to the underlying Application Binary Interface for a given platform and therefore have well defined semantics).
The non runtime primitive types that need to be specially handled are at least:
Vector64<T>
Vector128<T>
Vector256<T>
Int128
UInt128
It would also be worthwhile to validate that CLong
, CULong
, and NFloat
are properly handled as well.