Skip to content

Commit 0812d49

Browse files
authored
Make parsing of debug info lazy (#1657)
1 parent 18aee2a commit 0812d49

15 files changed

+313
-213
lines changed

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/DebugInfo.cs

+65-25
Original file line numberDiff line numberDiff line change
@@ -18,45 +18,45 @@ namespace ILCompiler.Reflection.ReadyToRun
1818
/// </summary>
1919
public class DebugInfo
2020
{
21-
private List<DebugInfoBoundsEntry> _boundsList = new List<DebugInfoBoundsEntry>();
22-
private List<NativeVarInfo> _variablesList = new List<NativeVarInfo>();
21+
private readonly ReadyToRunReader _readyToRunReader;
22+
private readonly int _offset;
23+
private List<DebugInfoBoundsEntry> _boundsList;
24+
private List<NativeVarInfo> _variablesList;
2325
private Machine _machine;
2426

25-
public DebugInfo(byte[] image, int offset, Machine machine)
27+
public DebugInfo(ReadyToRunReader readyToRunReader, int offset)
2628
{
27-
_machine = machine;
28-
29-
// Get the id of the runtime function from the NativeArray
30-
uint lookback = 0;
31-
uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);
29+
this._readyToRunReader = readyToRunReader;
30+
this._offset = offset;
31+
}
3232

33-
if (lookback != 0)
33+
public List<DebugInfoBoundsEntry> BoundsList
34+
{
35+
get
3436
{
35-
System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
36-
debugInfoOffset = (uint)offset - lookback;
37+
EnsureInitialized();
38+
return _boundsList;
3739
}
40+
}
3841

39-
NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset);
40-
uint boundsByteCount = reader.ReadUInt();
41-
uint variablesByteCount = reader.ReadUInt();
42-
int boundsOffset = reader.GetNextByteOffset();
43-
int variablesOffset = (int)(boundsOffset + boundsByteCount);
44-
45-
if (boundsByteCount > 0)
42+
public List<NativeVarInfo> VariablesList
43+
{
44+
get
4645
{
47-
ParseBounds(image, boundsOffset);
46+
EnsureInitialized();
47+
return _variablesList;
4848
}
49+
}
4950

50-
if (variablesByteCount > 0)
51+
public Machine Machine
52+
{
53+
get
5154
{
52-
ParseNativeVarInfo(image, variablesOffset);
55+
EnsureInitialized();
56+
return _machine;
5357
}
5458
}
5559

56-
public List<DebugInfoBoundsEntry> BoundsList => _boundsList;
57-
public List<NativeVarInfo> VariablesList => _variablesList;
58-
public Machine Machine => _machine;
59-
6060
/// <summary>
6161
/// Convert a register number in debug info into a machine-specific register
6262
/// </summary>
@@ -77,6 +77,46 @@ public static string GetPlatformSpecificRegister(Machine machine, int regnum)
7777
}
7878
}
7979

