Skip to content

Commit

Permalink
arm64 disassembler tests (#2222)
Browse files Browse the repository at this point in the history
* run the disassembler tests on arm64

* run the disassembler tests on Linux

* improve failed test output

* disable failing test
  • Loading branch information
adamsitnik authored Dec 8, 2022
1 parent ee24d7b commit 530d001
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
4 changes: 4 additions & 0 deletions src/BenchmarkDotNet.Disassembler.x64/DataContracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ public abstract class Asm : SourceCode
public class IntelAsm : Asm
{
public Instruction Instruction { get; set; }

public override string ToString() => Instruction.ToString();
}

public class Arm64Asm : Asm
{
#if !CLRMDV1 // don't include it in ClrMD V1 disassembler that supports only x86 and x64
public Gee.External.Capstone.Arm64.Arm64Instruction Instruction { get; set; }

public override string ToString() => Instruction.ToString();
#endif
}

Expand Down
61 changes: 39 additions & 22 deletions tests/BenchmarkDotNet.IntegrationTests/DisassemblyDiagnoserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,38 @@
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.IntegrationTests.Xunit;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Tests.Loggers;
using BenchmarkDotNet.Tests.XUnit;
using Xunit;
using Xunit.Abstractions;

namespace BenchmarkDotNet.IntegrationTests
{
public class DisassemblyDiagnoserTests : BenchmarkTestExecutor
{
private const string WindowsOnly = "Disassembler supports only Windows";

public DisassemblyDiagnoserTests(ITestOutputHelper output) : base(output) { }

public static IEnumerable<object[]> GetAllJits()
=> new[]
{
if (RuntimeInformation.IsFullFramework)
{
#if NETFRAMEWORK
new object[] { Jit.LegacyJit, Platform.X86, ClrRuntime.Net462 }, // 32bit LegacyJit for desktop .NET
new object[] { Jit.LegacyJit, Platform.X64, ClrRuntime.Net462 }, // 64bit LegacyJit for desktop .NET

new object[] { Jit.RyuJit, Platform.X64, ClrRuntime.Net462 }, // RyuJit for desktop .NET
#endif
new object[] { Jit.RyuJit, Platform.X64, CoreRuntime.Core70 }, // .NET Core

// we could add new object[] { Jit.Llvm, Platform.X64, new MonoRuntime() } here but our CI would need to have Mono installed..
};
yield return new object[] { Jit.LegacyJit, Platform.X86, ClrRuntime.Net462 }; // 32bit LegacyJit for desktop .NET
yield return new object[] { Jit.LegacyJit, Platform.X64, ClrRuntime.Net462 }; // 64bit LegacyJit for desktop .NET
yield return new object[] { Jit.RyuJit, Platform.X64, ClrRuntime.Net462 }; // RyuJit for desktop .NET
}
else if (RuntimeInformation.IsNetCore)
{
if (RuntimeInformation.GetCurrentPlatform() is Platform.X86 or Platform.X64)
{
yield return new object[] { Jit.RyuJit, Platform.X64, CoreRuntime.Core70 }; // .NET Core x64
}
else if (RuntimeInformation.GetCurrentPlatform() is Platform.Arm64 && RuntimeInformation.IsLinux())
{
yield return new object[] { Jit.RyuJit, Platform.Arm64, CoreRuntime.Core70 }; // .NET Core arm64
}
}
// we could add new object[] { Jit.Llvm, Platform.X64, new MonoRuntime() } here but our CI would need to have Mono installed..
}

public class WithCalls
{
Expand Down Expand Up @@ -71,11 +77,14 @@ public void Recursive()
[MethodImpl(MethodImplOptions.NoInlining)] public void Benchmark(bool justAnOverload) { } // we need to test overloads (#562)
}

[TheoryWindowsOnly(WindowsOnly)]
[Theory]
[MemberData(nameof(GetAllJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void CanDisassembleAllMethodCalls(Jit jit, Platform platform, Runtime runtime)
{
if (RuntimeInformation.IsMacOS()) return; // currently not supported
if (RuntimeInformation.IsLinux()) return; // https://github.com/dotnet/BenchmarkDotNet/issues/2223

var disassemblyDiagnoser = new DisassemblyDiagnoser(
new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));

Expand All @@ -88,11 +97,13 @@ public void CanDisassembleAllMethodCalls(Jit jit, Platform platform, Runtime run
AssertDisassembled(disassemblyDiagnoser, $"{nameof(WithCalls.Recursive)}()");
}

[TheoryWindowsOnly(WindowsOnly)]
[Theory]
[MemberData(nameof(GetAllJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void CanDisassembleAllMethodCallsUsingFilters(Jit jit, Platform platform, Runtime runtime)
{
if (RuntimeInformation.IsMacOS()) return; // currently not supported

var disassemblyDiagnoser = new DisassemblyDiagnoser(
new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 1, filters: new[] { "*WithCalls*" }));

Expand All @@ -111,11 +122,13 @@ public void CanDisassembleAllMethodCallsUsingFilters(Jit jit, Platform platform,
public T Create() => new T();
}

[TheoryWindowsOnly(WindowsOnly)]
[Theory]
[MemberData(nameof(GetAllJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void CanDisassembleGenericTypes(Jit jit, Platform platform, Runtime runtime)
{
if (RuntimeInformation.IsMacOS()) return; // currently not supported

var disassemblyDiagnoser = new DisassemblyDiagnoser(
new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));

Expand All @@ -131,19 +144,22 @@ public class WithInlineable
[Benchmark] public void JustReturn() { }
}

[TheoryWindowsOnly(WindowsOnly)]
[Theory]
[MemberData(nameof(GetAllJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void CanDisassembleInlinableBenchmarks(Jit jit, Platform platform, Runtime runtime)
{
if (RuntimeInformation.IsMacOS()) return; // currently not supported
if (RuntimeInformation.IsLinux()) return; // https://github.com/dotnet/BenchmarkDotNet/issues/2223

var disassemblyDiagnoser = new DisassemblyDiagnoser(
new DisassemblyDiagnoserConfig(printSource: true, maxDepth: 3));

CanExecute<WithInlineable>(CreateConfig(jit, platform, runtime, disassemblyDiagnoser, RunStrategy.Monitoring));

var disassemblyResult = disassemblyDiagnoser.Results.Values.Single(result => result.Methods.Count(method => method.Name.Contains(nameof(WithInlineable.JustReturn))) == 1);

Assert.Contains(disassemblyResult.Methods, method => method.Maps.Any(map => map.SourceCodes.OfType<IntelAsm>().All(asm => asm.Instruction.ToString().Contains("ret"))));
Assert.Contains(disassemblyResult.Methods, method => method.Maps.Any(map => map.SourceCodes.OfType<Asm>().All(asm => asm.ToString().Contains("ret"))));
}

private IConfig CreateConfig(Jit jit, Platform platform, Runtime runtime, IDiagnoser disassemblyDiagnoser, RunStrategy runStrategy)
Expand All @@ -159,9 +175,10 @@ private IConfig CreateConfig(Jit jit, Platform platform, Runtime runtime, IDiagn

private void AssertDisassembled(DisassemblyDiagnoser diagnoser, string methodSignature)
{
Assert.True(diagnoser.Results.Single().Value
.Methods.Any(method => method.Name.EndsWith(methodSignature) && method.Maps.Any(map => map.SourceCodes.Any())),
$"{methodSignature} is missing");
DisassemblyResult result = diagnoser.Results.Single().Value;

Assert.Contains(methodSignature, result.Methods.Select(m => m.Name.Split('.').Last()).ToArray());
Assert.Contains(result.Methods.Single(m => m.Name.EndsWith(methodSignature)).Maps, map => map.SourceCodes.Any());
}
}
}

0 comments on commit 530d001

Please # to comment.