提交 07a6dca8 编写于 作者: T Tomas Matousek

Changes ObjectPool leak detection to use simple light-up to get the stack...

Changes ObjectPool leak detection to use simple light-up to get the stack trace (which is nonportable), and fixes a few leaks
上级 98b912d6
......@@ -2216,6 +2216,14 @@ public MembersAndInitializers ToReadOnlyAndFree()
StaticSyntaxLength,
InstanceSyntaxLength);
}
public void Free()
{
NonTypeNonIndexerMembers.Free();
StaticInitializers.Free();
InstanceInitializers.Free();
IndexerDeclarations.Free();
}
}
private MembersAndInitializers BuildMembersAndInitializers(DiagnosticBag diagnostics)
......@@ -2252,6 +2260,7 @@ private MembersAndInitializers BuildMembersAndInitializers(DiagnosticBag diagnos
// of the data in the builder and would fail in an assertion if we tried to construct it from incomplete builder.
if (_lazyMembersAndInitializers != null)
{
builder.Free();
return null;
}
......
......@@ -1530,7 +1530,7 @@ internal void EnsureAnonymousTypeTemplates(CancellationToken cancellationToken)
{
Debug.Assert(peStreamProvider != null);
DiagnosticBag diagnostics = new DiagnosticBag();
DiagnosticBag diagnostics = DiagnosticBag.GetInstance();
if (options != null)
{
options.ValidateOptions(diagnostics, this.MessageProvider);
......
......@@ -326,7 +326,8 @@ private TypeSymbol ResolveSignatureTypeHandleOrThrow(ref BlobReader ppSig, out b
}
else
{
throw new UnsupportedSignatureContent();
isNoPiaLocalType = false;
typeSymbol = GetTypeOfTypeSpec((TypeSpecificationHandle)token);
}
Debug.Assert(typeSymbol != null);
......@@ -683,35 +684,43 @@ internal ImmutableArray<LocalInfo<TypeSymbol>> DecodeLocalSignatureOrThrow(ref B
var locals = ArrayBuilder<LocalInfo<TypeSymbol>>.GetInstance(localCount);
var offsets = ArrayBuilder<int>.GetInstance(localCount);
for (int i = 0; i < localCount; i++)
{
offsets.Add(signatureReader.Offset);
locals.Add(DecodeLocalVariableOrThrow(ref signatureReader));
}
if (signatureReader.RemainingBytes > 0)
try
{
throw new UnsupportedSignatureContent();
}
for (int i = 0; i < localCount; i++)
{
offsets.Add(signatureReader.Offset);
locals.Add(DecodeLocalVariableOrThrow(ref signatureReader));
}
// Include signatures with each local.
signatureReader.Reset();
for (int i = 0; i < localCount; i++)
{
int start = offsets[i];
Debug.Assert(signatureReader.Offset <= start);
while (signatureReader.Offset < start)
if (signatureReader.RemainingBytes > 0)
{
signatureReader.ReadByte();
throw new UnsupportedSignatureContent();
}
int n = (i < localCount - 1) ? (offsets[i + 1] - start) : signatureReader.RemainingBytes;
var signature = signatureReader.ReadBytes(n);
// Include signatures with each local.
signatureReader.Reset();
for (int i = 0; i < localCount; i++)
{
int start = offsets[i];
Debug.Assert(signatureReader.Offset <= start);
while (signatureReader.Offset < start)
{
signatureReader.ReadByte();
}
locals[i] = locals[i].WithSignature(signature);
}
int n = (i < localCount - 1) ? (offsets[i + 1] - start) : signatureReader.RemainingBytes;
var signature = signatureReader.ReadBytes(n);
return locals.ToImmutableAndFree();
locals[i] = locals[i].WithSignature(signature);
}
return locals.ToImmutable();
}
finally
{
offsets.Free();
locals.Free();
}
}
/// <exception cref="UnsupportedSignatureContent">If the encoded local variable type is invalid.</exception>
......
......@@ -391,7 +391,7 @@ internal static ImmutableArray<byte> CalculatePublicKeyToken(ImmutableArray<byte
result.Add(hash[l - i]);
}
return result.ToImmutable();
return result.ToImmutableAndFree();
}
/// <summary>
......
......@@ -297,6 +297,7 @@ internal static string BuildQualifiedNamespaceName(INamespace @namespace)
}
}
namesReversed.Free();
return result.ToStringAndFree();
}
}
......
......@@ -68,7 +68,7 @@ private class LeakTracker : IDisposable
private volatile bool disposed;
#if TRACE_LEAKS
internal volatile System.Diagnostics.StackTrace Trace = null;
internal volatile object Trace = null;
#endif
public void Dispose()
......@@ -88,18 +88,14 @@ private string GetTrace()
~LeakTracker()
{
if (!this.disposed &&
!Environment.HasShutdownStarted &&
!AppDomain.CurrentDomain.IsFinalizingForUnload())
if (!this.disposed && !Environment.HasShutdownStarted)
{
string report = string.Format("Pool detected potential leaking of {0}. \n Location of the leak: \n {1} ",
typeof(T).ToString(),
GetTrace());
var trace = GetTrace();
// If you are seeing this message it means that object has been allocated from the pool
// and has not been returned back. This is not critical, but turns pool into rather
// inefficient kind of "new".
Debug.WriteLine("TRACEOBJECTPOOLLEAKS_BEGIN\n" + report + "TRACEOBJECTPOOLLEAKS_END");
Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nPool detected potential leaking of {typeof(T)}. \n Location of the leak: \n {GetTrace()} TRACEOBJECTPOOLLEAKS_END");
}
}
}
......@@ -147,7 +143,7 @@ internal T Allocate()
leakTrackers.Add(inst, tracker);
#if TRACE_LEAKS
var frame = new System.Diagnostics.StackTrace(false);
var frame = CaptureStackTrace();
tracker.Trace = frame;
#endif
#endif
......@@ -238,11 +234,8 @@ internal void ForgetTrackedObject(T old, T replacement = null)
}
else
{
string report = string.Format("Object of type {0} was freed, but was not from pool. \n Callstack: \n {1} ",
typeof(T).ToString(),
new System.Diagnostics.StackTrace(false));
Debug.WriteLine("TRACEOBJECTPOOLLEAKS_BEGIN\n" + report + "TRACEOBJECTPOOLLEAKS_END");
var trace = CaptureStackTrace();
Debug.WriteLine($"TRACEOBJECTPOOLLEAKS_BEGIN\nObject of type {typeof(T)} was freed, but was not from pool. \n Callstack: \n {trace} TRACEOBJECTPOOLLEAKS_END");
}
if (replacement != null)
......@@ -253,6 +246,15 @@ internal void ForgetTrackedObject(T old, T replacement = null)
#endif
}
#if DETECT_LEAKS
private static Lazy<Type> _stackTraceType = new Lazy<Type>(() => Type.GetType("System.Diagnostics.StackTrace"));
private static object CaptureStackTrace()
{
return Activator.CreateInstance(_stackTraceType.Value);
}
#endif
[Conditional("DEBUG")]
private void Validate(object obj)
{
......
......@@ -52,6 +52,8 @@ internal static void GetAllScopes(this ISymUnmanagedMethod method, ArrayBuilder<
stack.Push(nested);
}
}
stack.Free();
}
/// <summary>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册