Skip to content

Commit

Permalink
Make parsing of debug info lazy (#1657)
Browse files Browse the repository at this point in the history
  • Loading branch information
cshung authored Jan 13, 2020
1 parent 18aee2a commit 0812d49
Show file tree
Hide file tree
Showing 15 changed files with 313 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,45 @@ namespace ILCompiler.Reflection.ReadyToRun
/// </summary>
public class DebugInfo
{
private List<DebugInfoBoundsEntry> _boundsList = new List<DebugInfoBoundsEntry>();
private List<NativeVarInfo> _variablesList = new List<NativeVarInfo>();
private readonly ReadyToRunReader _readyToRunReader;
private readonly int _offset;
private List<DebugInfoBoundsEntry> _boundsList;
private List<NativeVarInfo> _variablesList;
private Machine _machine;

public DebugInfo(byte[] image, int offset, Machine machine)
public DebugInfo(ReadyToRunReader readyToRunReader, int offset)
{
_machine = machine;

// Get the id of the runtime function from the NativeArray
uint lookback = 0;
uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);
this._readyToRunReader = readyToRunReader;
this._offset = offset;
}

if (lookback != 0)
public List<DebugInfoBoundsEntry> BoundsList
{
get
{
System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
debugInfoOffset = (uint)offset - lookback;
EnsureInitialized();
return _boundsList;
}
}

NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset);
uint boundsByteCount = reader.ReadUInt();
uint variablesByteCount = reader.ReadUInt();
int boundsOffset = reader.GetNextByteOffset();
int variablesOffset = (int)(boundsOffset + boundsByteCount);

if (boundsByteCount > 0)
public List<NativeVarInfo> VariablesList
{
get
{
ParseBounds(image, boundsOffset);
EnsureInitialized();
return _variablesList;
}
}

if (variablesByteCount > 0)
public Machine Machine
{
get
{
ParseNativeVarInfo(image, variablesOffset);
EnsureInitialized();
return _machine;
}
}

public List<DebugInfoBoundsEntry> BoundsList => _boundsList;
public List<NativeVarInfo> VariablesList => _variablesList;
public Machine Machine => _machine;

/// <summary>
/// Convert a register number in debug info into a machine-specific register
/// </summary>
Expand All @@ -77,6 +77,46 @@ public static string GetPlatformSpecificRegister(Machine machine, int regnum)
}
}

private void EnsureInitialized()
{
if (_boundsList != null)
{
return;
}
int offset = _offset;
_boundsList = new List<DebugInfoBoundsEntry>();
_variablesList = new List<NativeVarInfo>();
Machine machine = _readyToRunReader.Machine;
byte[] image = _readyToRunReader.Image;
_machine = machine;

// Get the id of the runtime function from the NativeArray
uint lookback = 0;
uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);

if (lookback != 0)
{
System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
debugInfoOffset = (uint)offset - lookback;
}

NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset);
uint boundsByteCount = reader.ReadUInt();
uint variablesByteCount = reader.ReadUInt();
int boundsOffset = reader.GetNextByteOffset();
int variablesOffset = (int)(boundsOffset + boundsByteCount);

if (boundsByteCount > 0)
{
ParseBounds(image, boundsOffset);
}

if (variablesByteCount > 0)
{
ParseNativeVarInfo(image, variablesOffset);
}
}