80+
private void EnsureInitialized()
81+
{
82+
if (_boundsList != null)
83+
{
84+
return;
85+
}
86+
int offset = _offset;
87+
_boundsList = new List<DebugInfoBoundsEntry>();
88+
_variablesList = new List<NativeVarInfo>();
89+
Machine machine = _readyToRunReader.Machine;
90+
byte[] image = _readyToRunReader.Image;
91+
_machine = machine;
92+
93+
// Get the id of the runtime function from the NativeArray
94+
uint lookback = 0;
95+
uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);
96+
97+
if (lookback != 0)
98+
{
99+
System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
100+
debugInfoOffset = (uint)offset - lookback;
101+
}
102+
103+
NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset);
104+
uint boundsByteCount = reader.ReadUInt();
105+
uint variablesByteCount = reader.ReadUInt();
106+
int boundsOffset = reader.GetNextByteOffset();
107+
int variablesOffset = (int)(boundsOffset + boundsByteCount);
108+
109+
if (boundsByteCount > 0)
110+
{
111+
ParseBounds(image, boundsOffset);
112+
}
113+
114+
if (variablesByteCount > 0)
115+
{
116+
ParseNativeVarInfo(image, variablesOffset);
117+
}
118+
}
119+
80120
private void ParseBounds(byte[] image, int offset)
81121
{
82122
// Bounds info contains (Native Offset, IL Offset, flags)

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/EHInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public class EHClause
8484
/// </summary>
8585
/// <param name="reader">R2R image reader<param>
8686
/// <param name="offset">Offset of the EH clause in the image</param>
87-
public EHClause(R2RReader reader, int offset)
87+
public EHClause(ReadyToRunReader reader, int offset)
8888
{
8989
Flags = (CorExceptionFlag)BitConverter.ToUInt32(reader.Image, offset + 0 * sizeof(uint));
9090
TryOffset = BitConverter.ToUInt32(reader.Image, offset + 1 * sizeof(uint));
@@ -175,7 +175,7 @@ public class EHInfo
175175
/// <param name="methodRva">Starting RVA of the runtime function</param>
176176
/// <param name="offset">File offset of the EH info</param>
177177
/// <param name="clauseCount">Number of EH info clauses</param>
178-
public EHInfo(R2RReader reader, int ehInfoRva, int methodRva, int offset, int clauseCount)
178+
public EHInfo(ReadyToRunReader reader, int ehInfoRva, int methodRva, int offset, int clauseCount)
179179
{
180180
EHInfoRVA = ehInfoRva;
181181
MethodRVA = methodRva;

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/GCRefMap.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ public GCRefMap(uint stackPop, GCRefMapEntry[] entries)
5757
/// </summary>
5858
public class GCRefMapDecoder
5959
{
60-
private readonly R2RReader _reader;
60+
private readonly ReadyToRunReader _reader;
6161
private int _offset;
6262
private int _pendingByte;
6363
private int _pos;
6464

65-
public GCRefMapDecoder(R2RReader reader, int offset)
65+
public GCRefMapDecoder(ReadyToRunReader reader, int offset)
6666
{
6767
_reader = reader;
6868
_offset = offset;

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RHeader.cs renamed to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunHeader.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace ILCompiler.Reflection.ReadyToRun
1313
/// <summary>
1414
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_HEADER
1515
/// </summary>
16-
public class R2RHeader
16+
public class ReadyToRunHeader
1717
{
1818
/// <summary>
1919
/// The expected signature of a ReadyToRun header
@@ -51,9 +51,9 @@ public class R2RHeader
5151
/// <summary>
5252
/// The ReadyToRun section RVAs and sizes
5353
/// </summary>
54-
public IDictionary<R2RSection.SectionType, R2RSection> Sections { get; }
54+
public IDictionary<ReadyToRunSection.SectionType, ReadyToRunSection> Sections { get; }
5555

56-
public R2RHeader() { }
56+
public ReadyToRunHeader() { }
5757

5858
/// <summary>
5959
/// Initializes the fields of the R2RHeader
@@ -62,7 +62,7 @@ public R2RHeader() { }
6262
/// <param name="rva">Relative virtual address of the ReadyToRun header</param>
6363
/// <param name="curOffset">Index in the image byte array to the start of the ReadyToRun header</param>
6464
/// <exception cref="BadImageFormatException">The signature must be 0x00525452</exception>
65-
public R2RHeader(byte[] image, int rva, int curOffset)
65+
public ReadyToRunHeader(byte[] image, int rva, int curOffset)
6666
{
6767
RelativeVirtualAddress = rva;
6868
int startOffset = curOffset;
@@ -80,18 +80,18 @@ public R2RHeader(byte[] image, int rva, int curOffset)
8080
MinorVersion = NativeReader.ReadUInt16(image, ref curOffset);
8181
Flags = NativeReader.ReadUInt32(image, ref curOffset);
8282
int nSections = NativeReader.ReadInt32(image, ref curOffset);
83-
Sections = new Dictionary<R2RSection.SectionType, R2RSection>();
83+
Sections = new Dictionary<ReadyToRunSection.SectionType, ReadyToRunSection>();
8484

8585
for (int i = 0; i < nSections; i++)
8686
{
8787
int type = NativeReader.ReadInt32(image, ref curOffset);
88-
var sectionType = (R2RSection.SectionType)type;
89-
if (!Enum.IsDefined(typeof(R2RSection.SectionType), type))
88+
var sectionType = (ReadyToRunSection.SectionType)type;
89+
if (!Enum.IsDefined(typeof(ReadyToRunSection.SectionType), type))
9090
{
9191
// TODO (refactoring) - what should we do?
9292
// R2RDump.WriteWarning("Invalid ReadyToRun section type");
9393
}
94-
Sections[sectionType] = new R2RSection(sectionType,
94+
Sections[sectionType] = new ReadyToRunSection(sectionType,
9595
NativeReader.ReadInt32(image, ref curOffset),
9696
NativeReader.ReadInt32(image, ref curOffset));
9797
}

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RImportSection.cs renamed to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunImportSection.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace ILCompiler.Reflection.ReadyToRun
1313
/// <summary>
1414
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_IMPORT_SECTION
1515
/// </summary>
16-
public struct R2RImportSection
16+
public struct ReadyToRunImportSection
1717
{
1818
public class ImportSectionEntry
1919
{
@@ -76,9 +76,9 @@ public ImportSectionEntry(int index, int startOffset, int startRVA, long section
7676

7777
public int AuxiliaryDataSize { get; set; }
7878

79-
public R2RImportSection(
79+
public ReadyToRunImportSection(
8080
int index,
81-
R2RReader reader,
81+
ReadyToRunReader reader,
8282
int rva,
8383
int size,
8484
CorCompileImportFlags flags,

src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/R2RMethod.cs renamed to src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunMethod.cs

+21-12
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public abstract class BaseGcInfo
5050
/// </summary>
5151
public class RuntimeFunction
5252
{
53+
private ReadyToRunReader _readyToRunReader;
54+
private DebugInfo _debugInfo;
55+
5356
/// <summary>
5457
/// The index of the runtime function
5558
/// </summary>
@@ -82,34 +85,42 @@ public class RuntimeFunction
8285
/// <summary>
8386
/// The method that this runtime function belongs to
8487
/// </summary>
85-
public R2RMethod Method { get; }
88+
public ReadyToRunMethod Method { get; }
8689

8790
public BaseUnwindInfo UnwindInfo { get; }
8891

8992
public EHInfo EHInfo { get; }
9093

91-
public DebugInfo DebugInfo { get; }
92-
93-
public RuntimeFunction() { }
94+
public DebugInfo DebugInfo
95+
{
96+
get
97+
{
98+
if (_debugInfo == null)
99+
{
100+
_readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out _debugInfo);
101+
}
102+
return _debugInfo;
103+
}
104+
}
94105

95106
public RuntimeFunction(
107+
ReadyToRunReader readyToRunReader,
96108
int id,
97109
int startRva,
98110
int endRva,
99111
int unwindRva,
100112
int codeOffset,
101-
R2RMethod method,
113+
ReadyToRunMethod method,
102114
BaseUnwindInfo unwindInfo,
103115
BaseGcInfo gcInfo,
104-
EHInfo ehInfo,
105-
DebugInfo debugInfo)
116+
EHInfo ehInfo)
106117
{
118+
_readyToRunReader = readyToRunReader;
107119
Id = id;
108120
StartAddress = startRva;
109121
UnwindRVA = unwindRva;
110122
Method = method;
111123
UnwindInfo = unwindInfo;
112-
DebugInfo = debugInfo;
113124

114125
if (endRva != -1)
115126
{
@@ -141,7 +152,7 @@ public RuntimeFunction(
141152
}
142153
}
143154

144-
public class R2RMethod
155+
public class ReadyToRunMethod
145156
{
146157
private const int _mdtMethodDef = 0x06000000;
147158

@@ -196,12 +207,10 @@ public class R2RMethod
196207

197208
public FixupCell[] Fixups { get; set; }
198209

199-
public R2RMethod() { }
200-
201210
/// <summary>
202211
/// Extracts the method signature from the metadata by rid
203212
/// </summary>
204-
public R2RMethod(
213+
public ReadyToRunMethod(
205214
int index,
206215
MetadataReader metadataReader,
207216
EntityHandle methodHandle,

0 commit comments

Comments
 (0)