1
1
using System ;
2
- using System . Collections . Generic ;
3
- using System . Collections . Immutable ;
4
- using System . Linq ;
5
- using BenchmarkDotNet . Analysers ;
2
+ using System . Reflection ;
6
3
using BenchmarkDotNet . Detectors ;
7
4
using BenchmarkDotNet . Diagnosers ;
8
- using BenchmarkDotNet . Engines ;
9
- using BenchmarkDotNet . Exporters ;
5
+ using BenchmarkDotNet . Helpers ;
10
6
using BenchmarkDotNet . Jobs ;
11
- using BenchmarkDotNet . Loggers ;
12
- using BenchmarkDotNet . Reports ;
13
- using BenchmarkDotNet . Running ;
14
- using BenchmarkDotNet . Validators ;
15
- using RunMode = BenchmarkDotNet . Diagnosers . RunMode ;
7
+ using JetBrains . Profiler . SelfApi ;
16
8
17
- namespace BenchmarkDotNet . Diagnostics . dotMemory
9
+ namespace BenchmarkDotNet . Diagnostics . dotMemory ;
10
+
11
+ public class DotMemoryDiagnoser ( Uri ? nugetUrl = null , string ? downloadTo = null ) : SnapshotProfilerBase
18
12
{
19
- public class DotMemoryDiagnoser ( Uri ? nugetUrl = null , string ? toolsDownloadFolder = null ) : IProfiler
13
+ public override string ShortName => "dotMemory" ;
14
+
15
+ protected override void InitTool ( Progress progress )
20
16
{
21
- private DotMemoryTool ? tool ;
17
+ DotMemory . InitAsync ( progress , nugetUrl , NuGetApi . V3 , downloadTo ) . Wait ( ) ;
18
+ }
22
19
23
- public IEnumerable < string > Ids => new [ ] { "DotMemory" } ;
24
- public string ShortName => "dotMemory" ;
20
+ protected override void AttachToCurrentProcess ( string snapshotFile )
21
+ {
22
+ DotMemory . Attach ( new DotMemory . Config ( ) . SaveToFile ( snapshotFile ) ) ;
23
+ }
25
24
26
- public RunMode GetRunMode ( BenchmarkCase benchmarkCase )
27
- {
28
- return IsSupported ( benchmarkCase . Job . Environment . GetRuntime ( ) . RuntimeMoniker ) ? RunMode . ExtraRun : RunMode . None ;
29
- }
25
+ protected override void AttachToProcessByPid ( int pid , string snapshotFile )
26
+ {
27
+ DotMemory . Attach ( new DotMemory . Config ( ) . ProfileExternalProcess ( pid ) . SaveToFile ( snapshotFile ) ) ;
28
+ }
30
29
31
- private readonly List < string > snapshotFilePaths = new ( ) ;
30
+ protected override void TakeSnapshot ( )
31
+ {
32
+ DotMemory . GetSnapshot ( ) ;
33
+ }
32
34
33
- public void Handle ( HostSignal signal , DiagnoserActionParameters parameters )
34
- {
35
- var logger = parameters . Config . GetCompositeLogger ( ) ;
36
- var job = parameters . BenchmarkCase . Job ;
35
+ protected override void Detach ( )
36
+ {
37
+ DotMemory . Detach ( ) ;
38
+ }
37
39
38
- var runtimeMoniker = job . Environment . GetRuntime ( ) . RuntimeMoniker ;
39
- if ( ! IsSupported ( runtimeMoniker ) )
40
- {
41
- logger . WriteLineError ( $ "Runtime '{ runtimeMoniker } ' is not supported by dotMemory") ;
42
- return ;
43
- }
40
+ protected override string CreateSnapshotFilePath ( DiagnoserActionParameters parameters )
41
+ {
42
+ return ArtifactFileNameHelper . GetFilePath ( parameters , "snapshots" , DateTime . Now , "dmw" , ".0000" . Length ) ;
43
+ }
44
44
45
- switch ( signal )
46
- {
47
- case HostSignal . BeforeAnythingElse :
48
- if ( tool is null )
49
- {
50
- tool = new DotMemoryTool ( logger , nugetUrl , downloadTo : toolsDownloadFolder ) ;
51
- tool . Init ( ) ;
52
- }
53
- break ;
54
- case HostSignal . BeforeActualRun :
55
- if ( tool is null )
56
- throw new InvalidOperationException ( "DotMemory tool is not initialized" ) ;
57
- snapshotFilePaths . Add ( tool . Start ( parameters ) ) ;
58
- break ;
59
- case HostSignal . AfterActualRun :
60
- if ( tool is null )
61
- throw new InvalidOperationException ( "DotMemory tool is not initialized" ) ;
62
- tool . Stop ( ) ;
63
- tool = null ;
64
- break ;
65
- }
66
- }
45
+ protected override string GetRunnerPath ( )
46
+ {
47
+ var consoleRunnerPackageField = typeof ( DotMemory ) . GetField ( "ConsoleRunnerPackage" , BindingFlags . NonPublic | BindingFlags . Static ) ;
48
+ if ( consoleRunnerPackageField == null )
49
+ throw new InvalidOperationException ( "Field 'ConsoleRunnerPackage' not found." ) ;
67
50
68
- public IEnumerable < IExporter > Exporters => Enumerable . Empty < IExporter > ( ) ;
69
- public IEnumerable < IAnalyser > Analysers => Enumerable . Empty < IAnalyser > ( ) ;
51
+ object ? consoleRunnerPackage = consoleRunnerPackageField . GetValue ( null ) ;
52
+ if ( consoleRunnerPackage == null )
53
+ throw new InvalidOperationException ( "Unable to get value of 'ConsoleRunnerPackage'." ) ;
70
54
71
- public IEnumerable < ValidationError > Validate ( ValidationParameters validationParameters )
72
- {
73
- var runtimeMonikers = validationParameters . Benchmarks . Select ( b => b . Job . Environment . GetRuntime ( ) . RuntimeMoniker ) . Distinct ( ) ;
74
- foreach ( var runtimeMoniker in runtimeMonikers )
75
- {
76
- if ( ! IsSupported ( runtimeMoniker ) )
77
- yield return new ValidationError ( true , $ "Runtime '{ runtimeMoniker } ' is not supported by dotMemory") ;
78
- }
79
- }
55
+ var consoleRunnerPackageType = consoleRunnerPackage . GetType ( ) ;
56
+ var getRunnerPathMethod = consoleRunnerPackageType . GetMethod ( "GetRunnerPath" ) ;
57
+ if ( getRunnerPathMethod == null )
58
+ throw new InvalidOperationException ( "Method 'GetRunnerPath' not found." ) ;
80
59
81
- internal static bool IsSupported ( RuntimeMoniker runtimeMoniker )
82
- {
83
- switch ( runtimeMoniker )
84
- {
85
- case RuntimeMoniker . HostProcess :
86
- case RuntimeMoniker . Net461 :
87
- case RuntimeMoniker . Net462 :
88
- case RuntimeMoniker . Net47 :
89
- case RuntimeMoniker . Net471 :
90
- case RuntimeMoniker . Net472 :
91
- case RuntimeMoniker . Net48 :
92
- case RuntimeMoniker . Net481 :
93
- case RuntimeMoniker . Net50 :
94
- case RuntimeMoniker . Net60 :
95
- case RuntimeMoniker . Net70 :
96
- case RuntimeMoniker . Net80 :
97
- case RuntimeMoniker . Net90 :
98
- return true ;
99
- case RuntimeMoniker . NotRecognized :
100
- case RuntimeMoniker . Mono :
101
- case RuntimeMoniker . NativeAot60 :
102
- case RuntimeMoniker . NativeAot70 :
103
- case RuntimeMoniker . NativeAot80 :
104
- case RuntimeMoniker . NativeAot90 :
105
- case RuntimeMoniker . Wasm :
106
- case RuntimeMoniker . WasmNet50 :
107
- case RuntimeMoniker . WasmNet60 :
108
- case RuntimeMoniker . WasmNet70 :
109
- case RuntimeMoniker . WasmNet80 :
110
- case RuntimeMoniker . WasmNet90 :
111
- case RuntimeMoniker . MonoAOTLLVM :
112
- case RuntimeMoniker . MonoAOTLLVMNet60 :
113
- case RuntimeMoniker . MonoAOTLLVMNet70 :
114
- case RuntimeMoniker . MonoAOTLLVMNet80 :
115
- case RuntimeMoniker . MonoAOTLLVMNet90 :
116
- case RuntimeMoniker . Mono60 :
117
- case RuntimeMoniker . Mono70 :
118
- case RuntimeMoniker . Mono80 :
119
- case RuntimeMoniker . Mono90 :
120
- #pragma warning disable CS0618 // Type or member is obsolete
121
- case RuntimeMoniker . NetCoreApp50 :
122
- #pragma warning restore CS0618 // Type or member is obsolete
123
- return false ;
124
- case RuntimeMoniker . NetCoreApp20 :
125
- case RuntimeMoniker . NetCoreApp21 :
126
- case RuntimeMoniker . NetCoreApp22 :
127
- return OsDetector . IsWindows ( ) ;
128
- case RuntimeMoniker . NetCoreApp30 :
129
- case RuntimeMoniker . NetCoreApp31 :
130
- return OsDetector . IsWindows ( ) || OsDetector . IsLinux ( ) ;
131
- default :
132
- throw new ArgumentOutOfRangeException ( nameof ( runtimeMoniker ) , runtimeMoniker , $ "Runtime moniker { runtimeMoniker } is not supported") ;
133
- }
134
- }
60
+ string ? runnerPath = getRunnerPathMethod . Invoke ( consoleRunnerPackage , null ) as string ;
61
+ if ( runnerPath == null )
62
+ throw new InvalidOperationException ( "Unable to invoke 'GetRunnerPath'." ) ;
135
63
136
- public IEnumerable < Metric > ProcessResults ( DiagnoserResults results ) => ImmutableArray < Metric > . Empty ;
64
+ return runnerPath ;
65
+ }
137
66
138
- public void DisplayResults ( ILogger logger )
67
+ internal override bool IsSupported ( RuntimeMoniker runtimeMoniker )
68
+ {
69
+ switch ( runtimeMoniker )
139
70
{
140
- if ( snapshotFilePaths . Any ( ) )
141
- {
142
- logger . WriteLineInfo ( "The following dotMemory snapshots were generated:" ) ;
143
- foreach ( string snapshotFilePath in snapshotFilePaths )
144
- logger . WriteLineInfo ( $ "* { snapshotFilePath } ") ;
145
- }
71
+ case RuntimeMoniker . HostProcess :
72
+ case RuntimeMoniker . Net461 :
73
+ case RuntimeMoniker . Net462 :
74
+ case RuntimeMoniker . Net47 :
75
+ case RuntimeMoniker . Net471 :
76
+ case RuntimeMoniker . Net472 :
77
+ case RuntimeMoniker . Net48 :
78
+ case RuntimeMoniker . Net481 :
79
+ case RuntimeMoniker . Net50 :
80
+ case RuntimeMoniker . Net60 :
81
+ case RuntimeMoniker . Net70 :
82
+ case RuntimeMoniker . Net80 :
83
+ case RuntimeMoniker . Net90 :
84
+ return true ;
85
+ case RuntimeMoniker . NotRecognized :
86
+ case RuntimeMoniker . Mono :
87
+ case RuntimeMoniker . NativeAot60 :
88
+ case RuntimeMoniker . NativeAot70 :
89
+ case RuntimeMoniker . NativeAot80 :
90
+ case RuntimeMoniker . NativeAot90 :
91
+ case RuntimeMoniker . Wasm :
92
+ case RuntimeMoniker . WasmNet50 :
93
+ case RuntimeMoniker . WasmNet60 :
94
+ case RuntimeMoniker . WasmNet70 :
95
+ case RuntimeMoniker . WasmNet80 :
96
+ case RuntimeMoniker . WasmNet90 :
97
+ case RuntimeMoniker . MonoAOTLLVM :
98
+ case RuntimeMoniker . MonoAOTLLVMNet60 :
99
+ case RuntimeMoniker . MonoAOTLLVMNet70 :
100
+ case RuntimeMoniker . MonoAOTLLVMNet80 :
101
+ case RuntimeMoniker . MonoAOTLLVMNet90 :
102
+ case RuntimeMoniker . Mono60 :
103
+ case RuntimeMoniker . Mono70 :
104
+ case RuntimeMoniker . Mono80 :
105
+ case RuntimeMoniker . Mono90 :
106
+ #pragma warning disable CS0618 // Type or member is obsolete
107
+ case RuntimeMoniker . NetCoreApp50 :
108
+ #pragma warning restore CS0618 // Type or member is obsolete
109
+ return false ;
110
+ case RuntimeMoniker . NetCoreApp20 :
111
+ case RuntimeMoniker . NetCoreApp21 :
112
+ case RuntimeMoniker . NetCoreApp22 :
113
+ return OsDetector . IsWindows ( ) ;
114
+ case RuntimeMoniker . NetCoreApp30 :
115
+ case RuntimeMoniker . NetCoreApp31 :
116
+ return OsDetector . IsWindows ( ) || OsDetector . IsLinux ( ) ;
117
+ default :
118
+ throw new ArgumentOutOfRangeException ( nameof ( runtimeMoniker ) , runtimeMoniker , $ "Runtime moniker { runtimeMoniker } is not supported") ;
146
119
}
147
120
}
148
121
}
0 commit comments