private void ParseBounds(byte[] image, int offset)
{
// Bounds info contains (Native Offset, IL Offset, flags)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public class EHClause
/// </summary>
/// <param name="reader">R2R image reader<param>
/// <param name="offset">Offset of the EH clause in the image</param>
public EHClause(R2RReader reader, int offset)
public EHClause(ReadyToRunReader reader, int offset)
{
Flags = (CorExceptionFlag)BitConverter.ToUInt32(reader.Image, offset + 0 * sizeof(uint));
TryOffset = BitConverter.ToUInt32(reader.Image, offset + 1 * sizeof(uint));
Expand Down Expand Up @@ -175,7 +175,7 @@ public class EHInfo
/// <param name="methodRva">Starting RVA of the runtime function</param>
/// <param name="offset">File offset of the EH info</param>
/// <param name="clauseCount">Number of EH info clauses</param>
public EHInfo(R2RReader reader, int ehInfoRva, int methodRva, int offset, int clauseCount)
public EHInfo(ReadyToRunReader reader, int ehInfoRva, int methodRva, int offset, int clauseCount)
{
EHInfoRVA = ehInfoRva;
MethodRVA = methodRva;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ public GCRefMap(uint stackPop, GCRefMapEntry[] entries)
/// </summary>
public class GCRefMapDecoder
{
private readonly R2RReader _reader;
private readonly ReadyToRunReader _reader;
private int _offset;
private int _pendingByte;
private int _pos;

public GCRefMapDecoder(R2RReader reader, int offset)
public GCRefMapDecoder(ReadyToRunReader reader, int offset)
{
_reader = reader;
_offset = offset;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.Reflection.ReadyToRun
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_HEADER
/// </summary>
public class R2RHeader
public class ReadyToRunHeader
{
/// <summary>
/// The expected signature of a ReadyToRun header
Expand Down Expand Up @@ -51,9 +51,9 @@ public class R2RHeader
/// <summary>
/// The ReadyToRun section RVAs and sizes
/// </summary>
public IDictionary<R2RSection.SectionType, R2RSection> Sections { get; }
public IDictionary<ReadyToRunSection.SectionType, ReadyToRunSection> Sections { get; }

public R2RHeader() { }
public ReadyToRunHeader() { }

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

for (int i = 0; i < nSections; i++)
{
int type = NativeReader.ReadInt32(image, ref curOffset);
var sectionType = (R2RSection.SectionType)type;
if (!Enum.IsDefined(typeof(R2RSection.SectionType), type))
var sectionType = (ReadyToRunSection.SectionType)type;
if (!Enum.IsDefined(typeof(ReadyToRunSection.SectionType), type))
{
// TODO (refactoring) - what should we do?
// R2RDump.WriteWarning("Invalid ReadyToRun section type");
}
Sections[sectionType] = new R2RSection(sectionType,
Sections[sectionType] = new ReadyToRunSection(sectionType,
NativeReader.ReadInt32(image, ref curOffset),
NativeReader.ReadInt32(image, ref curOffset));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace ILCompiler.Reflection.ReadyToRun
/// <summary>
/// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/inc/readytorun.h">src/inc/readytorun.h</a> READYTORUN_IMPORT_SECTION
/// </summary>
public struct R2RImportSection
public struct ReadyToRunImportSection
{
public class ImportSectionEntry
{
Expand Down Expand Up @@ -76,9 +76,9 @@ public ImportSectionEntry(int index, int startOffset, int startRVA, long section

public int AuxiliaryDataSize { get; set; }

public R2RImportSection(
public ReadyToRunImportSection(
int index,
R2RReader reader,
ReadyToRunReader reader,
int rva,
int size,
CorCompileImportFlags flags,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ public abstract class BaseGcInfo
/// </summary>
public class RuntimeFunction
{
private ReadyToRunReader _readyToRunReader;
private DebugInfo _debugInfo;

/// <summary>
/// The index of the runtime function
/// </summary>
Expand Down Expand Up @@ -82,34 +85,42 @@ public class RuntimeFunction
/// <summary>
/// The method that this runtime function belongs to
/// </summary>
public R2RMethod Method { get; }
public ReadyToRunMethod Method { get; }

public BaseUnwindInfo UnwindInfo { get; }

public EHInfo EHInfo { get; }

public DebugInfo DebugInfo { get; }

public RuntimeFunction() { }
public DebugInfo DebugInfo
{
get
{
if (_debugInfo == null)
{
_readyToRunReader.RuntimeFunctionToDebugInfo.TryGetValue(Id, out _debugInfo);
}
return _debugInfo;
}
}

public RuntimeFunction(
ReadyToRunReader readyToRunReader,
int id,
int startRva,
int endRva,
int unwindRva,
int codeOffset,
R2RMethod method,
ReadyToRunMethod method,
BaseUnwindInfo unwindInfo,
BaseGcInfo gcInfo,
EHInfo ehInfo,
DebugInfo debugInfo)
EHInfo ehInfo)
{
_readyToRunReader = readyToRunReader;
Id = id;
StartAddress = startRva;
UnwindRVA = unwindRva;
Method = method;
UnwindInfo = unwindInfo;
DebugInfo = debugInfo;

if (endRva != -1)
{
Expand Down Expand Up @@ -141,7 +152,7 @@ public RuntimeFunction(
}
}

public class R2RMethod
public class ReadyToRunMethod
{
private const int _mdtMethodDef = 0x06000000;

Expand Down Expand Up @@ -196,12 +207,10 @@ public class R2RMethod

public FixupCell[] Fixups { get; set; }

public R2RMethod() { }

/// <summary>
/// Extracts the method signature from the metadata by rid
/// </summary>
public R2RMethod(
public ReadyToRunMethod(
int index,
MetadataReader metadataReader,
EntityHandle methodHandle,
Expand Down
Loading

0 comments on commit 0812d49

Please sign in to comment.