Browse Source

Merge pull request #3076 from eduardo-vp/add/gc-info

pull/3081/head
Siegfried Pammer 2 years ago committed by GitHub
parent
commit
0c2e4b145b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      ILSpy.ReadyToRun/Properties/Resources.Designer.cs
  2. 7
      ILSpy.ReadyToRun/Properties/Resources.resx
  3. 7
      ILSpy.ReadyToRun/Properties/Resources.zh-Hans.resx
  4. 66
      ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
  5. 5
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
  6. 15
      ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
  7. 22
      ILSpy.ReadyToRun/ReadyToRunOptions.cs

15
ILSpy.ReadyToRun/Properties/Resources.Designer.cs generated

@ -90,10 +90,19 @@ namespace ILSpy.ReadyToRun.Properties { @@ -90,10 +90,19 @@ namespace ILSpy.ReadyToRun.Properties {
/// <summary>
/// Looks up a localized string similar to Show Unwind Info.
/// </summary>
public static string ShowUnwindInfo {
public static string ShowStackUnwindInfo {
get {
return ResourceManager.GetString("ShowUnwindInfo", resourceCulture);
return ResourceManager.GetString("ShowStackUnwindInfo", resourceCulture);
}
}
}
/// <summary>
/// Looks up a localized string similar to Show GC Info.
/// </summary>
public static string ShowGCInfo {
get {
return ResourceManager.GetString("ShowGCInfo", resourceCulture);
}
}
}
}

7
ILSpy.ReadyToRun/Properties/Resources.resx

@ -126,7 +126,10 @@ @@ -126,7 +126,10 @@
<data name="ShowDebugInfo" xml:space="preserve">
<value>Show Debug Info</value>
</data>
<data name="ShowUnwindInfo" xml:space="preserve">
<value>Show Unwind Info</value>
<data name="ShowGCInfo" xml:space="preserve">
<value>Show GC Info</value>
</data>
<data name="ShowStackUnwindInfo" xml:space="preserve">
<value>Show Stack Unwind Info</value>
</data>
</root>

7
ILSpy.ReadyToRun/Properties/Resources.zh-Hans.resx

@ -126,7 +126,10 @@ @@ -126,7 +126,10 @@
<data name="ShowDebugInfo" xml:space="preserve">
<value>显示调试信息</value>
</data>
<data name="ShowUnwindInfo" xml:space="preserve">
<value>显示展开信息</value>
<data name="ShowGCInfo" xml:space="preserve">
<value>显示垃圾回收信息</value>
</data>
<data name="ShowStackUnwindInfo" xml:space="preserve">
<value>显示堆栈展开信息</value>
</data>
</root>

66
ILSpy.ReadyToRun/ReadyToRunDisassembler.cs

