Browse Source

Fixed memory leak (and potential thread-safety issue) in SD.Dom.

ExtensionMethodsPublic.memberSignatureComparer.parameterListComparer.cachedHashes was keeping references to all methods that were ever compared.
4.0
Daniel Grunwald 15 years ago
parent
commit
d793900605
  1. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs
  2. 33
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ParameterListComparer.cs

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs

@ -87,6 +87,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -87,6 +87,7 @@ namespace ICSharpCode.SharpDevelop.Dom
//Dictionary<IMember, IMember> overrideDict = new Dictionary<IMember, IMember>();
ParameterListComparer parameterListComparer = new ParameterListComparer();
parameterListComparer.UseCachedHashes = true;
HashSet<IMethod> handledMethods = new HashSet<IMethod>(parameterListComparer);
Dictionary<IMethod, IMethod> overrideMethodDict = new Dictionary<IMethod, IMethod>(parameterListComparer);
IMember nonMethodOverride = null;

33
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ParameterListComparer.cs

@ -10,10 +10,32 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -10,10 +10,32 @@ namespace ICSharpCode.SharpDevelop.Dom
{
public class ParameterListComparer : IEqualityComparer<IMethod>
{
Dictionary<IMethod, int> cachedHashes;
/// <summary>
/// Gets/Sets whether to cache hashcodes. This can improve performance for
/// algorithms that repeatedly request the hash of a parameter list.
/// </summary>
/// <remarks>
/// This class is thread-safe only when not using cached hashes.
/// Also, cached hashes may cause a memory leak when the ParameterListComparer
/// instance is kept alive.
/// </remarks>
public bool UseCachedHashes {
get {
return cachedHashes != null;
}
set {
cachedHashes = value ? new Dictionary<IMethod, int>() : null;
}
}
public bool Equals(IMethod x, IMethod y)
{
if (GetHashCode(x) != GetHashCode(y))
return false;
if (cachedHashes != null) {
if (GetHashCode(x) != GetHashCode(y))
return false;
}
var paramsX = x.Parameters;
var paramsY = y.Parameters;
if (paramsX.Count != paramsY.Count)
@ -31,12 +53,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -31,12 +53,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return true;
}
Dictionary<IMethod, int> cachedHashes = new Dictionary<IMethod, int>();
public int GetHashCode(IMethod obj)
{
int hashCode;
if (cachedHashes.TryGetValue(obj, out hashCode))
if (cachedHashes != null && cachedHashes.TryGetValue(obj, out hashCode))
return hashCode;
hashCode = obj.TypeParameters.Count;
unchecked {
@ -49,7 +69,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -49,7 +69,8 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
}
cachedHashes[obj] = hashCode;
if (cachedHashes != null)
cachedHashes[obj] = hashCode;
return hashCode;
}
}

Loading…
Cancel
Save