Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs/tools
diff options
context:
space:
mode:
authorRadek Doulik <radekdoulik@users.noreply.github.com>2019-08-07 19:24:51 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2019-08-07 19:24:51 +0300
commit1f2b37ed37ec0f28129a6041e977f465188dff5a (patch)
treecdd882755790643bcc1c2207697b8902c7684e4a /mcs/tools
parentdcd57151613af34b213e0bd49de70e402d19cc47 (diff)
[aotprof-tool] Initial import of AOT profiler tool (#15384)
* [aotprof-tool] Initial import Imported https://github.com/radekdoulik/aotprofile-tool and updated it to use Mono.Profiler.Log * [aotprof-tool] Added man page * [aotprof-tool] Use the shortened name in README.md
Diffstat (limited to 'mcs/tools')
-rw-r--r--mcs/tools/Makefile1
-rw-r--r--mcs/tools/aprofutil/Makefile8
-rw-r--r--mcs/tools/aprofutil/Program.cs232
-rw-r--r--mcs/tools/aprofutil/README.md70
-rw-r--r--mcs/tools/aprofutil/aprofutil.csproj66
-rw-r--r--mcs/tools/aprofutil/aprofutil.exe.sources1
6 files changed, 378 insertions, 0 deletions
diff --git a/mcs/tools/Makefile b/mcs/tools/Makefile
index c632a8bf388..fcda3b1b56e 100644
--- a/mcs/tools/Makefile
+++ b/mcs/tools/Makefile
@@ -2,6 +2,7 @@ thisdir = tools
net_4_5_dirs := \
al \
+ aprofutil \
linker \
culevel \
genxs \
diff --git a/mcs/tools/aprofutil/Makefile b/mcs/tools/aprofutil/Makefile
new file mode 100644
index 00000000000..46b47779c3c
--- /dev/null
+++ b/mcs/tools/aprofutil/Makefile
@@ -0,0 +1,8 @@
+thisdir = tools/aprofutil
+include ../../build/rules.make
+
+PROGRAM = aprofutil.exe
+
+LIB_REFS = System System.Core Mono.Options Mono.Profiler.Log
+
+include ../../build/executable.make
diff --git a/mcs/tools/aprofutil/Program.cs b/mcs/tools/aprofutil/Program.cs
new file mode 100644
index 00000000000..edf245f6ed2
--- /dev/null
+++ b/mcs/tools/aprofutil/Program.cs
@@ -0,0 +1,232 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using Mono.Options;
+using Mono.Profiler.Aot;
+
+using static System.Console;
+
+namespace aotprofiletool {
+ class MainClass {
+ static readonly string Name = "aotprofile-tool";
+
+ static bool Methods;
+ static bool Modules;
+ static bool Summary;
+ static bool Types;
+ static bool Verbose;
+
+ static Regex FilterMethod;
+ static Regex FilterModule;
+ static Regex FilterType;
+
+ static string Output;
+
+ static string ProcessArguments (string [] args)
+ {
+ var help = false;
+ var options = new OptionSet {
+ $"Usage: {Name}.exe OPTIONS* <aotprofile-file>",
+ "",
+ "Processes AOTPROFILE files created by Mono's AOT Profiler",
+ "",
+ "Copyright 2019 Microsoft Corporation",
+ "",
+ "Options:",
+ { "h|help|?",
+ "Show this message and exit",
+ v => help = v != null },
+ { "a|all",
+ "Show modules, types and methods in the profile",
+ v => Modules = Types = Methods = true },
+ { "d|modules",
+ "Show modules in the profile",
+ v => Modules = true },
+ { "filter-method=",
+ "Filter by method with regex VALUE",
+ v => FilterMethod = new Regex (v) },
+ { "filter-module=",
+ "Filter by module with regex VALUE",
+ v => FilterModule = new Regex (v) },
+ { "filter-type=",
+ "Filter by type with regex VALUE",
+ v => FilterType = new Regex (v) },
+ { "m|methods",
+ "Show methods in the profile",
+ v => Methods = true },
+ { "o|output=",
+ "Write profile to OUTPUT file",
+ v => Output = v },
+ { "s|summary",
+ "Show summary of the profile",
+ v => Summary = true },
+ { "t|types",
+ "Show types in the profile",
+ v => Types = true },
+ { "v|verbose",
+ "Output information about progress during the run of the tool",
+ v => Verbose = true },
+ "",
+ "If no other option than -v is used then --all is used by default"
+ };
+
+ var remaining = options.Parse (args);
+
+ if (help || args.Length < 1) {
+ options.WriteOptionDescriptions (Out);
+
+ Environment.Exit (0);
+ }
+
+ if (remaining.Count != 1) {
+ Error ("Please specify one <aotprofile-file> to process.");
+ Environment.Exit (2);
+ }
+
+ return remaining [0];
+ }
+
+ public static void Main (string [] args)
+ {
+ var path = ProcessArguments (args);
+
+ if (!File.Exists (path)) {
+ Error ($"'{path}' doesn't exist.");
+ Environment.Exit (3);
+ }
+
+ if (args.Length == 1) {
+ Modules = Types = Methods = true;
+ }
+
+ var reader = new ProfileReader ();
+ ProfileData pd;
+
+ using (var stream = new FileStream (path, FileMode.Open)) {
+ if (Verbose)
+ ColorWriteLine ($"Reading '{path}'...", ConsoleColor.Yellow);
+
+ pd = reader.ReadAllData (stream);
+ }
+
+ List<MethodRecord> methods = new List<MethodRecord> (pd.Methods);
+ ICollection<TypeRecord> types = new List<TypeRecord> (pd.Types);
+ ICollection<ModuleRecord> modules = new List<ModuleRecord> (pd.Modules);
+
+ if (FilterMethod != null || FilterType != null || FilterModule != null) {
+ methods = new List<MethodRecord> ();
+ types = new HashSet<TypeRecord> ();
+ modules = new HashSet<ModuleRecord> ();
+
+ foreach (var method in pd.Methods) {
+
+ var type = method.Type;
+ var module = type.Module;
+
+ if (FilterModule != null) {
+ var match = FilterModule.Match (module.ToString ());
+
+ if (!match.Success)
+ continue;
+ }
+
+ if (FilterType != null) {
+ var match = FilterType.Match (method.Type.ToString ());
+
+ if (!match.Success)
+ continue;
+ }
+
+ if (FilterMethod != null) {
+ var match = FilterMethod.Match (method.ToString ());
+
+ if (!match.Success)
+ continue;
+ }
+
+ methods.Add (method);
+ types.Add (type);
+ modules.Add (module);
+ }
+ }
+
+ if (FilterMethod == null && FilterType != null) {
+ foreach (var type in pd.Types) {
+ if (types.Contains (type))
+ continue;
+
+ var match = FilterType.Match (type.ToString ());
+
+ if (!match.Success)
+ continue;
+
+ types.Add (type);
+ }
+ }
+
+ if (Modules) {
+ ColorWriteLine ($"Modules:", ConsoleColor.Green);
+
+ foreach (var module in modules)
+ WriteLine ($"\t{module.Mvid} {module.ToString ()}");
+ }
+
+ if (Types) {
+ ColorWriteLine ($"Types:", ConsoleColor.Green);
+
+ foreach (var type in types)
+ WriteLine ($"\t{type}");
+ }
+
+ if (Methods) {
+ ColorWriteLine ($"Methods:", ConsoleColor.Green);
+
+ foreach (var method in methods)
+ WriteLine ($"\t{method}");
+ }
+
+ if (Summary) {
+ ColorWriteLine ($"Summary:", ConsoleColor.Green);
+ WriteLine ($"\tModules: {modules.Count.ToString ("N0"),10}{(modules.Count != pd.Modules.Length ? $" (of {pd.Modules.Length})" : "" )}");
+ WriteLine ($"\tTypes: {types.Count.ToString ("N0"),10}{(types.Count != pd.Types.Length ? $" (of {pd.Types.Length})" : "")}");
+ WriteLine ($"\tMethods: {methods.Count.ToString ("N0"),10}{(methods.Count != pd.Methods.Length ? $" (of {pd.Methods.Length})" : "")}");
+ }
+
+ if (!string.IsNullOrEmpty (Output)) {
+ if (Verbose)
+ ColorWriteLine ($"Going to write the profile to '{Output}'", ConsoleColor.Yellow);
+ var modulesArray = new ModuleRecord [modules.Count];
+ modules.CopyTo (modulesArray, 0);
+ var typesArray = new TypeRecord [types.Count];
+ types.CopyTo (typesArray, 0);
+ var updatedPD = new ProfileData (modulesArray, typesArray, methods.ToArray ());
+
+ using (var stream = new FileStream (Output, FileMode.Create)) {
+ var writer = new ProfileWriter ();
+ writer.WriteAllData (stream, updatedPD);
+ }
+ }
+ }
+
+ static void ColorMessage (string message, ConsoleColor color, TextWriter writer, bool writeLine = true)
+ {
+ ForegroundColor = color;
+
+ if (writeLine)
+ writer.WriteLine (message);
+ else
+ writer.Write (message);
+
+ ResetColor ();
+ }
+
+ public static void ColorWriteLine (string message, ConsoleColor color) => ColorMessage (message, color, Out);
+
+ public static void ColorWrite (string message, ConsoleColor color) => ColorMessage (message, color, Out, false);
+
+ public static void Error (string message) => ColorMessage ($"Error: {Name}: {message}", ConsoleColor.Red, Console.Error);
+
+ public static void Warning (string message) => ColorMessage ($"Warning: {Name}: {message}", ConsoleColor.Yellow, Console.Error);
+ }
+}
diff --git a/mcs/tools/aprofutil/README.md b/mcs/tools/aprofutil/README.md
new file mode 100644
index 00000000000..22e749e20c9
--- /dev/null
+++ b/mcs/tools/aprofutil/README.md
@@ -0,0 +1,70 @@
+**aprofutil** is a tool to inspect AOT profiler files
+
+```
+Usage: aprofutil.exe OPTIONS* <aotprofile-file>
+
+Processes AOTPROFILE files created by Mono's AOT Profiler
+
+Copyright 2019 Microsoft Corporation
+
+Options:
+ -h, --help, -? Show this message and exit
+ -a, --all Show modules, types and methods in the profile
+ -d, --modules Show modules in the profile
+ --filter-method=VALUE Filter by method with regex VALUE
+ --filter-module=VALUE Filter by module with regex VALUE
+ --filter-type=VALUE Filter by type with regex VALUE
+ -m, --methods Show methods in the profile
+ -s, --summary Show summary of the profile
+ -t, --types Show types in the profile
+ -v, --verbose Output information about progress during the run
+ of the tool
+
+If no other option than -v is used then --all is used by default
+```
+
+It can be use to show and filter the profiler file content in readable text form.
+
+### Example usage
+
+Display modules and summary of XA startup profile
+```
+mono aprofutil.exe -sd startup.aotprofile
+Modules:
+ 41C38B0A-2032-45CE-8638-0299CED65330 mscorlib
+ 0326DF03-2158-4F7A-9A2B-B7A9419F021D Mono.Android
+ 8FB63BB4-1195-4173-A9ED-0EC341B07C32 System
+ 74C06E06-C1C7-4A4C-B64E-EAC7DBB08BBC Java.Interop
+ 11E2319F-6A26-461C-9C46-C972248BEE4B System.Core
+ 7999CC4B-D566-4ECA-8A72-469344172CA3 Xamarin.Forms.Platform.Android
+ C5089213-328B-451D-BA87-D6585C120780 Xamarin.Forms.Performance.Integration.Droid
+ D754F8AE-503C-41C8-B16F-647FC662507A Xamarin.Android.Support.v7.AppCompat
+ 929ECB6D-1171-4C66-8470-DD32AC608969 Xamarin.Android.Support.Fragment
+ F841E23B-59A8-4AE2-9A84-D2FC1D891B4A Xamarin.Forms.Core
+ 945CCBF8-C2DB-468B-B3BD-D7ACA37B69AD Xamarin.Forms.Performance.Integration
+ AF20FA19-F07E-4BD4-B5ED-104706EA660E Xamarin.Forms.Xaml
+ 629C84F8-0988-42EF-8BC5-872173A0A71F FormsViewGroup
+ 60398815-8E62-487E-A553-781F56A0849D Xamarin.Android.Support.Design
+ F0C550D7-665A-40B5-A307-8E9B49976D87 Xamarin.Android.Support.Core.UI
+ 23A34485-DE75-440E-BA9D-E235F664E990 Xamarin.Android.Support.Compat
+Summary:
+ Modules: 16
+ Types: 907
+ Methods: 4,230
+```
+
+Filter Java.Interop.Runtime type in XA startup profile:
+```
+mono aprofutil.exe --filter-type Java.Interop.Runtime -sa startup.aotprofile
+Modules:
+ 0326DF03-2158-4F7A-9A2B-B7A9419F021D Mono.Android
+Types:
+ Java.Interop.Runtime
+Methods:
+ bool Java.Interop.Runtime:IsGCUserPeer (Android.Runtime.IJavaObject)
+ bool Java.Interop.Runtime:IsGCUserPeer (intptr)
+Summary:
+ Modules: 1 (of 16)
+ Types: 1 (of 907)
+ Methods: 2 (of 4230)
+```
diff --git a/mcs/tools/aprofutil/aprofutil.csproj b/mcs/tools/aprofutil/aprofutil.csproj
new file mode 100644
index 00000000000..faa957543d6
--- /dev/null
+++ b/mcs/tools/aprofutil/aprofutil.csproj
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- WARNING: this file is autogenerated, don't modify it. Edit the .sources file of the corresponding assembly instead if you want to add/remove C# source files. -->
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">net_4_x</Platform>
+ <ProjectGuid>{658B566B-CED1-4C42-9926-C1AA930BA368}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoWarn>1699</NoWarn>
+ <LangVersion>latest</LangVersion>
+ <HostPlatform Condition=" '$(HostPlatform)' == '' and '$(OS)' == 'Windows_NT'">win32</HostPlatform>
+ <HostPlatform Condition=" '$(HostPlatform)' == '' and '$(OS)' == 'Unix' and $([System.IO.File]::Exists('/usr/lib/libc.dylib'))">macos</HostPlatform>
+ <HostPlatform Condition=" '$(HostPlatform)' == '' and '$(OS)' == 'Unix'">linux</HostPlatform>
+ <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
+ <NoStdLib>False</NoStdLib>
+ <NoConfig>True</NoConfig>
+ <AssemblyName>aprofutil</AssemblyName>
+ <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup>
+ <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0,
+ Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This
+ is a problem to compile the Mono mscorlib.dll -->
+ <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Platform)' == 'net_4_x' ">
+ <OutputPath>./../../class/lib/net_4_x-$(HostPlatform)</OutputPath>
+ <IntermediateOutputPath>./../../class/obj/$(AssemblyName)-net_4_x-$(HostPlatform)</IntermediateOutputPath>
+ <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;WIN_PLATFORM</DefineConstants>
+ </PropertyGroup>
+ <!-- @ALL_PROFILE_PROPERTIES@ -->
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <!-- TRACE is set only for Debug configuration, so inherit from platform-specific value -->
+ <DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- @BUILT_SOURCES@ -->
+ <!--Common files-->
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ </ItemGroup>
+ <!--End of common files-->
+ <!-- @ALL_SOURCES@ -->
+ <!-- @COMMON_PROJECT_REFERENCES@ -->
+ <ItemGroup Condition=" '$(Platform)' == 'net_4_x' ">
+ <ProjectReference Include="../../class/System/System.csproj" />
+ <ProjectReference Include="../../class/System.Core/System.Core.csproj" />
+ <ProjectReference Include="../../class/Mono.Options/Mono.Options.csproj" />
+ <ProjectReference Include="../../class/Mono.Profiler.Log/Mono.Profiler.Log.csproj" />
+ </ItemGroup>
+ <!-- @ALL_REFERENCES@ -->
+ <!-- @ALL_RESOURCES@ -->
+ <PropertyGroup>
+ <!-- Force the pre-build event to run after references have been resolved. The default
+ behavior is to run them before resolving references, which can cause things like
+ culevel.exe to be used before they have been built. -->
+ <PreBuildEventDependsOn>ResolveReferences</PreBuildEventDependsOn>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/mcs/tools/aprofutil/aprofutil.exe.sources b/mcs/tools/aprofutil/aprofutil.exe.sources
new file mode 100644
index 00000000000..48de7b53bdd
--- /dev/null
+++ b/mcs/tools/aprofutil/aprofutil.exe.sources
@@ -0,0 +1 @@
+Program.cs