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
//Dictionary<IMember, IMember> overrideDict = new Dictionary<IMember, IMember>(); //Dictionary<IMember, IMember> overrideDict = new Dictionary<IMember, IMember>();
ParameterListComparer parameterListComparer = new ParameterListComparer(); ParameterListComparer parameterListComparer = new ParameterListComparer();
parameterListComparer.UseCachedHashes = true;
HashSet<IMethod> handledMethods = new HashSet<IMethod>(parameterListComparer); HashSet<IMethod> handledMethods = new HashSet<IMethod>(parameterListComparer);
Dictionary<IMethod, IMethod> overrideMethodDict = new Dictionary<IMethod, IMethod>(parameterListComparer); Dictionary<IMethod, IMethod> overrideMethodDict = new Dictionary<IMethod, IMethod>(parameterListComparer);
IMember nonMethodOverride = null; IMember nonMethodOverride = null;

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

@ -10,10 +10,32 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public class ParameterListComparer : IEqualityComparer<IMethod> 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) public bool Equals(IMethod x, IMethod y)
{ {
if (GetHashCode(x) != GetHashCode(y)) if (cachedHashes != null) {
return false; if (GetHashCode(x) != GetHashCode(y))
return false;
}
var paramsX = x.Parameters; var paramsX = x.Parameters;
var paramsY = y.Parameters; var paramsY = y.Parameters;
if (paramsX.Count != paramsY.Count) if (paramsX.Count != paramsY.Count)
@ -31,12 +53,10 @@ namespace ICSharpCode.SharpDevelop.Dom
return true; return true;
} }
Dictionary<IMethod, int> cachedHashes = new Dictionary<IMethod, int>();
public int GetHashCode(IMethod obj) public int GetHashCode(IMethod obj)
{ {
int hashCode; int hashCode;
if (cachedHashes.TryGetValue(obj, out hashCode)) if (cachedHashes != null && cachedHashes.TryGetValue(obj, out hashCode))
return hashCode; return hashCode;
hashCode = obj.TypeParameters.Count; hashCode = obj.TypeParameters.Count;
unchecked { unchecked {
@ -49,7 +69,8 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
} }
cachedHashes[obj] = hashCode; if (cachedHashes != null)
cachedHashes[obj] = hashCode;
return hashCode; return hashCode;
} }
} }

Loading…
Cancel
Save