-
-
Notifications
You must be signed in to change notification settings - Fork 987
/
Copy pathTailCallDiagnoserTests.cs
92 lines (75 loc) · 3.5 KB
/
TailCallDiagnoserTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#if NETFRAMEWORK
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnostics.Windows;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Tests.Loggers;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.IntegrationTests.Xunit;
using BenchmarkDotNet.Tests.XUnit;
using Xunit;
using Xunit.Abstractions;
namespace BenchmarkDotNet.IntegrationTests
{
public class TailCallDiagnoserTests : BenchmarkTestExecutor
{
private const string WindowsOnly = "Use JIT ETW Tail Call Event (Windows only)";
private const string TAIL_CALL_MARK = "Tail call type";
public TailCallDiagnoserTests(ITestOutputHelper outputHelper) : base(outputHelper)
{
}
public static IEnumerable<object[]> GetJits()
=> new[]
{
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
};
public class TailCallBenchmarks
{
private long FactorialWithTailing(int pos, int depth)
=> pos == 0 ? depth : FactorialWithTailing(pos - 1, depth * pos);
private long FactorialWithTailing(int depth) => FactorialWithTailing(1, depth);
[Benchmark]
public long Factorial() => FactorialWithTailing(7);
}
public class NonTailCallBenchmarks
{
private long FactorialWithoutTailing(int depth) => depth == 0 ? 1 : depth * FactorialWithoutTailing(depth - 1);
[Benchmark]
public long Factorial() => FactorialWithoutTailing(7);
}
[TheoryEnvSpecific(WindowsOnly, EnvRequirement.WindowsOnly)]
[MemberData(nameof(GetJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void TailCallDiagnoserCatchesTailCallEvents(Jit jit, Platform platform, Runtime runtime)
{
var output = Execute<TailCallBenchmarks>(jit, platform, runtime);
Assert.Contains(output.CapturedOutput, x => x.Text.Contains(TAIL_CALL_MARK));
}
[TheoryEnvSpecific(WindowsOnly, EnvRequirement.WindowsOnly)]
[MemberData(nameof(GetJits))]
[Trait(Constants.Category, Constants.BackwardCompatibilityCategory)]
public void TailCallDiagnoserNotCatchesTailCallEvents(Jit jit, Platform platform, Runtime runtime)
{
var output = Execute<NonTailCallBenchmarks>(jit, platform, runtime);
Assert.DoesNotContain(output.CapturedOutput, x => x.Text.Contains(TAIL_CALL_MARK));
}
private LogCapture Execute<T>(Jit jit, Platform platform, Runtime runtime)
{
var tailCallDiagnoser = new TailCallDiagnoser(false, true);
CanExecute<T>(CreateConfig(jit, platform, runtime, tailCallDiagnoser));
return tailCallDiagnoser.Logger;
}
private IConfig CreateConfig(Jit jit, Platform platform, Runtime runtime, TailCallDiagnoser diagnoser) => ManualConfig.CreateEmpty()
.AddJob(Job.Dry.WithJit(jit).WithPlatform(platform).WithRuntime(runtime))
.AddLogger(DefaultConfig.Instance.GetLoggers().ToArray())
.AddColumnProvider(DefaultColumnProviders.Instance)
.AddDiagnoser(diagnoser)
.AddLogger(new OutputLogger(Output));
}
}
#endif