コード例 #1
0
        private ClrMethodData?FindJitCompiledMethod(ClrRuntime runtime, MethodJitResult result)
        {
            var sos = runtime.DacLibrary.SOSDacInterface;

            var methodDescAddress = unchecked ((ulong)result.Handle.ToInt64());

            if (!sos.GetMethodDescData(methodDescAddress, 0, out var methodDesc))
            {
                return(null);
            }

            return(GetJitCompiledMethodByMethodDescIfValid(sos, methodDesc)
                   ?? FindJitCompiledMethodInMethodTable(sos, methodDesc));
        }
コード例 #2
0
        private void DisassembleAndWrite(MethodJitResult result, ClrRuntime runtime, ArchitectureMode architecture, Translator translator, Reference <ulong> methodAddressRef, TextWriter writer)
        {
            var(method, regions) = ResolveJitResult(runtime, result);
            if (method == null)
            {
                writer.WriteLine("Unknown (0x{0:X})", (ulong)result.Handle.ToInt64());
                writer.WriteLine("    ; Method was not found by CLRMD (reason unknown).");
                writer.WriteLine("    ; See https://github.com/ashmind/SharpLab/issues/84.");
                return;
            }

            writer.WriteLine(method.GetFullSignature());
            switch (result.Status)
            {
            case MethodJitStatus.IgnoredRuntime:
                writer.WriteLine("    ; Cannot produce JIT assembly for runtime-implemented method.");
                return;

            case MethodJitStatus.IgnoredOpenGenericWithNoAttribute:
                writer.WriteLine("    ; Open generics cannot be JIT-compiled.");
                writer.WriteLine("    ; However you can use attribute SharpLab.Runtime.JitGeneric to specify argument types.");
                writer.WriteLine("    ; Example: [JitGeneric(typeof(int)), JitGeneric(typeof(string))] void M<T>() { ... }.");
                return;
            }

            if (regions == null)
            {
                if (result.Status == MethodJitStatus.SuccessGeneric)
                {
                    writer.WriteLine("    ; Failed to find HotColdInfo for generic method (reference types?).");
                    writer.WriteLine("    ; If you know a solution, please comment at https://github.com/ashmind/SharpLab/issues/99.");
                    return;
                }
                writer.WriteLine("    ; Failed to find HotColdRegions — please report at https://github.com/ashmind/SharpLab/issues.");
                return;
            }

            var methodAddress = regions.HotStart;

            methodAddressRef.Value = methodAddress;
            using (var disasm = new Disassembler(new IntPtr(unchecked ((long)methodAddress)), (int)regions.HotSize, architecture, methodAddress)) {
                foreach (var instruction in disasm.Disassemble())
                {
                    writer.Write("    L");
                    writer.Write((instruction.Offset - methodAddress).ToString("x4"));
                    writer.Write(": ");
                    writer.WriteLine(translator.Translate(instruction));
                }
            }
        }
コード例 #3
0
        private (ClrMethod?method, HotColdRegions?regions) ResolveJitResult(ClrRuntime runtime, MethodJitResult result)
        {
            ClrMethod?methodByPointer = null;

            if (result.Pointer != null)
            {
                methodByPointer = runtime.GetMethodByAddress((ulong)result.Pointer.Value.ToInt64());
                if (methodByPointer != null)
                {
                    if (!result.IsSuccess)
                    {
                        return(methodByPointer, null);
                    }

                    var regionsByPointer = FindNonEmptyHotColdInfo(methodByPointer);
                    if (regionsByPointer != null)
                    {
                        return(methodByPointer, regionsByPointer);
                    }
                }
            }

            var methodByHandle = runtime.GetMethodByHandle((ulong)result.Handle.ToInt64());

            if (methodByHandle == null)
            {
                return(methodByPointer, null);
            }
            if (!result.IsSuccess)
            {
                return(methodByHandle, null);
            }
            var regionsByHandle = FindNonEmptyHotColdInfo(methodByHandle);

            if (regionsByHandle == null && methodByPointer != null)
            {
                return(methodByPointer, null);
            }

            return(methodByHandle, regionsByHandle);
        }
コード例 #4
0
        private void DisassembleAndWrite(MethodJitResult result, ClrRuntime runtime, ArchitectureMode architecture, Translator translator, Reference <ulong> methodAddressRef, TextWriter writer)
        {
            void WriteSignatureFromClrMethod()
            {
                var signature = runtime.GetMethodByHandle(unchecked ((ulong)result.Handle.ToInt64()))?.Signature;

                WriteSignature(signature);
            }

            void WriteSignature(string?signature)
            {
                if (signature != null)
                {
                    writer.WriteLine(signature);
                }
                else
                {
                    writer.WriteLine("Unknown (0x{0:X})", (ulong)result.Handle.ToInt64());
                    writer.WriteLine("    ; Method signature was not found -- please report this issue.");
                }
            }

            switch (result.Status)
            {
            case MethodJitStatus.IgnoredRuntime:
                WriteSignatureFromClrMethod();
                writer.WriteLine("    ; Cannot produce JIT assembly for runtime-implemented method.");
                return;

            case MethodJitStatus.IgnoredOpenGenericWithNoAttribute:
                WriteSignatureFromClrMethod();
                writer.WriteLine("    ; Open generics cannot be JIT-compiled.");
                writer.WriteLine("    ; However you can use attribute SharpLab.Runtime.JitGeneric to specify argument types.");
                writer.WriteLine("    ; Example: [JitGeneric(typeof(int)), JitGeneric(typeof(string))] void M<T>() { ... }.");
                return;
            }

            if (FindJitCompiledMethod(runtime, result) is not {
            } method)
            {
                WriteSignatureFromClrMethod();
                if (result.Status == MethodJitStatus.SuccessGeneric)
                {
                    writer.WriteLine("    ; Failed to find JIT output for generic method (reference types?).");
                    writer.WriteLine("    ; If you know a solution, please comment at https://github.com/ashmind/SharpLab/issues/99.");
                    return;
                }

                writer.WriteLine("    ; Failed to find JIT output — please report at https://github.com/ashmind/SharpLab/issues.");
                return;
            }

            WriteSignature(method.Signature);
            var methodAddress = method.MethodAddress;

            methodAddressRef.Value = methodAddress;
            using (var disasm = new Disassembler(new IntPtr(unchecked ((long)methodAddress)), (int)method.MethodSize, architecture, methodAddress)) {
                foreach (var instruction in disasm.Disassemble())
                {
                    writer.Write("    L");
                    writer.Write((instruction.Offset - methodAddress).ToString("x4"));
                    writer.Write(": ");
                    writer.WriteLine(translator.Translate(instruction));
                }
            }
        }