Skip to content

Commit 3cbd6dc

Browse files
committed
Simplify IInProcessDiagnoser interface.
Return `InProcessDiagnoserHandlerData` type instead of tuple.
1 parent 4be04d1 commit 3cbd6dc

File tree

9 files changed

+53
-42
lines changed

9 files changed

+53
-42
lines changed

src/BenchmarkDotNet/Code/CodeGenerator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,15 @@ private static string GetInProcessDiagnoserRouters(BenchmarkBuildInfo buildInfo)
260260

261261
static string? ToSourceCode(IInProcessDiagnoser diagnoser, BenchmarkCase benchmarkCase, int index)
262262
{
263-
var (handlerType, serializedConfig) = diagnoser.GetSeparateProcessHandlerTypeAndSerializedConfig(benchmarkCase);
264-
if (handlerType is null)
263+
var handlerData = diagnoser.GetHandlerData(benchmarkCase);
264+
if (handlerData.HandlerType is null)
265265
{
266266
return null;
267267
}
268268
string routerType = typeof(InProcessDiagnoserRouter).GetCorrectCSharpTypeName();
269269
return $$"""
270270
new {{routerType}}() {
271-
{{nameof(InProcessDiagnoserRouter.handler)}} = {{routerType}}.{{nameof(InProcessDiagnoserRouter.Init)}}(new {{handlerType.GetCorrectCSharpTypeName()}}(), {{SourceCodeHelper.ToSourceCode(serializedConfig)}}),
271+
{{nameof(InProcessDiagnoserRouter.handler)}} = {{routerType}}.{{nameof(InProcessDiagnoserRouter.Init)}}(new {{handlerData.HandlerType.GetCorrectCSharpTypeName()}}(), {{SourceCodeHelper.ToSourceCode(handlerData.SerializedConfig)}}),
272272
{{nameof(InProcessDiagnoserRouter.index)}} = {{index}},
273273
{{nameof(InProcessDiagnoserRouter.runMode)}} = {{SourceCodeHelper.ToSourceCode(diagnoser.GetRunMode(benchmarkCase))}}
274274
}

src/BenchmarkDotNet/Diagnosers/IDiagnoser.cs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.ComponentModel;
1+
using System.Collections.Generic;
42
using BenchmarkDotNet.Analysers;
53
using BenchmarkDotNet.Engines;
64
using BenchmarkDotNet.Exporters;
@@ -42,24 +40,14 @@ public interface IConfigurableDiagnoser<in TConfig> : IDiagnoser
4240
public interface IInProcessDiagnoser : IDiagnoser
4341
{
4442
/// <summary>
45-
/// Gets the type of the handler that will run in the separate benchmark process and its serialized config.
43+
/// Gets the data used to construct the <see cref="IInProcessDiagnoserHandler"/> that will run in the benchmark process.
4644
/// </summary>
4745
/// <remarks>
48-
/// The handlerType must implement <see cref="IInProcessDiagnoserHandler"/> and have a publicly accessible default constructor.
46+
/// The <see cref="InProcessDiagnoserHandlerData.HandlerType"/> must implement <see cref="IInProcessDiagnoserHandler"/> and have a publicly accessible default constructor.
4947
/// <para/>
5048
/// Return <see langword="default"/> to not run the diagnoser handler for the <paramref name="benchmarkCase"/>.
5149
/// </remarks>
52-
(Type? handlerType, string? serializedConfig) GetSeparateProcessHandlerTypeAndSerializedConfig(BenchmarkCase benchmarkCase);
53-
54-
// GetSameProcessHandler is needed to prevent the handler type from being trimmed for InProcess toolchains.
55-
56-
/// <summary>
57-
/// Gets the handler that will run in the same process.
58-
/// </summary>
59-
/// <remarks>
60-
/// Return <see langword="null"/> to not run the diagnoser handler for the <paramref name="benchmarkCase"/>.
61-
/// </remarks>
62-
IInProcessDiagnoserHandler? GetSameProcessHandler(BenchmarkCase benchmarkCase);
50+
InProcessDiagnoserHandlerData GetHandlerData(BenchmarkCase benchmarkCase);
6351

6452
/// <summary>
6553
/// Deserializes the results of the handler.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
4+
namespace BenchmarkDotNet.Diagnosers
5+
{
6+
/// <summary>
7+
/// The data used to construct the <see cref="IInProcessDiagnoserHandler"/> in the separate process.
8+
/// </summary>
9+
/// <param name="handlerType">The type of the <see cref="IInProcessDiagnoserHandler"/>.</param>
10+
/// <param name="serializedConfig">The serialized config that will be passed to <see cref="IInProcessDiagnoserHandler.Initialize(string?)"/>.</param>
11+
public readonly struct InProcessDiagnoserHandlerData(
12+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
13+
Type? handlerType,
14+
string? serializedConfig)
15+
{
16+
/// <summary>
17+
/// The type of the <see cref="IInProcessDiagnoserHandler"/>. If <see langword="null"/>, the handler will not be created.
18+
/// </summary>
19+
/// <remarks>
20+
/// The type must implement <see cref="IInProcessDiagnoserHandler"/> and have a publicly accessible default constructor.
21+
/// <para/>
22+
/// </remarks>
23+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
24+
public Type? HandlerType { get; } = handlerType;
25+
26+
/// <summary>
27+
/// The serialized config that will be passed to <see cref="IInProcessDiagnoserHandler.Initialize(string?)"/>.
28+
/// </summary>
29+
public string? SerializedConfig { get; } = serializedConfig;
30+
}
31+
}

src/BenchmarkDotNet/Diagnosers/InProcessDiagnoserRouter.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using JetBrains.Annotations;
2+
using System;
23
using System.ComponentModel;
34

45
namespace BenchmarkDotNet.Diagnosers;
@@ -16,4 +17,9 @@ public static IInProcessDiagnoserHandler Init(IInProcessDiagnoserHandler handler
1617
handler.Initialize(serializedConfig);
1718
return handler;
1819
}
20+
21+
internal static IInProcessDiagnoserHandler? CreateOrNull(InProcessDiagnoserHandlerData data)
22+
=> data.HandlerType is null
23+
? null
24+
: Init((IInProcessDiagnoserHandler) Activator.CreateInstance(data.HandlerType), data.SerializedConfig);
1925
}

src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,18 @@ private static IEnumerable<IExporter> GetExporters(Dictionary<BenchmarkCase, Dis
215215
private static long SumNativeCodeSize(DisassemblyResult disassembly)
216216
=> disassembly.Methods.Sum(method => method.Maps.Sum(map => map.SourceCodes.OfType<Asm>().Sum(asm => asm.InstructionLength)));
217217

218-
(Type? handlerType, string? serializedConfig) IInProcessDiagnoser.GetSeparateProcessHandlerTypeAndSerializedConfig(BenchmarkCase benchmarkCase)
218+
InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)
219219
{
220220
if (GetRunMode(benchmarkCase) == RunMode.None
221221
|| Config.RunInHost
222+
// We don't use handler for InProcess toolchains, the host diagnoser already handles it without needing to serialize data.
223+
|| (benchmarkCase.Job.Infrastructure.TryGetToolchain(out var toolchain) && toolchain.IsInProcess)
222224
// Mono disassembler always runs another process.
223225
|| ShouldUseMonoDisassembler(benchmarkCase))
224226
{
225227
return default;
226228
}
227-
return (typeof(DisassemblyDiagnoserInProcessHandler), BuildClrMdArgs(benchmarkCase, null, 0).Serialize());
229+
return new(typeof(DisassemblyDiagnoserInProcessHandler), BuildClrMdArgs(benchmarkCase, null, 0).Serialize());
228230
}
229231

230232
void IInProcessDiagnoser.DeserializeResults(BenchmarkCase benchmarkCase, string results)
@@ -235,9 +237,6 @@ void IInProcessDiagnoser.DeserializeResults(BenchmarkCase benchmarkCase, string
235237
this.results.Add(benchmarkCase, result);
236238
}
237239

238-
// We don't use handler for InProcess toolchains, the host diagnoser already handles it without needing to serialize data.
239-
public IInProcessDiagnoserHandler? GetSameProcessHandler(BenchmarkCase benchmarkCase) => null;
240-
241240
private class NativeCodeSizeMetricDescriptor : IMetricDescriptor
242241
{
243242
internal static readonly IMetricDescriptor Instance = new NativeCodeSizeMetricDescriptor();

src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReuse.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static (Job, EngineParameters, IEngineFactory) PrepareForRun<T>(T instanc
3434
{
3535
index = i,
3636
runMode = d.GetRunMode(benchmarkCase),
37-
handler = d.GetSameProcessHandler(benchmarkCase)
37+
handler = InProcessDiagnoserRouter.CreateOrNull(d.GetHandlerData(benchmarkCase))
3838
})
3939
.Where(r => r.handler != null)
4040
.ToArray(),

src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public static void RunCore(IHost host, ExecuteParameters parameters)
136136
{
137137
index = i,
138138
runMode = d.GetRunMode(benchmarkCase),
139-
handler = d.GetSameProcessHandler(benchmarkCase)
139+
handler = Diagnosers.InProcessDiagnoserRouter.CreateOrNull(d.GetHandlerData(benchmarkCase))
140140
})
141141
.Where(r => r.handler != null)
142142
.ToArray()],

tests/BenchmarkDotNet.IntegrationTests/Diagnosers/MockInProcessDiagnoser.cs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using BenchmarkDotNet.Running;
88
using BenchmarkDotNet.Validators;
99
using System.Collections.Generic;
10-
using System;
1110

1211
namespace BenchmarkDotNet.IntegrationTests.Diagnosers;
1312

@@ -36,22 +35,10 @@ public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }
3635

3736
public IEnumerable<ValidationError> Validate(ValidationParameters validationParameters) => [];
3837

39-
public (Type? handlerType, string? serializedConfig) GetSeparateProcessHandlerTypeAndSerializedConfig(BenchmarkCase benchmarkCase)
38+
InProcessDiagnoserHandlerData IInProcessDiagnoser.GetHandlerData(BenchmarkCase benchmarkCase)
4039
=> RunMode == RunMode.None
4140
? default
42-
: (typeof(MockInProcessDiagnoserHandler), ExpectedResult);
43-
44-
public virtual IInProcessDiagnoserHandler? GetSameProcessHandler(BenchmarkCase benchmarkCase)
45-
{
46-
var (handlerType, serializedConfig) = GetSeparateProcessHandlerTypeAndSerializedConfig(benchmarkCase);
47-
if (handlerType == null)
48-
{
49-
return null;
50-
}
51-
var handler = (IInProcessDiagnoserHandler)Activator.CreateInstance(handlerType);
52-
handler.Initialize(serializedConfig);
53-
return handler;
54-
}
41+
: new(typeof(MockInProcessDiagnoserHandler), ExpectedResult);
5542

5643
public void DeserializeResults(BenchmarkCase benchmarkCase, string results)
5744
{

tests/BenchmarkDotNet.IntegrationTests/DisassemblyDiagnoserTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public DisassemblyDiagnoserTests(ITestOutputHelper output) : base(output) { }
2828

2929
public static IEnumerable<object[]> GetAllJits()
3030
{
31-
yield return [RuntimeInformation.GetCurrentJit(), RuntimeInformation.GetCurrentPlatform(), InProcessEmitToolchain.DontLogOutput]; // InProcess
31+
yield return [RuntimeInformation.GetCurrentJit(), RuntimeInformation.GetCurrentPlatform(), InProcessEmitToolchain.Instance]; // InProcess
3232

3333
if (RuntimeInformation.IsFullFramework)
3434
{

0 commit comments

Comments
 (0)