2 using System
.Collections
.Generic
;
4 using System
.Text
.RegularExpressions
;
6 using Mono
.Profiler
.Aot
;
8 using static System
.Console
;
10 namespace aotprofiletool
{
12 static readonly string Name
= "aotprofile-tool";
20 static Regex FilterMethod
;
21 static Regex FilterModule
;
22 static Regex FilterType
;
26 static string ProcessArguments (string [] args
)
29 var options
= new OptionSet
{
30 $"Usage: {Name}.exe OPTIONS* <aotprofile-file>",
32 "Processes AOTPROFILE files created by Mono's AOT Profiler",
34 "Copyright 2019 Microsoft Corporation",
38 "Show this message and exit",
39 v
=> help
= v
!= null },
41 "Show modules, types and methods in the profile",
42 v
=> Modules
= Types
= Methods
= true },
44 "Show modules in the profile",
45 v
=> Modules
= true },
47 "Filter by method with regex VALUE",
48 v
=> FilterMethod
= new Regex (v
) },
50 "Filter by module with regex VALUE",
51 v
=> FilterModule
= new Regex (v
) },
53 "Filter by type with regex VALUE",
54 v
=> FilterType
= new Regex (v
) },
56 "Show methods in the profile",
57 v
=> Methods
= true },
59 "Write profile to OUTPUT file",
62 "Show summary of the profile",
63 v
=> Summary
= true },
65 "Show types in the profile",
68 "Output information about progress during the run of the tool",
69 v
=> Verbose
= true },
71 "If no other option than -v is used then --all is used by default"
74 var remaining
= options
.Parse (args
);
76 if (help
|| args
.Length
< 1) {
77 options
.WriteOptionDescriptions (Out
);
82 if (remaining
.Count
!= 1) {
83 Error ("Please specify one <aotprofile-file> to process.");
90 public static void Main (string [] args
)
92 var path
= ProcessArguments (args
);
94 if (!File
.Exists (path
)) {
95 Error ($"'{path}' doesn't exist.");
99 if (args
.Length
== 1) {
100 Modules
= Types
= Methods
= true;
103 var reader
= new ProfileReader ();
106 using (var stream
= new FileStream (path
, FileMode
.Open
)) {
108 ColorWriteLine ($"Reading '{path}'...", ConsoleColor
.Yellow
);
110 pd
= reader
.ReadAllData (stream
);
113 List
<MethodRecord
> methods
= new List
<MethodRecord
> (pd
.Methods
);
114 ICollection
<TypeRecord
> types
= new List
<TypeRecord
> (pd
.Types
);
115 ICollection
<ModuleRecord
> modules
= new List
<ModuleRecord
> (pd
.Modules
);
117 if (FilterMethod
!= null || FilterType
!= null || FilterModule
!= null) {
118 methods
= new List
<MethodRecord
> ();
119 types
= new HashSet
<TypeRecord
> ();
120 modules
= new HashSet
<ModuleRecord
> ();
122 foreach (var method
in pd
.Methods
) {
124 var type
= method
.Type
;
125 var module
= type
.Module
;
127 if (FilterModule
!= null) {
128 var match
= FilterModule
.Match (module
.ToString ());
134 if (FilterType
!= null) {
135 var match
= FilterType
.Match (method
.Type
.ToString ());
141 if (FilterMethod
!= null) {
142 var match
= FilterMethod
.Match (method
.ToString ());
148 methods
.Add (method
);
150 modules
.Add (module
);
154 if (FilterMethod
== null && FilterType
!= null) {
155 foreach (var type
in pd
.Types
) {
156 if (types
.Contains (type
))
159 var match
= FilterType
.Match (type
.ToString ());
169 ColorWriteLine ($"Modules:", ConsoleColor
.Green
);
171 foreach (var module
in modules
)
172 WriteLine ($"\t{module.Mvid} {module.ToString ()}");
176 ColorWriteLine ($"Types:", ConsoleColor
.Green
);
178 foreach (var type
in types
)
179 WriteLine ($"\t{type}");
183 ColorWriteLine ($"Methods:", ConsoleColor
.Green
);
185 foreach (var method
in methods
)
186 WriteLine ($"\t{method}");
190 ColorWriteLine ($"Summary:", ConsoleColor
.Green
);
191 WriteLine ($"\tModules: {modules.Count.ToString ("N0"),10}{(modules.Count != pd.Modules.Length ? $" (of {pd.Modules.Length})" : "" )}");
192 WriteLine ($"\tTypes
: {types.Count.ToString ("N0"),10}{(types.Count != pd.Types.Length ? $" (of {pd.Types.Length}
)" : "")}");
193 WriteLine ($"\tMethods: {methods.Count.ToString ("N0"),10}{(methods.Count != pd.Methods.Length ? $" (of {pd.Methods.Length})" : "")}");
196 if (!string.IsNullOrEmpty (Output)) {
198 ColorWriteLine ($"Going to write the profile to
'{Output}'", ConsoleColor.Yellow);
199 var modulesArray = new ModuleRecord [modules.Count];
200 modules.CopyTo (modulesArray, 0);
201 var typesArray = new TypeRecord [types.Count];
202 types.CopyTo (typesArray, 0);
203 var updatedPD = new ProfileData (modulesArray, typesArray, methods.ToArray ());
205 using (var stream = new FileStream (Output, FileMode.Create)) {
206 var writer = new ProfileWriter ();
207 writer.WriteAllData (stream, updatedPD);
212 static void ColorMessage (string message, ConsoleColor color, TextWriter writer, bool writeLine = true)
214 ForegroundColor = color;
217 writer.WriteLine (message);
219 writer.Write (message);
224 public static void ColorWriteLine (string message, ConsoleColor color) => ColorMessage (message, color, Out);
226 public static void ColorWrite (string message, ConsoleColor color) => ColorMessage (message, color, Out, false);
228 public static void Error (string message) => ColorMessage ($"Error
: {Name}
: {message}
", ConsoleColor.Red, Console.Error);
230 public static void Warning (string message) => ColorMessage ($"Warning
: {Name}
: {message}
", ConsoleColor.Yellow, Console.Error);