public CoreClrConfig() { var job = Job.MediumRun.With( CustomCoreClrToolchain.CreateBuilder() .UseCoreClrNuGet("3.0.0-preview1-26814-05", "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json") .UseCoreFxNuGet("4.6.0-preview1-26814-05", "https://dotnet.myget.org/F/dotnet-core/api/v3/index.json") .TargetFrameworkMoniker("netcoreapp3.0") .DisplayName("Net Core 3.0") .RuntimeIdentifier("win-x64") .ToToolchain()) .WithGcServer(true) .WithIterationCount(23) .WithLaunchCount(1) .WithWarmupCount(5); Add(job.With( new List <EnvironmentVariable>() { new EnvironmentVariable("COMPlus_EnableAVX", "0"), new EnvironmentVariable("COMPlus_TieredCompilation", "0") })); //DefaultConfig.Instance.With() Add(DefaultConfig.Instance.GetExporters().ToArray()); Add(DefaultConfig.Instance.GetLoggers().ToArray()); Add(DefaultConfig.Instance.GetColumnProviders().ToArray()); var diagnoser = new DisassemblyDiagnoserConfig( printAsm: true, printSource: true, printPrologAndEpilog: true, recursiveDepth: 2); Add(DisassemblyDiagnoser.Create(diagnoser)); }
internal HtmlDisassemblyExporter(IReadOnlyDictionary <BenchmarkCase, DisassemblyResult> results, DisassemblyDiagnoserConfig config) { this.results = results; this.config = config; }
public WindowsDisassembler(DisassemblyDiagnoserConfig config) => this.config = config;
internal static IReadOnlyList <Element> Prettify(DisassembledMethod method, DisassemblyResult disassemblyResult, DisassemblyDiagnoserConfig config, string labelPrefix) { var asmInstructions = method.Maps.SelectMany(map => map.SourceCodes.OfType <Asm>()).ToArray(); // first of all, we search of referenced addresses (jump|calls) var referencedAddresses = new HashSet <ulong>(); foreach (var asm in asmInstructions) { if (ClrMdV2Disassembler.TryGetReferencedAddress(asm.Instruction, disassemblyResult.PointerSize, out ulong referencedAddress)) { referencedAddresses.Add(referencedAddress); } } // for every IP that is referenced, we emit a uinque label var addressesToLabels = new Dictionary <ulong, string>(); int currentLabelIndex = 0; foreach (var instruction in asmInstructions) { if (referencedAddresses.Contains(instruction.InstructionPointer) && !addressesToLabels.ContainsKey(instruction.InstructionPointer)) { addressesToLabels.Add(instruction.InstructionPointer, $"{labelPrefix}_L{currentLabelIndex++:00}"); } } var formatterWithLabelsSymbols = config.GetFormatterWithSymbolSolver(addressesToLabels); var formatterWithGlobalSymbols = config.GetFormatterWithSymbolSolver(disassemblyResult.AddressToNameMapping); var prettified = new List <Element>(); foreach (var map in method.Maps) { foreach (var instruction in map.SourceCodes) { if (instruction is Sharp sharp) { prettified.Add(new Element(sharp.Text, sharp)); } else if (instruction is MonoCode mono) { prettified.Add(new Element(mono.Text, mono)); } else if (instruction is Asm asm) { // this IP is referenced by some jump|call, so we add a label if (addressesToLabels.TryGetValue(asm.InstructionPointer, out string label)) { prettified.Add(new Label(label)); } if (ClrMdV2Disassembler.TryGetReferencedAddress(asm.Instruction, disassemblyResult.PointerSize, out ulong referencedAddress)) { // jump or a call within same method if (addressesToLabels.TryGetValue(referencedAddress, out string translated)) { prettified.Add(new Reference(InstructionFormatter.Format(asm.Instruction, formatterWithLabelsSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize), translated, asm)); continue; } // call to a known method if (disassemblyResult.AddressToNameMapping.ContainsKey(referencedAddress)) { prettified.Add(new Element(InstructionFormatter.Format(asm.Instruction, formatterWithGlobalSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize), asm)); continue; } } prettified.Add(new Element(InstructionFormatter.Format(asm.Instruction, formatterWithGlobalSymbols, config.PrintInstructionAddresses, disassemblyResult.PointerSize), asm)); } } } return(prettified); }
internal static void Export(ILogger logger, DisassemblyResult disassemblyResult, DisassemblyDiagnoserConfig config, bool quotingCode = true) { int methodIndex = 0; foreach (var method in disassemblyResult.Methods.Where(method => string.IsNullOrEmpty(method.Problem))) { if (quotingCode) { logger.WriteLine("```assembly"); } logger.WriteLine($"; {method.Name}"); var pretty = DisassemblyPrettifier.Prettify(method, disassemblyResult, config, $"M{methodIndex++:00}"); ulong totalSizeInBytes = 0; foreach (var element in pretty) { if (element is DisassemblyPrettifier.Label label) { logger.WriteLine($"{label.TextRepresentation}:"); } else if (element.Source is Sharp sharp) { logger.WriteLine($"; {sharp.Text.Replace("\n", "\n; ")}"); // they are multiline and we need to add ; for each line } else if (element.Source is Asm asm) { checked { totalSizeInBytes += (uint)asm.Instruction.ByteLength; } logger.WriteLine($" {element.TextRepresentation}"); } else if (element.Source is MonoCode mono) { logger.WriteLine(mono.Text); } } logger.WriteLine($"; Total bytes of code {totalSizeInBytes}"); if (quotingCode) { logger.WriteLine("```"); } } foreach (var withProblems in disassemblyResult.Methods .Where(method => !string.IsNullOrEmpty(method.Problem)) .GroupBy(method => method.Problem)) { logger.WriteLine($"**{withProblems.Key}**"); foreach (var withProblem in withProblems) { logger.WriteLine(withProblem.Name); } } logger.WriteLine(); }
internal LinuxDisassembler(DisassemblyDiagnoserConfig config) => this.config = config;
internal static string BuildDisassemblyString(DisassemblyResult disassemblyResult, DisassemblyDiagnoserConfig config) { StringBuilder sb = new StringBuilder(); int methodIndex = 0; foreach (var method in disassemblyResult.Methods.Where(method => string.IsNullOrEmpty(method.Problem))) { sb.AppendLine("```assembly"); sb.AppendLine($"; {method.Name}"); var pretty = Prettify.Value.Invoke(method, disassemblyResult, config, $"M{methodIndex++:00}"); ulong totalSizeInBytes = 0; foreach (var element in pretty) { if (element.Source() is Asm asm) { checked { totalSizeInBytes += (uint)asm.Instruction.ByteLength; } sb.AppendLine($" {element.TextRepresentation()}"); } else // it's a DisassemblyPrettifier.Label (internal type..) { sb.AppendLine($"{element.TextRepresentation()}:"); } } sb.AppendLine($"; Total bytes of code {totalSizeInBytes}"); sb.AppendLine("```"); } return(sb.ToString()); }
internal SameArchitectureDisassembler(DisassemblyDiagnoserConfig config) => this.config = config;
internal MonoDisassembler(DisassemblyDiagnoserConfig _) { }