1010using BenchmarkDotNet . Configs ;
1111using BenchmarkDotNet . Detectors ;
1212using BenchmarkDotNet . Diagnosers ;
13+ using BenchmarkDotNet . Environments ;
1314using BenchmarkDotNet . Extensions ;
1415using BenchmarkDotNet . IntegrationTests . Xunit ;
1516using BenchmarkDotNet . Jobs ;
1920using BenchmarkDotNet . Tests . Loggers ;
2021using BenchmarkDotNet . Tests . XUnit ;
2122using BenchmarkDotNet . Toolchains ;
22- using BenchmarkDotNet . Toolchains . NativeAot ;
23+ using BenchmarkDotNet . Toolchains . DotNetCli ;
2324using BenchmarkDotNet . Toolchains . InProcess . Emit ;
25+ using BenchmarkDotNet . Toolchains . Mono ;
26+ using BenchmarkDotNet . Toolchains . MonoAotLLVM ;
27+ using BenchmarkDotNet . Toolchains . MonoWasm ;
28+ using BenchmarkDotNet . Toolchains . NativeAot ;
2429using Xunit ;
2530using Xunit . Abstractions ;
26- using BenchmarkDotNet . Toolchains . Mono ;
2731
2832namespace BenchmarkDotNet . IntegrationTests
2933{
@@ -86,6 +90,31 @@ public void MemoryDiagnoserSupportsModernMono()
8690 MemoryDiagnoserIsAccurate ( MonoToolchain . Mono80 ) ;
8791 }
8892
93+ [ TheoryEnvSpecific ( "JSVU does not support ARM on Windows or Linux" , EnvRequirement . NonWindowsArm , EnvRequirement . NonLinuxArm ) ]
94+ [ InlineData ( MonoAotCompilerMode . mini ) ]
95+ // BUG: https://github.com/dotnet/BenchmarkDotNet/issues/3036
96+ [ InlineData ( MonoAotCompilerMode . wasm , Skip = "AOT is broken" ) ]
97+ public void MemoryDiagnoserSupportsMonoWasm ( MonoAotCompilerMode aotCompilerMode )
98+ {
99+ var ptrSize = sizeof ( Int32 ) ; // We can't rely on IntPtr.Size, since we run on a different platform. Wasm is currently 32bit.
100+ var objectAllocationOverhead = ptrSize * 2 ; // pointer to method table + object header word
101+ var arraySizeOverhead = ptrSize * 2 ; // bounds + max_length
102+ var intTaskSize = 40 ; // We can't use CalculateRequiredSpace for AllocateTask since it calculates the size with IntPtr.Size.
103+
104+ var netCoreAppSettings = new NetCoreAppSettings ( "net8.0" , runtimeFrameworkVersion : null ! , "Wasm" , aotCompilerMode : aotCompilerMode ) ;
105+
106+ var runtime = new WasmRuntime (
107+ netCoreAppSettings . TargetFrameworkMoniker , RuntimeMoniker . WasmNet80 ,
108+ "Wasm" , aotCompilerMode == MonoAotCompilerMode . wasm , "v8" ) ;
109+
110+ AssertAllocations ( WasmToolchain . From ( netCoreAppSettings ) , typeof ( AccurateAllocations ) , new Dictionary < string , long >
111+ {
112+ { nameof ( AccurateAllocations . EightBytesArray ) , 8 + objectAllocationOverhead + arraySizeOverhead } ,
113+ { nameof ( AccurateAllocations . SixtyFourBytesArray ) , 64 + objectAllocationOverhead + arraySizeOverhead } ,
114+ { nameof ( AccurateAllocations . AllocateTask ) , intTaskSize } ,
115+ } , runtime : runtime ) ;
116+ }
117+
89118 public class AllocatingGlobalSetupAndCleanup
90119 {
91120 private List < int > list = default ! ;
@@ -322,9 +351,10 @@ public void MemoryDiagnoserIsAccurateForMultiThreadedBenchmarks(IToolchain toolc
322351 } ) ;
323352 }
324353
325- private void AssertAllocations ( IToolchain toolchain , Type benchmarkType , Dictionary < string , long > benchmarksAllocationsValidators , bool disableTieredJit = true , int iterationCount = 1 )
354+ private void AssertAllocations ( IToolchain toolchain , Type benchmarkType , Dictionary < string , long > benchmarksAllocationsValidators ,
355+ bool disableTieredJit = true , int iterationCount = 1 , Runtime ? runtime = null )
326356 {
327- var config = CreateConfig ( toolchain , disableTieredJit , iterationCount ) ;
357+ var config = CreateConfig ( toolchain , runtime , disableTieredJit , iterationCount ) ;
328358 var benchmarks = BenchmarkConverter . TypeToBenchmarks ( benchmarkType , config ) ;
329359
330360 var summary = BenchmarkRunner . Run ( benchmarks ) ;
@@ -361,6 +391,7 @@ private void AssertAllocations(IToolchain toolchain, Type benchmarkType, Diction
361391 }
362392
363393 private IConfig CreateConfig ( IToolchain toolchain ,
394+ Runtime ? runtime ,
364395 // Tiered JIT can allocate some memory on a background thread, let's disable it by default to make our tests less flaky (#1542).
365396 // This was mostly fixed in net7.0, but tiered jit thread is not guaranteed to not allocate, so we disable it just in case.
366397 bool disableTieredJit = true ,
@@ -382,6 +413,12 @@ private IConfig CreateConfig(IToolchain toolchain,
382413 . WithEnvironmentVariable ( Engines . Engine . UnitTestBlockFinalizerEnvKey , Engines . Engine . UnitTestBlockFinalizerEnvValue )
383414 . WithToolchain ( toolchain ) ;
384415#pragma warning restore CS0618 // WithEvaluateOverhead is obsolete
416+
417+ if ( runtime is not null )
418+ {
419+ job = job . WithRuntime ( runtime ) ;
420+ }
421+
385422 return ManualConfig . CreateEmpty ( )
386423 . AddJob ( disableTieredJit
387424 ? job . WithEnvironmentVariables (
0 commit comments