From 336b390daede2b039be780a3e0756cbb3a2702c7 Mon Sep 17 00:00:00 2001 From: filzrev <103790468+filzrev@users.noreply.github.com> Date: Wed, 26 Aug 2026 02:14:25 +0900 Subject: [PATCH] chore: modify clrmd related code to use interface --- .../Disassemblers/Arm64Disassembler.cs | 7 ++++--- .../Disassemblers/ClrMdDisassembler.cs | 13 ++++++------ .../Disassemblers/DataContracts.cs | 20 +++++++++---------- .../Disassemblers/IntelDisassembler.cs | 3 ++- .../Disassemblers/SourceCodeProvider.cs | 9 +++++---- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/BenchmarkDotNet/Disassemblers/Arm64Disassembler.cs b/src/BenchmarkDotNet/Disassemblers/Arm64Disassembler.cs index d8c1486793..be1da8e3e2 100644 --- a/src/BenchmarkDotNet/Disassemblers/Arm64Disassembler.cs +++ b/src/BenchmarkDotNet/Disassemblers/Arm64Disassembler.cs @@ -2,6 +2,7 @@ using Gee.External.Capstone; using Gee.External.Capstone.Arm64; using Microsoft.Diagnostics.Runtime; +using Microsoft.Diagnostics.Runtime.Interfaces; namespace BenchmarkDotNet.Disassemblers { @@ -19,9 +20,9 @@ private enum State private long _value; private int _expectedMovkShift; private Arm64RegisterId _registerId; - private ClrRuntime _runtime; + private IClrRuntime _runtime; - public void Init(ClrRuntime runtime) + public void Init(IClrRuntime runtime) { _state = State.LookingForPattern; _expectedMovkShift = 0; @@ -138,7 +139,7 @@ public void Feed(Arm64Instruction instruction) internal class Arm64Disassembler : ClrMdDisassembler { - protected override IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax) + protected override IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, IClrMethod currentMethod, DisassemblySyntax syntax) { const Arm64DisassembleMode disassembleMode = Arm64DisassembleMode.Arm; using (CapstoneArm64Disassembler disassembler = CapstoneDisassembler.CreateArm64Disassembler(disassembleMode)) diff --git a/src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs b/src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs index cc54ddea0c..f6e06d7b00 100644 --- a/src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs +++ b/src/BenchmarkDotNet/Disassemblers/ClrMdDisassembler.cs @@ -4,6 +4,7 @@ using BenchmarkDotNet.Filters; using BenchmarkDotNet.Portability; using Microsoft.Diagnostics.Runtime; +using Microsoft.Diagnostics.Runtime.Interfaces; using System.Text.RegularExpressions; namespace BenchmarkDotNet.Disassemblers @@ -157,7 +158,7 @@ private DisassembledMethod[] Disassemble(ClrMdArgs args, State state) return result.ToArray(); } - private static bool CanBeDisassembled(ClrMethod method) => method.ILOffsetMap.Length > 0 && method.NativeCode > 0; + private static bool CanBeDisassembled(IClrMethod method) => method.ILOffsetMap.Length > 0 && method.NativeCode > 0; private DisassembledMethod DisassembleMethod(MethodInfo methodInfo, State state, ClrMdArgs args, DisassemblySyntax syntax, SourceCodeProvider sourceCodeProvider) { @@ -206,7 +207,7 @@ private DisassembledMethod DisassembleMethod(MethodInfo methodInfo, State state, }; } - private IEnumerable Decode(ILToNativeMap map, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax) + private IEnumerable Decode(ILToNativeMap map, State state, int depth, IClrMethod currentMethod, DisassemblySyntax syntax) { ulong startAddress = map.StartAddress; uint size = (uint)(map.EndAddress - map.StartAddress); @@ -227,9 +228,9 @@ private IEnumerable Decode(ILToNativeMap map, State state, int depth, ClrMe return Decode(code, startAddress, state, depth, currentMethod, syntax); } - protected abstract IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax); + protected abstract IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, IClrMethod currentMethod, DisassemblySyntax syntax); - private static ILToNativeMap[] GetCompleteNativeMap(ClrMethod method, ClrRuntime runtime) + private static ILToNativeMap[] GetCompleteNativeMap(IClrMethod method, IClrRuntime runtime) { // it's better to use one single map rather than few small ones // it's simply easier to get next instruction when decoding ;) @@ -251,10 +252,10 @@ private static ILToNativeMap[] GetCompleteNativeMap(ClrMethod method, ClrRuntime .ToArray(); } - private static DisassembledMethod CreateEmpty(ClrMethod method, string reason) + private static DisassembledMethod CreateEmpty(IClrMethod method, string reason) => DisassembledMethod.Empty(method.Signature ?? "", method.NativeCode, reason); - protected void TryTranslateAddressToName(ulong address, bool isAddressPrecodeMD, State state, int depth, ClrMethod currentMethod) + protected void TryTranslateAddressToName(ulong address, bool isAddressPrecodeMD, State state, int depth, IClrMethod currentMethod) { if (!IsValidAddress(address) || state.AddressToNameMapping.ContainsKey(address)) return; diff --git a/src/BenchmarkDotNet/Disassemblers/DataContracts.cs b/src/BenchmarkDotNet/Disassemblers/DataContracts.cs index c7b5ddf428..2c83b46bf2 100644 --- a/src/BenchmarkDotNet/Disassemblers/DataContracts.cs +++ b/src/BenchmarkDotNet/Disassemblers/DataContracts.cs @@ -1,7 +1,7 @@ using Gee.External.Capstone; using Gee.External.Capstone.Arm64; using Iced.Intel; -using Microsoft.Diagnostics.Runtime; +using Microsoft.Diagnostics.Runtime.Interfaces; using System.ComponentModel; using System.Text.Json; using System.Text.Json.Serialization; @@ -218,18 +218,18 @@ public static class DisassemblerConstants internal sealed class State { - internal State(ClrRuntime runtime, string targetFrameworkMoniker) + internal State(IClrRuntime runtime, string targetFrameworkMoniker) { Runtime = runtime; Todo = new Queue(); - HandledMethods = new HashSet(new ClrMethodComparer()); + HandledMethods = new HashSet(new IClrMethodComparer()); AddressToNameMapping = []; RuntimeVersion = ParseVersion(targetFrameworkMoniker); } - internal ClrRuntime Runtime { get; } + internal IClrRuntime Runtime { get; } internal Queue Todo { get; } - internal HashSet HandledMethods { get; } + internal HashSet HandledMethods { get; } internal Dictionary AddressToNameMapping { get; } internal Version RuntimeVersion { get; } @@ -258,9 +258,9 @@ internal static Version ParseVersion(string targetFrameworkMoniker) return Version.Parse(versionToParse); } - private sealed class ClrMethodComparer : IEqualityComparer + private sealed class IClrMethodComparer : IEqualityComparer { - public bool Equals(ClrMethod? x, ClrMethod? y) + public bool Equals(IClrMethod? x, IClrMethod? y) { if (ReferenceEquals(x, y)) return true; @@ -271,16 +271,16 @@ public bool Equals(ClrMethod? x, ClrMethod? y) return x.NativeCode == y.NativeCode; } - public int GetHashCode(ClrMethod obj) => (int)obj.NativeCode; + public int GetHashCode(IClrMethod obj) => (int)obj.NativeCode; } } internal readonly struct MethodInfo // I am not using ValueTuple here (would be perfect) to keep the number of dependencies as low as possible { - internal ClrMethod Method { get; } + internal IClrMethod Method { get; } internal int Depth { get; } - internal MethodInfo(ClrMethod method, int depth) + internal MethodInfo(IClrMethod method, int depth) { Method = method; Depth = depth; diff --git a/src/BenchmarkDotNet/Disassemblers/IntelDisassembler.cs b/src/BenchmarkDotNet/Disassemblers/IntelDisassembler.cs index 94c874e57e..ecf513b9cf 100644 --- a/src/BenchmarkDotNet/Disassemblers/IntelDisassembler.cs +++ b/src/BenchmarkDotNet/Disassemblers/IntelDisassembler.cs @@ -1,12 +1,13 @@ using BenchmarkDotNet.Diagnosers; using Iced.Intel; using Microsoft.Diagnostics.Runtime; +using Microsoft.Diagnostics.Runtime.Interfaces; namespace BenchmarkDotNet.Disassemblers { internal class IntelDisassembler : ClrMdDisassembler { - protected override IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, ClrMethod currentMethod, DisassemblySyntax syntax) + protected override IEnumerable Decode(byte[] code, ulong startAddress, State state, int depth, IClrMethod currentMethod, DisassemblySyntax syntax) { var reader = new ByteArrayCodeReader(code); var decoder = Decoder.Create(state.Runtime.DataTarget.DataReader.PointerSize * 8, reader); diff --git a/src/BenchmarkDotNet/Disassemblers/SourceCodeProvider.cs b/src/BenchmarkDotNet/Disassemblers/SourceCodeProvider.cs index 18b9d17111..a2e568840a 100644 --- a/src/BenchmarkDotNet/Disassemblers/SourceCodeProvider.cs +++ b/src/BenchmarkDotNet/Disassemblers/SourceCodeProvider.cs @@ -1,5 +1,6 @@ using BenchmarkDotNet.Extensions; using Microsoft.Diagnostics.Runtime; +using Microsoft.Diagnostics.Runtime.Interfaces; using Microsoft.Diagnostics.Symbols; using System.Diagnostics; @@ -17,7 +18,7 @@ public void Dispose() symbolReader.Dispose(); } - internal IEnumerable GetSource(ClrMethod method, ILToNativeMap map) + internal IEnumerable GetSource(IClrMethod method, ILToNativeMap map) { var sourceLocation = GetSourceLocation(method, map.ILOffset); if (sourceLocation is not { LineNumber: > 0 }) @@ -105,7 +106,7 @@ private static string GetSmartPointer(string sourceLine, int? start, int? end) return new string(prefix); } - internal SourceLocation? GetSourceLocation(ClrMethod method, int ilOffset) + internal SourceLocation? GetSourceLocation(IClrMethod method, int ilOffset) { var reader = GetReaderForMethod(method); if (reader == null) @@ -114,9 +115,9 @@ private static string GetSmartPointer(string sourceLine, int? start, int? end) return reader.SourceLocationForManagedCode((uint)method.MetadataToken, ilOffset); } - private ManagedSymbolModule? GetReaderForMethod(ClrMethod? method) + private ManagedSymbolModule? GetReaderForMethod(IClrMethod? method) { - ClrModule? module = method?.Type?.Module; + IClrModule? module = method?.Type?.Module; PdbInfo? info = module?.Pdb; ManagedSymbolModule? reader = null;