@ -47,10 +47,26 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -47,10 +47,26 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public void Disassemble(PEFile currentFile, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
{
// TODO: Decorate the disassembly with GCInfo
ReadyToRunMethod readyToRunMethod = runtimeFunction.Method;
WriteCommentLine(readyToRunMethod.SignatureString);
if (ReadyToRunOptions.GetIsShowGCInfo(null))
{
if (readyToRunMethod.GcInfo != null)
{
string[] lines = readyToRunMethod.GcInfo.ToString().Split(Environment.NewLine);
WriteCommentLine("GC info:");
foreach (string line in lines)
{
WriteCommentLine(line);
}
}
else
{
WriteCommentLine("GC Info is not available for this method");
}
}
Dictionary<ulong, UnwindCode> unwindInfo = null;
if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64)
{
@ -96,30 +112,36 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -96,30 +112,36 @@ namespace ICSharpCode.ILSpy.ReadyToRun
formatter.Options.FirstOperandCharIndex = 10;
var tempOutput = new StringOutput();
ulong baseInstrIP = instructions[0].IP;
var boundsMap = new Dictionary<uint, uint>();
foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
{
// ignoring the return value assuming the same key is always mapped to the same value in runtimeFunction.DebugInfo.BoundsList
boundsMap.TryAdd(bound.NativeOffset, bound.ILOffset);
}
foreach (var instr in instructions)
{
int byteBaseIndex = (int)(instr.IP - address);
if (isShowDebugInfo && runtimeFunction.DebugInfo != null)
{
foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
if (byteBaseIndex >= 0 && boundsMap.TryGetValue((uint)byteBaseIndex, out uint boundILOffset))
{
if (bound.NativeOffset == byteBaseIndex)
if (boundILOffset == (uint)DebugInfoBoundsType.Prolog)
{
if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
{
WriteCommentLine("Prolog");
}
else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
{
WriteCommentLine("Epilog");
}
else
{
WriteCommentLine($"IL_{bound.ILOffset:x4}");
}
WriteCommentLine("Prolog");
}
else if (boundILOffset == (uint)DebugInfoBoundsType.Epilog)
{
WriteCommentLine("Epilog");
}
else
{
WriteCommentLine($"IL_{boundILOffset:x4}");
}
}
}
DecorateGCInfo(instr, baseInstrIP, readyToRunMethod.GcInfo);
formatter.Format(instr, tempOutput);
output.Write(instr.IP.ToString("X16"));
output.Write(" ");
@ -143,6 +165,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -143,6 +165,20 @@ namespace ICSharpCode.ILSpy.ReadyToRun
output.WriteLine();
}
private void DecorateGCInfo(Instruction instr, ulong baseInstrIP, BaseGcInfo gcInfo)
{
ulong codeOffset = instr.IP - baseInstrIP;
if (gcInfo != null && gcInfo.Transitions != null && gcInfo.Transitions.TryGetValue((int)codeOffset, out List<BaseGcTransition> transitionsForOffset))
{
// this value comes from a manual count of the spaces used for each instruction in Disassemble()
string indent = new string(' ', 36);
foreach (var transition in transitionsForOffset)
{
WriteCommentLine(indent + transition.ToString());
}
}
}
private void WriteCommentLine(string comment)
{
output.WriteLine("; " + comment);

5
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml

@ -11,12 +11,15 @@ @@ -11,12 +11,15 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Margin="3" Text="{x:Static properties:Resources.DisassemblyFormat}" />
<ComboBox Grid.Column="1" Margin="3" ItemsSource="{Binding DisassemblyFormats}" SelectedItem="{Binding DisassemblyFormat}" />
<TextBlock Grid.Row="1" Margin="3" Text="{x:Static properties:Resources.ShowUnwindInfo}"/>
<TextBlock Grid.Row="1" Margin="3" Text="{x:Static properties:Resources.ShowStackUnwindInfo}"/>
<CheckBox Grid.Row="1" Grid.Column="1" Margin="3" IsChecked="{Binding IsShowUnwindInfo}" />
<TextBlock Grid.Row="2" Margin="3" Text="{x:Static properties:Resources.ShowDebugInfo}"/>
<CheckBox Grid.Row="2" Grid.Column="1" Margin="3" IsChecked="{Binding IsShowDebugInfo}" />
<TextBlock Grid.Row="3" Margin="3" Text="{x:Static properties:Resources.ShowGCInfo}"/>
<CheckBox Grid.Row="3" Grid.Column="1" Margin="3" IsChecked="{Binding IsShowGCInfo}" />
</Grid>
</UserControl>

15
ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs

@ -39,6 +39,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -39,6 +39,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
s.DisassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(settings);
s.IsShowUnwindInfo = ReadyToRunOptions.GetIsShowUnwindInfo(settings);
s.IsShowDebugInfo = ReadyToRunOptions.GetIsShowDebugInfo(settings);
s.IsShowGCInfo = ReadyToRunOptions.GetIsShowGCInfo(settings);
this.DataContext = s;
}
@ -51,7 +52,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -51,7 +52,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public void Save(XElement root)
{
Options s = (Options)this.DataContext;
ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo, s.IsShowDebugInfo);
ReadyToRunOptions.SetDisassemblyOptions(root, s.DisassemblyFormat, s.IsShowUnwindInfo, s.IsShowDebugInfo, s.IsShowGCInfo);
}
}
@ -86,6 +87,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -86,6 +87,18 @@ namespace ICSharpCode.ILSpy.ReadyToRun
}
}
private bool isShowGCInfo;
public bool IsShowGCInfo {
get {
return isShowGCInfo;
}
set {
isShowGCInfo = value;
OnPropertyChanged(nameof(IsShowGCInfo));
}
}
private string disassemblyFormat;
public string DisassemblyFormat {

22
ILSpy.ReadyToRun/ReadyToRunOptions.cs

@ -87,12 +87,32 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -87,12 +87,32 @@ namespace ICSharpCode.ILSpy.ReadyToRun
}
}
public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool isShowUnwindInfo, bool isShowDebugInfo)
public static bool GetIsShowGCInfo(ILSpySettings settings)
{
if (settings == null)
{
settings = ILSpySettings.Load();
}
XElement e = settings[ns + "ReadyToRunOptions"];
XAttribute a = e.Attribute("IsShowGCInfo");
if (a == null)
{
return false;
}
else
{
return (bool)a;
}
}
public static void SetDisassemblyOptions(XElement root, string disassemblyFormat, bool isShowUnwindInfo, bool isShowDebugInfo, bool isShowGCInfo)
{
XElement section = new XElement(ns + "ReadyToRunOptions");
section.SetAttributeValue("DisassemblyFormat", disassemblyFormat);
section.SetAttributeValue("IsShowUnwindInfo", isShowUnwindInfo);
section.SetAttributeValue("IsShowDebugInfo", isShowDebugInfo);
section.SetAttributeValue("IsShowGCInfo", isShowGCInfo);
XElement existingElement = root.Element(ns + "ReadyToRunOptions");
if (existingElement != null)
{

Loading…
Cancel
Save