diff --git a/src/BenchmarkDotNet/Engines/Engine.cs b/src/BenchmarkDotNet/Engines/Engine.cs
index cdf8adcebc..271c3c44e1 100644
--- a/src/BenchmarkDotNet/Engines/Engine.cs
+++ b/src/BenchmarkDotNet/Engines/Engine.cs
@@ -267,7 +267,7 @@ private static void ForceGcCollect()
private static void EnableMonitoring()
{
- if (RuntimeInformation.IsMono) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes-in-mono
+ if (RuntimeInformation.IsOldMono) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes-in-mono
return;
if (RuntimeInformation.IsFullFramework)
diff --git a/src/BenchmarkDotNet/Engines/GcStats.cs b/src/BenchmarkDotNet/Engines/GcStats.cs
index afcf73f515..573e2c4828 100644
--- a/src/BenchmarkDotNet/Engines/GcStats.cs
+++ b/src/BenchmarkDotNet/Engines/GcStats.cs
@@ -132,7 +132,11 @@ public static GcStats FromForced(int forcedFullGarbageCollections)
private static long GetAllocatedBytes()
{
- if (RuntimeInformation.IsMono) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes-
+ if (RuntimeInformation.IsOldMono) // Monitoring is not available in Mono, see http://stackoverflow.com/questions/40234948/how-to-get-the-number-of-allocated-bytes-
+ return 0;
+
+ // we have no tests for WASM and don't want to risk introducing a new bug (https://github.com/dotnet/BenchmarkDotNet/issues/2226)
+ if (RuntimeInformation.IsWasm)
return 0;
// "This instance Int64 property returns the number of bytes that have been allocated by a specific
diff --git a/src/BenchmarkDotNet/Portability/RuntimeInformation.cs b/src/BenchmarkDotNet/Portability/RuntimeInformation.cs
index 009e34049c..de8cdc9c1b 100644
--- a/src/BenchmarkDotNet/Portability/RuntimeInformation.cs
+++ b/src/BenchmarkDotNet/Portability/RuntimeInformation.cs
@@ -25,8 +25,15 @@ internal static class RuntimeInformation
internal const string ReleaseConfigurationName = "RELEASE";
internal const string Unknown = "?";
+ ///
+ /// returns true for both the old (implementation of .NET Framework) and new Mono (.NET 6+ flavour)
+ ///
public static bool IsMono { get; } = Type.GetType("Mono.RuntimeStructs") != null; // it allocates a lot of memory, we need to check it once in order to keep Engine non-allocating!
+ public static bool IsOldMono { get; } = Type.GetType("Mono.Runtime") != null;
+
+ public static bool IsNewMono { get; } = IsMono && !IsOldMono;
+
public static bool IsFullFramework =>
#if NET6_0_OR_GREATER
false;
@@ -200,7 +207,24 @@ internal static CpuInfo GetCpuInfo()
internal static string GetRuntimeVersion()
{
- if (IsMono && !IsWasm)
+ if (IsWasm)
+ {
+ // code copied from https://github.com/dotnet/runtime/blob/2c573b59aaaf3fd17e2ecab95ad3769f195d2dbc/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs#L20-L30
+ string versionString = typeof(object).Assembly.GetCustomAttribute()?.InformationalVersion;
+
+ // Strip the git hash if there is one
+ if (versionString != null)
+ {
+ int plusIndex = versionString.IndexOf('+');
+ if (plusIndex != -1)
+ {
+ versionString = versionString.Substring(0, plusIndex);
+ }
+ }
+
+ return $".NET Core (Mono) {versionString}";
+ }
+ else if (IsMono)
{
var monoRuntimeType = Type.GetType("Mono.Runtime");
var monoDisplayName = monoRuntimeType?.GetMethod("GetDisplayName", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
@@ -221,7 +245,7 @@ internal static string GetRuntimeVersion()
return "Mono " + version;
}
- else
+ else if (IsNewMono)
{
return $"{GetNetCoreVersion()} using MonoVM";
}
@@ -230,23 +254,6 @@ internal static string GetRuntimeVersion()
{
return FrameworkVersionHelper.GetFrameworkDescription();
}
- else if (IsWasm)
- {
- // code copied from https://github.com/dotnet/runtime/blob/2c573b59aaaf3fd17e2ecab95ad3769f195d2dbc/src/libraries/System.Runtime.InteropServices.RuntimeInformation/src/System/Runtime/InteropServices/RuntimeInformation/RuntimeInformation.cs#L20-L30
- string versionString = typeof(object).Assembly.GetCustomAttribute()?.InformationalVersion;
-
- // Strip the git hash if there is one
- if (versionString != null)
- {
- int plusIndex = versionString.IndexOf('+');
- if (plusIndex != -1)
- {
- versionString = versionString.Substring(0, plusIndex);
- }
- }
-
- return $".NET Core (Mono) {versionString}";
- }
else if (IsNetCore)
{
return GetNetCoreVersion();
diff --git a/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs b/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs
index 2ffe1b3387..da5dbf57e5 100755
--- a/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs
+++ b/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs
@@ -23,6 +23,7 @@
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using Xunit;
using Xunit.Abstractions;
+using BenchmarkDotNet.Toolchains.Mono;
namespace BenchmarkDotNet.IntegrationTests
{
@@ -34,7 +35,7 @@ public class MemoryDiagnoserTests
public static IEnumerable