diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkAction.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkAction.cs
deleted file mode 100644
index 2cc2363f49..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkAction.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- /// Common API to run the Setup/Clean/Idle/Run methods
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public abstract class BenchmarkAction
- {
- /// Gets or sets invoke single callback.
- /// Invoke single callback.
- public Action InvokeSingle { get; protected set; }
-
- /// Gets or sets invoke multiple times callback.
- /// Invoke multiple times callback.
- public Action InvokeMultiple { get; protected set; }
-
- /// Gets the last run result.
- /// The last run result.
- public virtual object LastRunResult => null;
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionCodegen.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionCodegen.cs
deleted file mode 100644
index b77b2cfdc2..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionCodegen.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- ///
- /// How benchmark action code is generated
- ///
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public enum BenchmarkActionCodegen
- {
- ///
- /// The unroll feature is implemented using dynamic method codegen (Reflection.Emit).
- /// Provides most accurate results but may not work as expected on some platforms (e.g. .Net Native).
- ///
- ReflectionEmit,
-
- ///
- /// Fallback option: the unroll feature is implemented using
- /// method.
- /// Has additional overhead (+1 delegate call) but should work on all platforms.
- ///
- DelegateCombine
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory.cs
deleted file mode 100644
index 8def323161..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory.cs
+++ /dev/null
@@ -1,151 +0,0 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
-
-using BenchmarkDotNet.Extensions;
-using BenchmarkDotNet.Running;
-
-using JetBrains.Annotations;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- /// Helper class that creates instances.
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public static partial class BenchmarkActionFactory
- {
- ///
- /// Dispatch method that creates using
- /// or to find correct implementation.
- /// Either or should be not null.
- ///
- private static BenchmarkAction CreateCore(
- object instance,
- MethodInfo? targetMethod,
- MethodInfo? fallbackIdleSignature,
- BenchmarkActionCodegen codegenMode,
- int unrollFactor)
- {
- PrepareInstanceAndResultType(instance, targetMethod, fallbackIdleSignature, out var resultInstance, out var resultType);
-
- if (resultType == typeof(void))
- return new BenchmarkActionVoid(resultInstance, targetMethod, codegenMode, unrollFactor);
-
- if (resultType == typeof(Task))
- return new BenchmarkActionTask(resultInstance, targetMethod, codegenMode, unrollFactor);
-
- if (resultType.GetTypeInfo().IsGenericType)
- {
- var genericType = resultType.GetGenericTypeDefinition();
- var argType = resultType.GenericTypeArguments[0];
- if (typeof(Task<>) == genericType)
- return Create(
- typeof(BenchmarkActionTask<>).MakeGenericType(argType),
- resultInstance, targetMethod,
- codegenMode, unrollFactor);
-
- if (typeof(ValueTask<>).IsAssignableFrom(genericType))
- return Create(
- typeof(BenchmarkActionValueTask<>).MakeGenericType(argType),
- resultInstance, targetMethod,
- codegenMode, unrollFactor);
- }
-
- if (targetMethod == null && resultType.GetTypeInfo().IsValueType)
- // for Idle: we return int because creating bigger ValueType could take longer than benchmarked method itself.
- resultType = typeof(int);
-
- return Create(
- typeof(BenchmarkAction<>).MakeGenericType(resultType),
- resultInstance, targetMethod,
- codegenMode, unrollFactor);
- }
-
- private static void PrepareInstanceAndResultType(
- object instance, MethodInfo targetMethod, MethodInfo fallbackIdleSignature,
- out object resultInstance, out Type resultType)
- {
- var signature = targetMethod ?? fallbackIdleSignature;
- if (signature == null)
- throw new ArgumentNullException(
- nameof(fallbackIdleSignature),
- $"Either {nameof(targetMethod)} or {nameof(fallbackIdleSignature)} should be not null.");
-
- if (!signature.IsStatic && instance == null)
- throw new ArgumentNullException(
- nameof(instance),
- $"The {nameof(instance)} parameter should be not null as invocation method is instance method.");
-
- resultInstance = signature.IsStatic ? null : instance;
- resultType = signature.ReturnType;
-
- if (resultType == typeof(void))
- {
- // DONTTOUCH: async should be checked for target method
- // as fallbackIdleSignature used for result type detection only.
- bool isUsingAsyncKeyword = targetMethod?.HasAttribute() ?? false;
- if (isUsingAsyncKeyword)
- throw new NotSupportedException("Async void is not supported by design.");
- }
- }
-
- /// Helper to enforce .ctor signature.
- private static BenchmarkActionBase Create(Type actionType, object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor) =>
- (BenchmarkActionBase)Activator.CreateInstance(actionType, instance, method, codegenMode, unrollFactor);
-
- private static void FallbackMethod() { }
- private static readonly MethodInfo FallbackSignature = new Action(FallbackMethod).GetMethodInfo();
- private static readonly MethodInfo DummyMethod = typeof(DummyInstance).GetMethod(nameof(DummyInstance.Dummy));
-
- /// Creates run benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Describes how benchmark action code is generated.
- /// Unroll factor.
- /// Run benchmark action.
- public static BenchmarkAction CreateWorkload(Descriptor descriptor, object instance, BenchmarkActionCodegen codegenMode, int unrollFactor) =>
- CreateCore(instance, descriptor.WorkloadMethod, null, codegenMode, unrollFactor);
-
- /// Creates idle benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Describes how benchmark action code is generated.
- /// Unroll factor.
- /// Idle benchmark action.
- public static BenchmarkAction CreateOverhead(Descriptor descriptor, object instance, BenchmarkActionCodegen codegenMode, int unrollFactor) =>
- CreateCore(instance, null, descriptor.WorkloadMethod, codegenMode, unrollFactor);
-
- /// Creates global setup benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Setup benchmark action.
- public static BenchmarkAction CreateGlobalSetup(Descriptor descriptor, object instance) =>
- CreateCore(instance, descriptor.GlobalSetupMethod, FallbackSignature, BenchmarkActionCodegen.DelegateCombine, 1);
-
- /// Creates global cleanup benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Cleanup benchmark action.
- public static BenchmarkAction CreateGlobalCleanup(Descriptor descriptor, object instance) =>
- CreateCore(instance, descriptor.GlobalCleanupMethod, FallbackSignature, BenchmarkActionCodegen.DelegateCombine, 1);
-
- /// Creates global setup benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Setup benchmark action.
- public static BenchmarkAction CreateIterationSetup(Descriptor descriptor, object instance) =>
- CreateCore(instance, descriptor.IterationSetupMethod, FallbackSignature, BenchmarkActionCodegen.DelegateCombine, 1);
-
- /// Creates global cleanup benchmark action.
- /// Descriptor info.
- /// Instance of target.
- /// Cleanup benchmark action.
- public static BenchmarkAction CreateIterationCleanup(Descriptor descriptor, object instance) =>
- CreateCore(instance, descriptor.IterationCleanupMethod, FallbackSignature, BenchmarkActionCodegen.DelegateCombine, 1);
-
- /// Creates a dummy benchmark action.
- /// Dummy benchmark action.
- public static BenchmarkAction CreateDummy() =>
- CreateCore(new DummyInstance(), DummyMethod, null, BenchmarkActionCodegen.DelegateCombine, 1);
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Base.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Base.cs
deleted file mode 100644
index ba1fe75060..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Base.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-using System;
-using System.Linq;
-using System.Reflection;
-using System.Reflection.Emit;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- /*
- Design goals of the whole stuff:
- 0. Reusable API to call Setup/Clean/Overhead/Workload actions with arbitrary return value and store the result.
- Supported ones are: void, T, Task, Task, ValueTask. No input args, same as for outofproc benchmarks.
- 1. Overhead signature should match to the benchmark method signature (including static/instance modifier).
- 2. Should work under .Net native. There's CodegenMode option to use Delegate.Combine instead of emitting the code.
- 3. High data locality and no additional allocations / JIT where possible.
- This means NO closures allowed, no allocations but in .ctor and for LastCallResult boxing,
- all state should be stored explicitly as BenchmarkAction's fields.
- 4. There can be multiple benchmark actions per single target instance (workload, globalSetup, globalCleanup methods),
- so target instantiation is not a responsibility of the benchmark action.
- 5. Implementation should match to the code in BenchmarkProgram.txt.
- As example, this code emits loop unroll only, task waiting is implemented as a delegate call.
- Outofproc code uses TaskMethodInvoker.ExecuteBlocking callback for this.
- */
-
- // DONTTOUCH: Be VERY CAREFUL when changing the code.
- // Please, ensure that the implementation is in sync with content of BenchmarkProgram.txt
-
- /// Helper class that creates instances.
- public static partial class BenchmarkActionFactory
- {
- /// Base class that provides reusable API for final implementations.
- internal abstract class BenchmarkActionBase : BenchmarkAction
- {
- protected static TDelegate CreateWorkload(object? targetInstance, MethodInfo workloadMethod)
- {
- if (workloadMethod.IsStatic)
- return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate));
-
- return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate), targetInstance);
- }
-
- protected static TDelegate CreateWorkloadOrOverhead(
- object? targetInstance, MethodInfo? workloadMethod,
- TDelegate overheadStaticCallback, TDelegate overheadInstanceCallback) where TDelegate : notnull
- {
- if (workloadMethod == null)
- return targetInstance == null ? overheadStaticCallback : overheadInstanceCallback;
-
- if (workloadMethod.IsStatic)
- return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate));
-
- return (TDelegate)(object)workloadMethod.CreateDelegate(typeof(TDelegate), targetInstance);
- }
-
- protected static bool UseFallbackCode(BenchmarkActionCodegen codegenMode, int unrollFactor) =>
- unrollFactor <= 1 || codegenMode == BenchmarkActionCodegen.DelegateCombine;
-
- protected static TDelegate Unroll(TDelegate callback, int unrollFactor)
- {
- if (callback == null)
- throw new ArgumentNullException(nameof(callback));
-
- if (unrollFactor <= 1)
- return callback;
-
- return (TDelegate)(object)Delegate.Combine(
- Enumerable.Repeat((Delegate)(object)callback, unrollFactor).ToArray());
- }
-
- private const BindingFlags GetFieldFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
- protected static Action EmitInvokeMultiple(
- BenchmarkActionBase instance,
- string callbackFieldName,
- string storeResultFieldName,
- int unrollFactor)
- {
- if (instance == null)
- throw new ArgumentNullException(nameof(instance));
-
- if (callbackFieldName == null)
- throw new ArgumentNullException(nameof(callbackFieldName));
-
- var instanceType = instance.GetType();
- var callbackField = GetCallbackField(instanceType, callbackFieldName);
- var callbackInvokeMethod = callbackField.FieldType.GetTypeInfo().GetMethod(nameof(Action.Invoke))
- ?? throw new NullReferenceException($"{nameof(Action.Invoke)} not found");
- var storeResultField = GetStoreResultField(instanceType, storeResultFieldName, callbackInvokeMethod.ReturnType);
-
- // void InvokeMultipleEmitted(long x) // instance method associated with instanceType
- var m = new DynamicMethod("InvokeMultipleEmitted", typeof(void), new[] { instanceType, typeof(long) }, instanceType)
- {
- InitLocals = true
- };
-
- EmitInvokeMultipleBody(m, callbackField, callbackInvokeMethod, storeResultField, unrollFactor);
-
- return (Action)m.CreateDelegate(typeof(Action), instance);
- }
-
- private static FieldInfo GetCallbackField(Type instanceType, string callbackFieldName)
- {
- var callbackField = instanceType.GetTypeInfo().GetField(callbackFieldName, GetFieldFlags);
- if (callbackField == null)
- throw new ArgumentException($"Field {callbackFieldName} not found.", nameof(callbackFieldName));
-
- var callbackFieldType = callbackField.FieldType;
- if (callbackFieldType != typeof(Action) &&
- (!callbackFieldType.GetTypeInfo().IsGenericType || callbackFieldType.GetGenericTypeDefinition() != typeof(Func<>)))
- throw new ArgumentException(
- $"Type of {callbackFieldName} field should be either Action or Func.",
- nameof(callbackFieldName));
-
- return callbackField;
- }
-
- private static FieldInfo GetStoreResultField(
- Type instanceType, string storeResultFieldName, Type expectedFieldType)
- {
- if (expectedFieldType == typeof(void) || storeResultFieldName == null)
- return null;
-
- var storeResultField = instanceType.GetTypeInfo().GetField(storeResultFieldName, GetFieldFlags);
-
- if (expectedFieldType != storeResultField?.FieldType)
- throw new ArgumentException(
- $"Type of {storeResultFieldName} field should be equal to {expectedFieldType}.",
- nameof(storeResultFieldName));
-
- return storeResultField;
- }
-
- private static void EmitInvokeMultipleBody(
- DynamicMethod dynamicMethod,
- FieldInfo callbackField,
- MethodInfo callbackInvokeMethod,
- FieldInfo storeResultField, int unrollFactor)
- {
- /*
- // for long i = 0
- IL_0000: ldc.i4.0
- IL_0001: conv.i8
- IL_0002: stloc.0
-
- // jump to i < invokeCount
- IL_0003: br IL_0041
- // loop start (head: IL_0041)
- IL_0005: ... // loop body
-
- // i++;
- IL_003d: ldc.i4.1
- IL_003e: conv.i8
- IL_003f: add
- IL_0040: stloc.0
-
- // i < invokeCount
- IL_0041: ldloc.0
- IL_0042: ldarg.1
- IL_0043: blt IL_0005 // jump to loop start
- // end loop
-
- IL_0045: ret
- */
-
- bool noReturnValue = callbackInvokeMethod.ReturnType == typeof(void);
- bool hasStoreField = !noReturnValue && storeResultField != null;
-
- var g = dynamicMethod.GetILGenerator();
- g.DeclareLocal(typeof(long));
-
- var loopStart = g.DefineLabel();
- var loopCondition = g.DefineLabel();
-
- // for i = 0
- g.Emit(OpCodes.Ldc_I4_0);
- g.Emit(OpCodes.Conv_I8);
- g.Emit(OpCodes.Stloc_0);
-
- // jump to i < invokeCount
- g.Emit(OpCodes.Br, loopCondition);
-
- g.MarkLabel(loopStart);
- {
- // loop body: callback(); unroll
- for (int j = 0; j < unrollFactor; j++)
- {
- if (noReturnValue)
- {
- g.Emit(OpCodes.Ldarg_0); // this
- g.Emit(OpCodes.Ldfld, callbackField);
- g.Emit(OpCodes.Callvirt, callbackInvokeMethod);
- }
- else if (hasStoreField)
- {
- g.Emit(OpCodes.Ldarg_0); // this
- g.Emit(OpCodes.Dup); // this (copy will be used to store the field)
- g.Emit(OpCodes.Ldfld, callbackField);
- g.Emit(OpCodes.Callvirt, callbackInvokeMethod);
- g.Emit(OpCodes.Stfld, storeResultField);
- }
- else
- {
- g.Emit(OpCodes.Ldarg_0); // this
- g.Emit(OpCodes.Ldfld, callbackField);
- g.Emit(OpCodes.Callvirt, callbackInvokeMethod);
- g.Emit(OpCodes.Pop); // ignore the return value
- }
- }
-
- // i++;
- g.Emit(OpCodes.Ldloc_0);
- g.Emit(OpCodes.Ldc_I4_1);
- g.Emit(OpCodes.Conv_I8);
- g.Emit(OpCodes.Add);
- g.Emit(OpCodes.Stloc_0);
-
- // i < invokeCount
- g.MarkLabel(loopCondition);
- {
- g.Emit(OpCodes.Ldloc_0);
- g.Emit(OpCodes.Ldarg_1);
- g.Emit(OpCodes.Blt, loopStart); // jump to loop start
- }
- }
-
- g.Emit(OpCodes.Ret);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Dummy.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Dummy.cs
deleted file mode 100644
index dd067d37ae..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Dummy.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using JetBrains.Annotations;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- /// Helper class that creates instances.
- public static partial class BenchmarkActionFactory
- {
- private class DummyInstance
- {
- [UsedImplicitly]
- private int dummyField;
-
- public void Dummy()
- {
- // copy-pasted as emit is not supported across all platforms
- dummyField++; // 0
- dummyField++; // 1
- dummyField++; // 2
- dummyField++; // 3
- dummyField++; // 4
- dummyField++; // 5
- dummyField++; // 6
- dummyField++; // 7
- dummyField++; // 8
- dummyField++; // 9
- dummyField++; // 10
- dummyField++; // 11
- dummyField++; // 12
- dummyField++; // 13
- dummyField++; // 14
- dummyField++; // 15
- dummyField++; // 16
- dummyField++; // 17
- dummyField++; // 18
- dummyField++; // 19
- dummyField++; // 20
- dummyField++; // 21
- dummyField++; // 22
- dummyField++; // 23
- dummyField++; // 24
- dummyField++; // 25
- dummyField++; // 26
- dummyField++; // 27
- dummyField++; // 28
- dummyField++; // 29
- dummyField++; // 30
- dummyField++; // 31
- dummyField++; // 32
- dummyField++; // 33
- dummyField++; // 34
- dummyField++; // 35
- dummyField++; // 36
- dummyField++; // 37
- dummyField++; // 38
- dummyField++; // 39
- dummyField++; // 40
- dummyField++; // 41
- dummyField++; // 42
- dummyField++; // 43
- dummyField++; // 44
- dummyField++; // 45
- dummyField++; // 46
- dummyField++; // 47
- dummyField++; // 48
- dummyField++; // 49
- dummyField++; // 50
- dummyField++; // 51
- dummyField++; // 52
- dummyField++; // 53
- dummyField++; // 54
- dummyField++; // 55
- dummyField++; // 56
- dummyField++; // 57
- dummyField++; // 58
- dummyField++; // 59
- dummyField++; // 60
- dummyField++; // 61
- dummyField++; // 62
- dummyField++; // 63
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Implementations.cs b/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Implementations.cs
deleted file mode 100644
index 5ca5592e1e..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/BenchmarkActionFactory_Implementations.cs
+++ /dev/null
@@ -1,227 +0,0 @@
-using System;
-using System.Reflection;
-using System.Threading.Tasks;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- /*
- Design goals of the whole stuff: check the comments for BenchmarkActionBase.
- */
-
- // DONTTOUCH: Be VERY CAREFUL when changing the code.
- // Please, ensure that the implementation is in sync with content of BenchmarkProgram.txt
-
- /// Helper class that creates instances.
- public static partial class BenchmarkActionFactory
- {
- internal class BenchmarkActionVoid : BenchmarkActionBase
- {
- private readonly Action callback;
- private readonly Action unrolledCallback;
-
- public BenchmarkActionVoid(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
- {
- callback = CreateWorkloadOrOverhead(instance, method, OverheadStatic, OverheadInstance);
- InvokeSingle = callback;
-
- if (UseFallbackCode(codegenMode, unrollFactor))
- {
- unrolledCallback = Unroll(callback, unrollFactor);
- InvokeMultiple = InvokeMultipleHardcoded;
- }
- else
- {
- InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), null, unrollFactor);
- }
- }
-
- private static void OverheadStatic() { }
- private void OverheadInstance() { }
-
- private void InvokeMultipleHardcoded(long repeatCount)
- {
- for (long i = 0; i < repeatCount; i++)
- unrolledCallback();
- }
- }
-
- internal class BenchmarkAction : BenchmarkActionBase
- {
- private readonly Func callback;
- private readonly Func unrolledCallback;
- private T result;
-
- public BenchmarkAction(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
- {
- callback = CreateWorkloadOrOverhead>(instance, method, OverheadStatic, OverheadInstance);
- InvokeSingle = InvokeSingleHardcoded;
-
- if (UseFallbackCode(codegenMode, unrollFactor))
- {
- unrolledCallback = Unroll(callback, unrollFactor);
- InvokeMultiple = InvokeMultipleHardcoded;
- }
- else
- {
- InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), nameof(result), unrollFactor);
- }
- }
-
- private static T OverheadStatic() => default;
- private T OverheadInstance() => default;
-
- private void InvokeSingleHardcoded() => result = callback();
-
- private void InvokeMultipleHardcoded(long repeatCount)
- {
- for (long i = 0; i < repeatCount; i++)
- result = unrolledCallback();
- }
-
- public override object LastRunResult => result;
- }
-
- internal class BenchmarkActionTask : BenchmarkActionBase
- {
- private readonly Func startTaskCallback;
- private readonly Action callback;
- private readonly Action unrolledCallback;
-
- public BenchmarkActionTask(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
- {
- bool isIdle = method == null;
- if (!isIdle)
- {
- startTaskCallback = CreateWorkload>(instance, method);
- callback = ExecuteBlocking;
- }
- else
- {
- callback = Overhead;
- }
-
- InvokeSingle = callback;
-
- if (UseFallbackCode(codegenMode, unrollFactor))
- {
- unrolledCallback = Unroll(callback, unrollFactor);
- InvokeMultiple = InvokeMultipleHardcoded;
- }
- else
- {
- InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), null, unrollFactor);
- }
- }
-
- // must be kept in sync with VoidDeclarationsProvider.IdleImplementation
- private void Overhead() { }
-
- // must be kept in sync with TaskDeclarationsProvider.TargetMethodDelegate
- private void ExecuteBlocking() => startTaskCallback.Invoke().GetAwaiter().GetResult();
-
- private void InvokeMultipleHardcoded(long repeatCount)
- {
- for (long i = 0; i < repeatCount; i++)
- unrolledCallback();
- }
- }
-
- internal class BenchmarkActionTask : BenchmarkActionBase
- {
- private readonly Func> startTaskCallback;
- private readonly Func callback;
- private readonly Func unrolledCallback;
- private T result;
-
- public BenchmarkActionTask(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
- {
- bool isOverhead = method == null;
- if (!isOverhead)
- {
- startTaskCallback = CreateWorkload>>(instance, method);
- callback = ExecuteBlocking;
- }
- else
- {
- callback = Overhead;
- }
-
- InvokeSingle = InvokeSingleHardcoded;
-
- if (UseFallbackCode(codegenMode, unrollFactor))
- {
- unrolledCallback = Unroll(callback, unrollFactor);
- InvokeMultiple = InvokeMultipleHardcoded;
- }
- else
- {
- InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), nameof(result), unrollFactor);
- }
- }
-
- private T Overhead() => default;
-
- // must be kept in sync with GenericTaskDeclarationsProvider.TargetMethodDelegate
- private T ExecuteBlocking() => startTaskCallback().GetAwaiter().GetResult();
-
- private void InvokeSingleHardcoded() => result = callback();
-
- private void InvokeMultipleHardcoded(long repeatCount)
- {
- for (long i = 0; i < repeatCount; i++)
- result = unrolledCallback();
- }
-
- public override object LastRunResult => result;
- }
-
- internal class BenchmarkActionValueTask : BenchmarkActionBase
- {
- private readonly Func> startTaskCallback;
- private readonly Func callback;
- private readonly Func unrolledCallback;
- private T result;
-
- public BenchmarkActionValueTask(object instance, MethodInfo method, BenchmarkActionCodegen codegenMode, int unrollFactor)
- {
- bool isOverhead = method == null;
- if (!isOverhead)
- {
- startTaskCallback = CreateWorkload>>(instance, method);
- callback = ExecuteBlocking;
- }
- else
- {
- callback = Overhead;
- }
-
- InvokeSingle = InvokeSingleHardcoded;
-
- if (UseFallbackCode(codegenMode, unrollFactor))
- {
- unrolledCallback = Unroll(callback, unrollFactor);
- InvokeMultiple = InvokeMultipleHardcoded;
- }
- else
- {
- InvokeMultiple = EmitInvokeMultiple(this, nameof(callback), nameof(result), unrollFactor);
- }
- }
-
- private T Overhead() => default;
-
- // must be kept in sync with GenericTaskDeclarationsProvider.TargetMethodDelegate
- private T ExecuteBlocking() => startTaskCallback().GetAwaiter().GetResult();
-
- private void InvokeSingleHardcoded() => result = callback();
-
- private void InvokeMultipleHardcoded(long repeatCount)
- {
- for (long i = 0; i < repeatCount; i++)
- result = unrolledCallback();
- }
-
- public override object LastRunResult => result;
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/ConsumableTypeInfo.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/ConsumableTypeInfo.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/ConsumableTypeInfo.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/ConsumableTypeInfo.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ByRefConsumeEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ByRefConsumeEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ByRefConsumeEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ByRefConsumeEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ConsumableConsumeEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ConsumableConsumeEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ConsumableConsumeEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ConsumableConsumeEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ConsumeEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ConsumeEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/ConsumeEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/ConsumeEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/EmitExtensions.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/EmitExtensions.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/EmitExtensions.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/EmitExtensions.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/NonConsumableConsumeEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/NonConsumableConsumeEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/NonConsumableConsumeEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/NonConsumableConsumeEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/RunnableEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/RunnableEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/VoidConsumeEmitter.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/VoidConsumeEmitter.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Emitters/VoidConsumeEmitter.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/VoidConsumeEmitter.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableConstants.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableConstants.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableConstants.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableConstants.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableProgram.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableProgram.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableProgram.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableProgram.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableReflectionHelpers.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReflectionHelpers.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableReflectionHelpers.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReflectionHelpers.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableReuse.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReuse.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/Runnable/RunnableReuse.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable/RunnableReuse.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/RunnableActionKind.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/RunnableActionKind.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit.Implementation/RunnableActionKind.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/RunnableActionKind.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitArtifactsPath.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitArtifactsPath.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitBuilder.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitBuilder.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitBuilder.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitBuilder.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitExecutor.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitExecutor.cs
similarity index 99%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitExecutor.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitExecutor.cs
index 9d2cc3466b..d1aad700e6 100644
--- a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitExecutor.cs
+++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitExecutor.cs
@@ -24,7 +24,7 @@ public class InProcessEmitExecutor : IExecutor
/// Default timeout for in-process benchmarks.
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(5);
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
/// Timeout for the run.
/// true if the output should be logged.
public InProcessEmitExecutor(TimeSpan timeout, bool logOutput)
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitGenerator.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitToolchain.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitToolchain.cs
similarity index 93%
rename from src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitToolchain.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitToolchain.cs
index 8ca8f77897..4e63d417a2 100644
--- a/src/BenchmarkDotNet/Toolchains/InProcess.Emit/InProcessEmitToolchain.cs
+++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitToolchain.cs
@@ -12,13 +12,13 @@ public class InProcessEmitToolchain : Toolchain
/// The toolchain instance without output logging.
public static readonly IToolchain DontLogOutput = new InProcessEmitToolchain(false);
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
/// true if the output should be logged.
public InProcessEmitToolchain(bool logOutput) :
this(TimeSpan.Zero, logOutput)
{ }
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
/// Timeout for the run.
/// true if the output should be logged.
public InProcessEmitToolchain(TimeSpan timeout, bool logOutput) :
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessBuilder.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessBuilder.cs
deleted file mode 100644
index d487b43da6..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessBuilder.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Running;
-using BenchmarkDotNet.Toolchains.Results;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public class InProcessBuilder : IBuilder
- {
- /// always returns success
- public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger)
- => BuildResult.Success(generateResult);
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessExecutor.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessExecutor.cs
deleted file mode 100644
index ebb4bf9281..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessExecutor.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using BenchmarkDotNet.Engines;
-using BenchmarkDotNet.Environments;
-using BenchmarkDotNet.Extensions;
-using BenchmarkDotNet.Jobs;
-using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Toolchains.Parameters;
-using BenchmarkDotNet.Toolchains.Results;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- ///
- /// Implementation of for in-process benchmarks.
- ///
- [SuppressMessage("ReSharper", "ArrangeBraces_using")]
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public class InProcessExecutor : IExecutor
- {
- private static readonly TimeSpan UnderDebuggerTimeout = TimeSpan.FromDays(1);
-
- /// Default timeout for in-process benchmarks.
- public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(5);
-
- /// Initializes a new instance of the class.
- /// Timeout for the run.
- /// Describes how benchmark action code is generated.
- /// true if the output should be logged.
- public InProcessExecutor(TimeSpan timeout, BenchmarkActionCodegen codegenMode, bool logOutput)
- {
- if (timeout == TimeSpan.Zero)
- timeout = DefaultTimeout;
-
- ExecutionTimeout = timeout;
- CodegenMode = codegenMode;
- LogOutput = logOutput;
- }
-
- /// Timeout for the run.
- /// The timeout for the run.
- public TimeSpan ExecutionTimeout { get; }
-
- /// Describes how benchmark action code is generated.
- /// Benchmark action code generation mode.
- public BenchmarkActionCodegen CodegenMode { get; }
-
- /// Gets a value indicating whether the output should be logged.
- /// true if the output should be logged; otherwise, false.
- public bool LogOutput { get; }
-
- /// Executes the specified benchmark.
- public ExecuteResult Execute(ExecuteParameters executeParameters)
- {
- // TODO: preallocate buffer for output (no direct logging)?
- var hostLogger = LogOutput ? executeParameters.Logger : NullLogger.Instance;
- var host = new InProcessHost(executeParameters.BenchmarkCase, hostLogger, executeParameters.Diagnoser);
-
- int exitCode = -1;
- var runThread = new Thread(() => exitCode = ExecuteCore(host, executeParameters));
-
- if (executeParameters.BenchmarkCase.Descriptor.WorkloadMethod.GetCustomAttributes(false).Any() &&
- Portability.RuntimeInformation.IsWindows())
- {
- runThread.SetApartmentState(ApartmentState.STA);
- }
-
- runThread.IsBackground = true;
-
- var timeout = HostEnvironmentInfo.GetCurrent().HasAttachedDebugger ? UnderDebuggerTimeout : ExecutionTimeout;
-
- runThread.Start();
-
- if (!runThread.Join((int)timeout.TotalMilliseconds))
- throw new InvalidOperationException(
- $"Benchmark {executeParameters.BenchmarkCase.DisplayInfo} takes too long to run. " +
- "Prefer to use out-of-process toolchains for long-running benchmarks.");
-
- return ExecuteResult.FromRunResults(host.RunResults, exitCode);
- }
-
- private int ExecuteCore(IHost host, ExecuteParameters parameters)
- {
- int exitCode = -1;
- var process = Process.GetCurrentProcess();
- var oldPriority = process.PriorityClass;
- var oldAffinity = process.TryGetAffinity();
- var thread = Thread.CurrentThread;
- var oldThreadPriority = thread.Priority;
-
- var affinity = parameters.BenchmarkCase.Job.ResolveValueAsNullable(EnvironmentMode.AffinityCharacteristic);
- try
- {
- process.TrySetPriority(ProcessPriorityClass.High, parameters.Logger);
- thread.TrySetPriority(ThreadPriority.Highest, parameters.Logger);
-
- if (affinity != null)
- {
- process.TrySetAffinity(affinity.Value, parameters.Logger);
- }
-
- exitCode = InProcessRunner.Run(host, parameters.BenchmarkCase, CodegenMode);
- }
- catch (Exception ex)
- {
- parameters.Logger.WriteLineError($"// ! {GetType().Name}, exception: {ex}");
- }
- finally
- {
- process.TrySetPriority(oldPriority, parameters.Logger);
- thread.TrySetPriority(oldThreadPriority, parameters.Logger);
-
- if (affinity != null && oldAffinity != null)
- {
- process.TrySetAffinity(oldAffinity.Value, parameters.Logger);
- }
- }
-
- return exitCode;
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessGenerator.cs
deleted file mode 100644
index ca9803df55..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessGenerator.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Running;
-using BenchmarkDotNet.Toolchains.Results;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- ///
- /// Implementation of for in-process benchmarks.
- ///
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public class InProcessGenerator : IGenerator
- {
- /// returns a success
- public GenerateResult GenerateProject(BuildPartition buildPartition, ILogger logger, string rootArtifactsFolderPath)
- => GenerateResult.Success(null, Array.Empty());
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessRunner.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessRunner.cs
deleted file mode 100644
index aedd8f6788..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessRunner.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-using System;
-using System.Reflection;
-
-using BenchmarkDotNet.Engines;
-using BenchmarkDotNet.Environments;
-using BenchmarkDotNet.Exporters;
-using BenchmarkDotNet.Jobs;
-using BenchmarkDotNet.Running;
-
-using JetBrains.Annotations;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- internal class InProcessRunner
- {
- public static int Run(IHost host, BenchmarkCase benchmarkCase, BenchmarkActionCodegen codegenMode)
- {
- // the first thing to do is to let diagnosers hook in before anything happens
- // so all jit-related diagnosers can catch first jit compilation!
- host.BeforeAnythingElse();
-
- try
- {
- // we are not using Runnable here in any direct way in order to avoid strong dependency Main<=>Runnable
- // which could cause the jitting/assembly loading to happen before we do anything
- // we have some jitting diagnosers and we want them to catch all the informations!!
-
- string inProcessRunnableTypeName = $"{typeof(InProcessRunner).FullName}+{nameof(Runnable)}";
- var type = typeof(InProcessRunner).GetTypeInfo().Assembly.GetType(inProcessRunnableTypeName)
- ?? throw new InvalidOperationException($"Bug: type {inProcessRunnableTypeName} not found.");
-
- var methodInfo = type.GetMethod(nameof(Runnable.RunCore), BindingFlags.Public | BindingFlags.Static)
- ?? throw new InvalidOperationException($"Bug: method {nameof(Runnable.RunCore)} in {inProcessRunnableTypeName} not found.");
- methodInfo.Invoke(null, new object[] { host, benchmarkCase, codegenMode });
-
- return 0;
- }
- catch (Exception oom) when (oom is OutOfMemoryException || oom is TargetInvocationException reflection && reflection.InnerException is OutOfMemoryException)
- {
- host.WriteLine();
- host.WriteLine("OutOfMemoryException!");
- host.WriteLine("BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.");
- host.WriteLine("If your benchmark allocates memory and keeps it alive, you are creating a memory leak.");
- host.WriteLine("You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.");
- host.WriteLine();
- host.WriteLine(oom.ToString());
-
- return -1;
- }
- catch (Exception ex)
- {
- host.WriteLine();
- host.WriteLine(ex.ToString());
- return -1;
- }
- finally
- {
- host.AfterAll();
- }
- }
-
- /// Fills the properties of the instance of the object used to run the benchmark.
- /// The instance.
- /// The benchmark.
- internal static void FillMembers(object instance, BenchmarkCase benchmarkCase)
- {
- foreach (var parameter in benchmarkCase.Parameters.Items)
- {
- var flags = BindingFlags.Public;
- flags |= parameter.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
-
- var targetType = benchmarkCase.Descriptor.Type;
- var paramProperty = targetType.GetProperty(parameter.Name, flags);
-
- if (paramProperty == null)
- {
- var paramField = targetType.GetField(parameter.Name, flags);
- if (paramField == null)
- throw new InvalidOperationException(
- $"Type {targetType.FullName}: no property or field {parameter.Name} found.");
-
- var callInstance = paramField.IsStatic ? null : instance;
- paramField.SetValue(callInstance, parameter.Value);
- }
- else
- {
- var setter = paramProperty.GetSetMethod();
- if (setter == null)
- throw new InvalidOperationException(
- $"Type {targetType.FullName}: no settable property {parameter.Name} found.");
-
- var callInstance = setter.IsStatic ? null : instance;
- setter.Invoke(callInstance, new[] { parameter.Value });
- }
- }
- }
-
- [UsedImplicitly]
- private static class Runnable
- {
- public static void RunCore(IHost host, BenchmarkCase benchmarkCase, BenchmarkActionCodegen codegenMode)
- {
- var target = benchmarkCase.Descriptor;
- var job = benchmarkCase.Job; // TODO: filter job (same as SourceCodePresenter does)?
- int unrollFactor = benchmarkCase.Job.ResolveValue(RunMode.UnrollFactorCharacteristic, EnvironmentResolver.Instance);
-
- // DONTTOUCH: these should be allocated together
- var instance = Activator.CreateInstance(benchmarkCase.Descriptor.Type);
- var workloadAction = BenchmarkActionFactory.CreateWorkload(target, instance, codegenMode, unrollFactor);
- var overheadAction = BenchmarkActionFactory.CreateOverhead(target, instance, codegenMode, unrollFactor);
- var globalSetupAction = BenchmarkActionFactory.CreateGlobalSetup(target, instance);
- var globalCleanupAction = BenchmarkActionFactory.CreateGlobalCleanup(target, instance);
- var iterationSetupAction = BenchmarkActionFactory.CreateIterationSetup(target, instance);
- var iterationCleanupAction = BenchmarkActionFactory.CreateIterationCleanup(target, instance);
- var dummy1 = BenchmarkActionFactory.CreateDummy();
- var dummy2 = BenchmarkActionFactory.CreateDummy();
- var dummy3 = BenchmarkActionFactory.CreateDummy();
-
- FillMembers(instance, benchmarkCase);
-
- host.WriteLine();
- foreach (string infoLine in BenchmarkEnvironmentInfo.GetCurrent().ToFormattedString())
- host.WriteLine("// {0}", infoLine);
- host.WriteLine("// Job: {0}", job.DisplayInfo);
- host.WriteLine();
-
- var engineParameters = new EngineParameters
- {
- Host = host,
- WorkloadActionNoUnroll = invocationCount =>
- {
- for (int i = 0; i < invocationCount; i++)
- workloadAction.InvokeSingle();
- },
- WorkloadActionUnroll = workloadAction.InvokeMultiple,
- Dummy1Action = dummy1.InvokeSingle,
- Dummy2Action = dummy2.InvokeSingle,
- Dummy3Action = dummy3.InvokeSingle,
- OverheadActionNoUnroll = invocationCount =>
- {
- for (int i = 0; i < invocationCount; i++)
- overheadAction.InvokeSingle();
- },
- OverheadActionUnroll = overheadAction.InvokeMultiple,
- GlobalSetupAction = globalSetupAction.InvokeSingle,
- GlobalCleanupAction = globalCleanupAction.InvokeSingle,
- IterationSetupAction = iterationSetupAction.InvokeSingle,
- IterationCleanupAction = iterationCleanupAction.InvokeSingle,
- TargetJob = job,
- OperationsPerInvoke = target.OperationsPerInvoke,
- MeasureExtraStats = benchmarkCase.Config.HasExtraStatsDiagnoser(),
- BenchmarkName = FullNameProvider.GetBenchmarkName(benchmarkCase)
- };
-
- using (var engine = job
- .ResolveValue(InfrastructureMode.EngineFactoryCharacteristic, InfrastructureResolver.Instance)
- .CreateReadyToRun(engineParameters))
- {
- var results = engine.Run();
-
- host.ReportResults(results); // printing costs memory, do this after runs
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessToolchain.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessToolchain.cs
deleted file mode 100644
index 9dd55eed99..0000000000
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessToolchain.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.Collections.Generic;
-using BenchmarkDotNet.Characteristics;
-using BenchmarkDotNet.Running;
-using BenchmarkDotNet.Validators;
-
-namespace BenchmarkDotNet.Toolchains.InProcess
-{
- ///
- /// A toolchain to run the benchmarks in-process.
- ///
- ///
- [Obsolete("Please use BenchmarkDotNet.Toolchains.InProcess.NoEmit.* classes")]
- public sealed class InProcessToolchain : IToolchain
- {
- /// The default toolchain instance.
- public static readonly IToolchain Instance = new InProcessToolchain(true);
-
- /// The toolchain instance without output logging.
- public static readonly IToolchain DontLogOutput = new InProcessToolchain(false);
-
- /// Initializes a new instance of the class.
- /// true if the output should be logged.
- public InProcessToolchain(bool logOutput) : this(
- InProcessExecutor.DefaultTimeout,
- BenchmarkActionCodegen.ReflectionEmit,
- logOutput)
- {
- }
-
- /// Initializes a new instance of the class.
- /// Timeout for the run.
- /// Describes how benchmark action code is generated.
- /// true if the output should be logged.
- public InProcessToolchain(TimeSpan timeout, BenchmarkActionCodegen codegenMode, bool logOutput)
- {
- Generator = new InProcessGenerator();
- Builder = new InProcessBuilder();
- Executor = new InProcessExecutor(timeout, codegenMode, logOutput);
- }
-
- /// Validates the specified benchmark.
- /// The benchmark.
- /// The resolver.
- /// Collection of validation errors, when not empty means that toolchain does not support provided benchmark.
- public IEnumerable Validate(BenchmarkCase benchmarkCase, IResolver resolver) =>
- InProcessValidator.Validate(benchmarkCase);
-
- /// Name of the toolchain.
- /// The name of the toolchain.
- public string Name => nameof(InProcessToolchain);
-
- /// The generator.
- /// The generator.
- public IGenerator Generator { get; }
-
- /// The builder.
- /// The builder.
- public IBuilder Builder { get; }
-
- /// The executor.
- /// The executor.
- public IExecutor Executor { get; }
-
- public bool IsInProcess => true;
-
- /// Returns a that represents this instance.
- /// A that represents this instance.
- public override string ToString() => GetType().Name;
- }
-}
\ No newline at end of file
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessValidator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessValidator.cs
index 77cdcfe135..2e4f349b7f 100644
--- a/src/BenchmarkDotNet/Toolchains/InProcess/InProcessValidator.cs
+++ b/src/BenchmarkDotNet/Toolchains/InProcess/InProcessValidator.cs
@@ -14,7 +14,7 @@
namespace BenchmarkDotNet.Toolchains.InProcess
{
///
- /// Validator to be used together with
+ /// Validator to be used together with or
/// to proof that the config matches the environment.
///
///
@@ -81,9 +81,6 @@ private static string ValidatePlatform(Job job, Characteristic characteristic)
private static string ValidateToolchain(Job job, Characteristic characteristic) =>
job.Infrastructure.Toolchain is InProcessEmitToolchain
|| job.Infrastructure.Toolchain is InProcessNoEmitToolchain
-#pragma warning disable 618
- || job.Infrastructure.Toolchain is InProcessToolchain
-#pragma warning restore 618
? null
: $"should be instance of {nameof(InProcessEmitToolchain)} or {nameof(InProcessNoEmitToolchain)}.";
@@ -156,8 +153,8 @@ public IEnumerable Validate(ValidationParameters validationPara
$"Target {target} has {nameof(target.AdditionalLogic)} filled. AdditionalLogic is not supported by in-process toolchain.");
}
- foreach (var benchmarkWithArguments in validationParameters.Benchmarks.Where(benchmark => benchmark.HasArguments))
- yield return new ValidationError(true, "Arguments are not supported by the InProcessToolchain yet, see #687 for more details", benchmarkWithArguments);
+ foreach (var benchmarkWithArguments in validationParameters.Benchmarks.Where(benchmark => benchmark.HasArguments && benchmark.GetToolchain() is InProcessNoEmitToolchain))
+ yield return new ValidationError(true, "Arguments are not supported by the InProcessNoEmitToolchain, see #687 for more details", benchmarkWithArguments);
foreach (var validationError in validationParameters.Config.GetJobs().SelectMany(job => ValidateJob(job, TreatsWarningsAsErrors)))
yield return validationError;
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkAction.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkAction.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkAction.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkAction.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Base.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Base.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Base.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Base.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Dummy.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Dummy.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Dummy.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Dummy.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Implementations.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Implementations.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/BenchmarkActionFactory_Implementations.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory_Implementations.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitBuilder.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitBuilder.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitBuilder.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitBuilder.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitExecutor.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitExecutor.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitExecutor.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitExecutor.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitGenerator.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitGenerator.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitGenerator.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitRunner.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitRunner.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitRunner.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitRunner.cs
diff --git a/src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitToolchain.cs b/src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitToolchain.cs
similarity index 100%
rename from src/BenchmarkDotNet/Toolchains/InProcess.NoEmit/InProcessNoEmitToolchain.cs
rename to src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/InProcessNoEmitToolchain.cs
diff --git a/tests/BenchmarkDotNet.IntegrationTests/InProcessTest.cs b/tests/BenchmarkDotNet.IntegrationTests/InProcessTest.cs
index a5de2462f6..a06870ad5e 100644
--- a/tests/BenchmarkDotNet.IntegrationTests/InProcessTest.cs
+++ b/tests/BenchmarkDotNet.IntegrationTests/InProcessTest.cs
@@ -7,14 +7,13 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
-using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Tests.Loggers;
-using BenchmarkDotNet.Toolchains.InProcess;
+using BenchmarkDotNet.Toolchains.InProcess.NoEmit;
using JetBrains.Annotations;
using Xunit;
using Xunit.Abstractions;
@@ -66,7 +65,7 @@ public void BenchmarkDifferentPlatformReturnsValidationError()
: Platform.X64;
var otherPlatformConfig = new ManualConfig()
- .With(Job.Dry.With(InProcessToolchain.Instance).With(otherPlatform))
+ .With(Job.Dry.With(InProcessNoEmitToolchain.Instance).With(otherPlatform))
.With(new OutputLogger(Output))
.With(DefaultColumnProviders.Instance);
@@ -83,15 +82,11 @@ private void TestInvoke(Expression> methodCall, int un
var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod, targetMethod, targetMethod);
// Run mode
- var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor);
- TestInvoke(action, unrollFactor, false, null);
- action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor);
+ var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), unrollFactor);
TestInvoke(action, unrollFactor, false, null);
// Idle mode
- action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor);
- TestInvoke(action, unrollFactor, true, null);
- action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor);
+ action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), unrollFactor);
TestInvoke(action, unrollFactor, true, null);
// GlobalSetup/GlobalCleanup
@@ -121,9 +116,7 @@ private void TestInvoke(Expression> methodCall, in
var descriptor = new Descriptor(typeof(BenchmarkAllCases), targetMethod);
// Run mode
- var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor);
- TestInvoke(action, unrollFactor, false, expectedResult);
- action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor);
+ var action = BenchmarkActionFactory.CreateWorkload(descriptor, new BenchmarkAllCases(), unrollFactor);
TestInvoke(action, unrollFactor, false, expectedResult);
// Idle mode
@@ -140,9 +133,7 @@ private void TestInvoke(Expression> methodCall, in
else
idleExpected = GetDefault(expectedResult.GetType());
- action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.ReflectionEmit, unrollFactor);
- TestInvoke(action, unrollFactor, true, idleExpected);
- action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), BenchmarkActionCodegen.DelegateCombine, unrollFactor);
+ action = BenchmarkActionFactory.CreateOverhead(descriptor, new BenchmarkAllCases(), unrollFactor);
TestInvoke(action, unrollFactor, true, idleExpected);
}
@@ -189,48 +180,19 @@ private void TestInvoke(BenchmarkAction benchmarkAction, int unrollFactor, bool
}
}
- private IConfig CreateInProcessConfig(BenchmarkActionCodegen codegenMode, OutputLogger logger = null, IDiagnoser diagnoser = null)
+ private IConfig CreateInProcessConfig(OutputLogger logger = null)
{
return new ManualConfig()
- .AddJob(Job.Dry.WithToolchain(new InProcessToolchain(TimeSpan.Zero, codegenMode, true)).WithInvocationCount(UnrollFactor).WithUnrollFactor(UnrollFactor))
+ .AddJob(Job.Dry.WithToolchain(new InProcessNoEmitToolchain(TimeSpan.Zero, true)).WithInvocationCount(UnrollFactor).WithUnrollFactor(UnrollFactor))
.AddLogger(logger ?? (Output != null ? new OutputLogger(Output) : ConsoleLogger.Default))
.AddColumnProvider(DefaultColumnProviders.Instance);
}
[Fact]
- public void InProcessBenchmarkAllCasesReflectionEmitSupported()
- {
- var logger = new OutputLogger(Output);
- var config = CreateInProcessConfig(BenchmarkActionCodegen.ReflectionEmit, logger);
-
- try
- {
- BenchmarkAllCases.Counter = 0;
-
- var summary = CanExecute(config);
-
- var testLog = logger.GetLog();
- Assert.Contains("// Benchmark: BenchmarkAllCases.InvokeOnceVoid:", testLog);
- Assert.DoesNotContain("No benchmarks found", logger.GetLog());
-
- // Operations + GlobalSetup + GlobalCleanup
- long expectedCount = summary.Reports
- .SelectMany(r => r.AllMeasurements)
- .Where(m => m.IterationStage != IterationStage.Result)
- .Sum(m => m.Operations + 2);
- Assert.Equal(expectedCount, BenchmarkAllCases.Counter);
- }
- finally
- {
- BenchmarkAllCases.Counter = 0;
- }
- }
-
- [Fact]
- public void InProcessBenchmarkAllCasesDelegateCombineSupported()
+ public void InProcessBenchmarkAllCasesSupported()
{
var logger = new OutputLogger(Output);
- var config = CreateInProcessConfig(BenchmarkActionCodegen.DelegateCombine, logger);
+ var config = CreateInProcessConfig(logger);
try
{