Skip to content

Commit

Permalink
[Libraries][Android] Fix alignment for padding System.Decimal (dotnet…
Browse files Browse the repository at this point in the history
…#57978)

* [Libraries][Android] Fix alignment for padding System.Decimal

* Remove other active issue

* Remove trailing whitespaces

* Modify tests instead of the align behavior

* Remove Decimal struct special casing in marshal

* Remove wasm special case tests

Co-authored-by: Mitchell Hwang <[email protected]>
  • Loading branch information
mdh1418 and Mitchell Hwang authored Aug 25, 2021
1 parent a90b00e commit 5c04363
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ public void OffsetOf_ClassWithSequentialLayout_ReturnsExpected()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/49872", typeof(PlatformDetection), nameof(PlatformDetection.IsAndroid), nameof(PlatformDetection.Is32BitProcess))]
public void OffsetOf_ExplicitLayout_ReturnsExpected()
{
Type t = typeof(ExplicitLayoutTest);
Assert.Equal(56, Marshal.SizeOf(t));
Assert.Equal(OperatingSystem.IsAndroid() && RuntimeInformation.ProcessArchitecture == Architecture.X86 ? 52 : 56, Marshal.SizeOf(t));
Assert.Equal(new IntPtr(0), Marshal.OffsetOf(t, nameof(ExplicitLayoutTest.m_short1)));
Assert.Equal(new IntPtr(2), Marshal.OffsetOf(t, nameof(ExplicitLayoutTest.m_short2)));

Expand Down Expand Up @@ -107,27 +106,34 @@ public void OffsetOf_ValidField_ReturnsExpected()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/49872", typeof(PlatformDetection), nameof(PlatformDetection.IsAndroid), nameof(PlatformDetection.Is32BitProcess))]
public void OffsetOf_Decimal_ReturnsExpected()
{
Type t = typeof(FieldAlignmentTest_Decimal);

if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm))
if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86))
{
Assert.Equal(96, Marshal.SizeOf(t));
}
else if (OperatingSystem.IsAndroid())
{
Assert.Equal(72, Marshal.SizeOf(t));
}
else
{
Assert.Equal(88, Marshal.SizeOf(t));
}

Assert.Equal(new IntPtr(0), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.b)));
Assert.Equal(new IntPtr(8), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.p)));
Assert.Equal(OperatingSystem.IsAndroid() && RuntimeInformation.ProcessArchitecture == Architecture.X86 ? new IntPtr(4) : new IntPtr(8), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.p)));

if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.Wasm))
if (OperatingSystem.IsWindows() || (RuntimeInformation.ProcessArchitecture != Architecture.X86))
{
Assert.Equal(new IntPtr(88), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.s)));
}
else if (OperatingSystem.IsAndroid())
{
Assert.Equal(new IntPtr(68), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.s)));
}
else
{
Assert.Equal(new IntPtr(80), Marshal.OffsetOf(t, nameof(FieldAlignmentTest_Decimal.s)));
Expand Down Expand Up @@ -478,26 +484,26 @@ internal struct FieldAlignmentTest
public double m_double2; // 8 bytes
public byte m_byte3; // 1 byte
public byte m_byte4; // 1 byte
// 6 bytes of padding
// 6 bytes of padding (2 bytes on Linux x86)

public decimal m_decimal1; // 16 bytes
public char m_char4; // 1 byte
// 7 bytes of padding
// 7 bytes of padding (3 bytes on Linux x86)
}
struct FieldAlignmentTest_Decimal
{
public byte b; // 1 byte
// 7 bytes of padding
// 7 bytes of padding (3 bytes on Linux x86)

// The largest field in below struct is decimal (16 bytes wide).
// However, alignment requirement for the below struct should be only 8 bytes (not 16).
// This is because unlike fields of other types well known to mcg (like long, char etc.)
// which need to be aligned according to their byte size, decimal is really a struct
// with 8 byte alignment requirement.
public FieldAlignmentTest p; // 80 bytes (72 bytes on x86/Unix)
public FieldAlignmentTest p; // 80 bytes (72 bytes on Win x86/Unix) (64 bytes on Linux x86)

public short s; // 2 bytes
// 6 bytes of padding
// 6 bytes of padding (2 bytes on Linux x86)
}

struct FieldAlignmentTest_Guid
Expand Down
Loading

0 comments on commit 5c04363

Please sign in to comment.