[netcore] Remove local copy of static alc resolve methods
[mono-project.git] / mcs / tools / aprofutil / Program.cs
blobedf245f6ed23336c643c86ebc20bd1ac2d779fc2
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text.RegularExpressions;
5 using Mono.Options;
6 using Mono.Profiler.Aot;
8 using static System.Console;
10 namespace aotprofiletool {
11 class MainClass {
12 static readonly string Name = "aotprofile-tool";
14 static bool Methods;
15 static bool Modules;
16 static bool Summary;
17 static bool Types;
18 static bool Verbose;
20 static Regex FilterMethod;
21 static Regex FilterModule;
22 static Regex FilterType;
24 static string Output;
26 static string ProcessArguments (string [] args)
28 var help = false;
29 var options = new OptionSet {
30 $"Usage: {Name}.exe OPTIONS* <aotprofile-file>",
31 "",
32 "Processes AOTPROFILE files created by Mono's AOT Profiler",
33 "",
34 "Copyright 2019 Microsoft Corporation",
35 "",
36 "Options:",
37 { "h|help|?",
38 "Show this message and exit",
39 v => help = v != null },
40 { "a|all",
41 "Show modules, types and methods in the profile",
42 v => Modules = Types = Methods = true },
43 { "d|modules",
44 "Show modules in the profile",
45 v => Modules = true },
46 { "filter-method=",
47 "Filter by method with regex VALUE",
48 v => FilterMethod = new Regex (v) },
49 { "filter-module=",
50 "Filter by module with regex VALUE",
51 v => FilterModule = new Regex (v) },
52 { "filter-type=",
53 "Filter by type with regex VALUE",
54 v => FilterType = new Regex (v) },
55 { "m|methods",
56 "Show methods in the profile",
57 v => Methods = true },
58 { "o|output=",
59 "Write profile to OUTPUT file",
60 v => Output = v },
61 { "s|summary",
62 "Show summary of the profile",
63 v => Summary = true },
64 { "t|types",
65 "Show types in the profile",
66 v => Types = true },
67 { "v|verbose",
68 "Output information about progress during the run of the tool",
69 v => Verbose = true },
70 "",
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);
79 Environment.Exit (0);
82 if (remaining.Count != 1) {
83 Error ("Please specify one <aotprofile-file> to process.");
84 Environment.Exit (2);
87 return remaining [0];
90 public static void Main (string [] args)
92 var path = ProcessArguments (args);
94 if (!File.Exists (path)) {
95 Error ($"'{path}' doesn't exist.");
96 Environment.Exit (3);
99 if (args.Length == 1) {
100 Modules = Types = Methods = true;
103 var reader = new ProfileReader ();
104 ProfileData pd;
106 using (var stream = new FileStream (path, FileMode.Open)) {
107 if (Verbose)
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 ());
130 if (!match.Success)
131 continue;
134 if (FilterType != null) {
135 var match = FilterType.Match (method.Type.ToString ());
137 if (!match.Success)
138 continue;
141 if (FilterMethod != null) {
142 var match = FilterMethod.Match (method.ToString ());
144 if (!match.Success)
145 continue;
148 methods.Add (method);
149 types.Add (type);
150 modules.Add (module);
154 if (FilterMethod == null && FilterType != null) {
155 foreach (var type in pd.Types) {
156 if (types.Contains (type))
157 continue;
159 var match = FilterType.Match (type.ToString ());
161 if (!match.Success)
162 continue;
164 types.Add (type);
168 if (Modules) {
169 ColorWriteLine ($"Modules:", ConsoleColor.Green);
171 foreach (var module in modules)
172 WriteLine ($"\t{module.Mvid} {module.ToString ()}");
175 if (Types) {
176 ColorWriteLine ($"Types:", ConsoleColor.Green);
178 foreach (var type in types)
179 WriteLine ($"\t{type}");
182 if (Methods) {
183 ColorWriteLine ($"Methods:", ConsoleColor.Green);
185 foreach (var method in methods)
186 WriteLine ($"\t{method}");
189 if (Summary) {
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)) {
197 if (Verbose)
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;
216 if (writeLine)
217 writer.WriteLine (message);
218 else
219 writer.Write (message);
221 ResetColor ();
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);