Skip to content

Commit

Permalink
Generate new debug info for methods with substituted code (#506)
Browse files Browse the repository at this point in the history
Methods with substituted code weren't getting any debug information. Fixing that.
  • Loading branch information
MichalStrehovsky committed Dec 28, 2020
1 parent de8235d commit 95de52e
Showing 1 changed file with 41 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Internal.TypeSystem.Ecma;

using Debug = System.Diagnostics.Debug;
using MethodDebugInformation = Internal.IL.MethodDebugInformation;

namespace ILCompiler
{
Expand Down Expand Up @@ -441,7 +442,26 @@ public MethodIL GetMethodILWithInlinedSubstitutions(MethodIL method)
}
}

return new SubstitutedMethodIL(method, newBody, newEHRegions.ToArray());
// Existing debug information might not match new instruction boundaries (plus there's little point
// in generating debug information for NOPs) - generate new debug information by filtering
// out the sequence points associated with nopped out instructions.
MethodDebugInformation debugInfo = method.GetDebugInfo();
IEnumerable<ILSequencePoint> oldSequencePoints = debugInfo?.GetSequencePoints();
if (oldSequencePoints != null)
{
ArrayBuilder<ILSequencePoint> sequencePoints = new ArrayBuilder<ILSequencePoint>();
foreach (var sequencePoint in oldSequencePoints)
{
if (sequencePoint.Offset < flags.Length && (flags[sequencePoint.Offset] & OpcodeFlags.Mark) != 0)
{
sequencePoints.Add(sequencePoint);
}
}

debugInfo = new SubstitutedDebugInformation(debugInfo, sequencePoints.ToArray());
}

return new SubstitutedMethodIL(method, newBody, newEHRegions.ToArray(), debugInfo);
}

private bool TryGetConstantArgument(MethodIL methodIL, byte[] body, OpcodeFlags[] flags, int offset, int argIndex, out int constant)
Expand Down Expand Up @@ -609,12 +629,14 @@ private class SubstitutedMethodIL : MethodIL
private readonly byte[] _body;
private readonly ILExceptionRegion[] _ehRegions;
private readonly MethodIL _wrappedMethodIL;
private readonly MethodDebugInformation _debugInfo;

public SubstitutedMethodIL(MethodIL wrapped, byte[] body, ILExceptionRegion[] ehRegions)
public SubstitutedMethodIL(MethodIL wrapped, byte[] body, ILExceptionRegion[] ehRegions, MethodDebugInformation debugInfo)
{
_wrappedMethodIL = wrapped;
_body = body;
_ehRegions = ehRegions;
_debugInfo = debugInfo;
}

public override MethodDesc OwningMethod => _wrappedMethodIL.OwningMethod;
Expand All @@ -624,6 +646,23 @@ public SubstitutedMethodIL(MethodIL wrapped, byte[] body, ILExceptionRegion[] eh
public override byte[] GetILBytes() => _body;
public override LocalVariableDefinition[] GetLocals() => _wrappedMethodIL.GetLocals();
public override object GetObject(int token) => _wrappedMethodIL.GetObject(token);
public override MethodDebugInformation GetDebugInfo() => _debugInfo;
}

private class SubstitutedDebugInformation : MethodDebugInformation
{
private readonly MethodDebugInformation _originalDebugInformation;
private readonly ILSequencePoint[] _sequencePoints;

public SubstitutedDebugInformation(MethodDebugInformation originalDebugInformation, ILSequencePoint[] newSequencePoints)
{
_originalDebugInformation = originalDebugInformation;
_sequencePoints = newSequencePoints;
}

public override IEnumerable<Internal.IL.ILLocalVariable> GetLocalVariables() => _originalDebugInformation.GetLocalVariables();
public override IEnumerable<string> GetParameterNames() => _originalDebugInformation.GetParameterNames();
public override IEnumerable<ILSequencePoint> GetSequencePoints() => _sequencePoints;
}

private class FeatureSwitchHashtable : LockFreeReaderHashtable<EcmaModule, AssemblyFeatureInfo>
Expand Down

0 comments on commit 95de52e

Please sign in to comment.